-
{tag?._count?.tagOnPost || 0}
+
{0}
posts
diff --git a/apps/web/src/molecules/tag/tag-item/index.tsx b/apps/web/src/molecules/tag/tag-item/index.tsx
index b1b187ed..86dd51de 100644
--- a/apps/web/src/molecules/tag/tag-item/index.tsx
+++ b/apps/web/src/molecules/tag/tag-item/index.tsx
@@ -1,10 +1,10 @@
import Link from "next/link"
-import { TTagItem } from "database"
+import { TTagListItem } from "database"
import { useTranslations } from "next-intl"
import { Card, CardContent, CardHeader, Typography } from "ui"
-export default function TagItem({ tag }: { tag: TTagItem }) {
+export default function TagItem({ tag }: { tag: TTagListItem }) {
const t = useTranslations("common")
return (
@@ -28,7 +28,7 @@ export default function TagItem({ tag }: { tag: TTagItem }) {
variant="span"
className="font-semibold"
>
- {t("post_plural", { total: tag?._count?.tagOnPost || 0 })}
+ {tag?.description}
diff --git a/apps/web/src/molecules/tag/tag-list/index.tsx b/apps/web/src/molecules/tag/tag-list/index.tsx
index ed85e64b..115674d6 100644
--- a/apps/web/src/molecules/tag/tag-list/index.tsx
+++ b/apps/web/src/molecules/tag/tag-list/index.tsx
@@ -3,15 +3,16 @@
import React, { useCallback, useState } from "react"
import { useParams } from "next/navigation"
-import { getTags, TTagItem } from "database"
-import InfiniteScroll from "molecules/infinite-scroll"
+import { getTags, TTagListItem } from "database"
+
+import InfiniteScroll from "@/molecules/infinite-scroll"
import TagItem from "../tag-item"
const TagList: React.FC = () => {
const searchParams = useParams()
const [isLoading, setIsLoading] = useState(false)
- const [tags, setTags] = useState
([])
+ const [tags, setTags] = useState([])
const [page, setPage] = useState(1)
const [hasNextPage, setHasNextPage] = useState(true)
@@ -21,7 +22,6 @@ const TagList: React.FC = () => {
setIsLoading(true)
const { data } = await getTags({
...searchParams,
- page,
})
setTags((prev) => [...prev, ...data?.data])
diff --git a/apps/web/src/molecules/top-tags/NumberIndex.tsx b/apps/web/src/molecules/top-tags/NumberIndex.tsx
index b12f1151..ad3cf5d4 100644
--- a/apps/web/src/molecules/top-tags/NumberIndex.tsx
+++ b/apps/web/src/molecules/top-tags/NumberIndex.tsx
@@ -2,9 +2,10 @@
import React from "react"
-import { bebasNeue } from "font"
import { cn } from "ui"
+import { bebasNeue } from "@/font"
+
interface NumberIndexProps {
number: number
}
diff --git a/apps/web/src/molecules/top-tags/index.tsx b/apps/web/src/molecules/top-tags/index.tsx
index e8b6fae7..fe30adc2 100644
--- a/apps/web/src/molecules/top-tags/index.tsx
+++ b/apps/web/src/molecules/top-tags/index.tsx
@@ -1,7 +1,7 @@
import React from "react"
import Link from "next/link"
-import { getTopTags } from "database"
+import { getTags } from "database"
import { getTranslations } from "next-intl/server"
import { Typography } from "ui"
@@ -10,7 +10,15 @@ import NumberIndex from "./NumberIndex"
const TopTag: React.FC = async () => {
const t = await getTranslations()
- const { data: topTags } = await getTopTags()
+ const { data: topTags } = await getTags({
+ take: 10,
+ skip: 0,
+ // orderBy: {
+ // tagOnPost: {
+ // _count: "desc",
+ // },
+ // },
+ })
return (
@@ -27,7 +35,7 @@ const TopTag: React.FC = async () => {
#{tag.name}
{t("common.total_post_plural", {
- total: tag?._count?.tagOnPost || 0,
+ total: 0, //tag?._count?.tagOnPost || 0,
})}
diff --git a/apps/web/src/molecules/upload/AssetsManagement.tsx b/apps/web/src/molecules/upload/AssetsManagement.tsx
index 8e5e2e96..dc2a690e 100644
--- a/apps/web/src/molecules/upload/AssetsManagement.tsx
+++ b/apps/web/src/molecules/upload/AssetsManagement.tsx
@@ -1,7 +1,7 @@
import { useEffect, useMemo, useRef } from "react"
-import { useGetImages } from "hooks/useGetImages"
-import useInfiniteScroll from "hooks/useInfinityScroll"
+import { useGetImages } from "@/hooks/useGetImages"
+import useInfiniteScroll from "@/hooks/useInfinityScroll"
import { useFileManager } from "./FileManagerContainer"
import ImageList from "./ImageList"
diff --git a/apps/web/src/molecules/upload/FileManagerContainer.tsx b/apps/web/src/molecules/upload/FileManagerContainer.tsx
index 1ef8e026..edf290b6 100644
--- a/apps/web/src/molecules/upload/FileManagerContainer.tsx
+++ b/apps/web/src/molecules/upload/FileManagerContainer.tsx
@@ -1,7 +1,8 @@
import React, { createContext, useCallback, useContext, useReducer } from "react"
-import { OrderByField } from "constants/upload"
-import { Image, OrderBy } from "database"
+import { Image, ImageOrderBys } from "database"
+
+import { OrderByField } from "@/constants/upload"
export type FileManagerState = {
selectedFiles: Image[]
@@ -62,7 +63,7 @@ const FileManagerContainer = ({ children }: { children: React.ReactNode }) => {
dispatch({ type: "SET_SEARCH", payload: search })
}, [])
- const setOrder = useCallback((order: OrderBy) => {
+ const setOrder = useCallback((order: ImageOrderBys) => {
dispatch({ type: "SET_ORDER", payload: order })
}, [])
diff --git a/apps/web/src/molecules/upload/ImageSearchBar.tsx b/apps/web/src/molecules/upload/ImageSearchBar.tsx
index efa74ad2..4cc5b761 100644
--- a/apps/web/src/molecules/upload/ImageSearchBar.tsx
+++ b/apps/web/src/molecules/upload/ImageSearchBar.tsx
@@ -1,6 +1,5 @@
"use client"
-import { OrderByField } from "constants/upload"
import { ArrowDownWideNarrow } from "lucide-react"
import { useTranslations } from "next-intl"
import {
@@ -15,6 +14,8 @@ import {
Input,
} from "ui"
+import { OrderByField } from "@/constants/upload"
+
import { useFileManager } from "./FileManagerContainer"
export default function ImageSearchBar() {
diff --git a/apps/web/src/molecules/upload/UploadImageButton.tsx b/apps/web/src/molecules/upload/UploadImageButton.tsx
index 9cb74b46..43ca369e 100644
--- a/apps/web/src/molecules/upload/UploadImageButton.tsx
+++ b/apps/web/src/molecules/upload/UploadImageButton.tsx
@@ -2,12 +2,13 @@
import { useRef } from "react"
-import { useUploadImage } from "hooks/useUploadImage"
import { Upload } from "lucide-react"
import { useTranslations } from "next-intl"
import { toast } from "react-toastify"
import { LoadingButton } from "ui"
+import { useUploadImage } from "@/hooks/useUploadImage"
+
const UploadImageButton = () => {
const fileInputRef = useRef(null)
const t = useTranslations("uploads")
diff --git a/apps/web/src/molecules/upload/index.tsx b/apps/web/src/molecules/upload/index.tsx
index 88776c6c..e6f7d058 100644
--- a/apps/web/src/molecules/upload/index.tsx
+++ b/apps/web/src/molecules/upload/index.tsx
@@ -1,7 +1,6 @@
import { ReactNode, useState } from "react"
import { Image } from "database"
-import { useGetImages } from "hooks/useGetImages"
import { X } from "lucide-react"
import { useTranslations } from "next-intl"
import {
@@ -15,7 +14,9 @@ import {
Separator,
Typography,
} from "ui"
-import { truncateFileName } from "utils/text"
+
+import { useGetImages } from "@/hooks/useGetImages"
+import { truncateFileName } from "@/utils/text"
import AssetManagement from "./AssetsManagement"
import FileManagerContainer, { useFileManager } from "./FileManagerContainer"
diff --git a/apps/web/src/molecules/user-nav/LogoutMenu.tsx b/apps/web/src/molecules/user-nav/LogoutMenu.tsx
index d26558de..cd04f559 100644
--- a/apps/web/src/molecules/user-nav/LogoutMenu.tsx
+++ b/apps/web/src/molecules/user-nav/LogoutMenu.tsx
@@ -1,9 +1,10 @@
"use client"
-import { onSignOut } from "actions/auth"
import { useTranslations } from "next-intl"
import { DropdownMenuItem, DropdownMenuShortcut } from "ui"
+import { onSignOut } from "@/actions/auth"
+
export const LogoutMenu = () => {
const t = useTranslations()
diff --git a/apps/web/src/molecules/user-nav/index.tsx b/apps/web/src/molecules/user-nav/index.tsx
index 06c87e6c..ee0b4970 100644
--- a/apps/web/src/molecules/user-nav/index.tsx
+++ b/apps/web/src/molecules/user-nav/index.tsx
@@ -1,6 +1,5 @@
import Link from "next/link"
-import { auth } from "configs/auth"
import { getTranslations } from "next-intl/server"
import {
Avatar,
@@ -18,6 +17,8 @@ import {
Typography,
} from "ui"
+import { auth } from "@/configs/auth"
+
import { LogoutMenu } from "./LogoutMenu"
export async function UserNav() {
diff --git a/apps/web/src/molecules/user/posts/filter.tsx b/apps/web/src/molecules/user/posts/filter.tsx
index 5844caba..18e0a19e 100644
--- a/apps/web/src/molecules/user/posts/filter.tsx
+++ b/apps/web/src/molecules/user/posts/filter.tsx
@@ -3,10 +3,11 @@
import React from "react"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
-import { ORDER_BY } from "constants/order"
import { useTranslations } from "next-intl"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "ui"
+import { ORDER_BY } from "@/constants/order"
+
interface FilterProps {
total: number
}
diff --git a/apps/web/src/utils/navigation.ts b/apps/web/src/utils/navigation.ts
index 88c4c35e..b6bb49e4 100644
--- a/apps/web/src/utils/navigation.ts
+++ b/apps/web/src/utils/navigation.ts
@@ -1,6 +1,7 @@
-import { locales } from "i18n"
import { createSharedPathnamesNavigation } from "next-intl/navigation"
+import { locales } from "@/i18n"
+
export const localePrefix = "as-needed"
export const { Link, redirect, usePathname, useRouter } = createSharedPathnamesNavigation({
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
index 90875fe4..210330db 100644
--- a/apps/web/tsconfig.json
+++ b/apps/web/tsconfig.json
@@ -7,12 +7,10 @@
"name": "next"
}
],
- "baseUrl": "./src",
+ "baseUrl": ".",
"paths": {
"@/*": [
- "./src/*",
- "@/*",
- "assets/*"
+ "src/*"
],
"emails/*": [
"src/emails/*"
diff --git a/packages/database/prisma/migrations/20241223151825_rename_tag/migration.sql b/packages/database/prisma/migrations/20241223151825_rename_tag/migration.sql
new file mode 100644
index 00000000..69b5faed
--- /dev/null
+++ b/packages/database/prisma/migrations/20241223151825_rename_tag/migration.sql
@@ -0,0 +1,46 @@
+/*
+ Warnings:
+
+ - You are about to drop the `Tags` table. If the table is not empty, all the data it contains will be lost.
+
+*/
+-- DropForeignKey
+ALTER TABLE "TagOnPost" DROP CONSTRAINT "TagOnPost_tagId_fkey";
+
+-- DropForeignKey
+ALTER TABLE "Tags" DROP CONSTRAINT "Tags_imageId_fkey";
+
+-- DropTable
+DROP TABLE "Tags";
+
+-- CreateTable
+CREATE TABLE "Tag" (
+ "id" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "type" "TagType" NOT NULL DEFAULT 'TAG',
+ "name" VARCHAR(255) NOT NULL,
+ "slug" VARCHAR(255) NOT NULL,
+ "description" TEXT,
+ "parent" VARCHAR(255),
+ "count" INTEGER NOT NULL DEFAULT 0,
+ "totalFollowers" INTEGER NOT NULL DEFAULT 0,
+ "totalLike" INTEGER NOT NULL DEFAULT 0,
+ "totalPost" INTEGER NOT NULL DEFAULT 0,
+ "totalView" INTEGER NOT NULL DEFAULT 0,
+ "imageId" TEXT,
+
+ CONSTRAINT "Tag_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Tag_name_key" ON "Tag"("name");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Tag_slug_key" ON "Tag"("slug");
+
+-- AddForeignKey
+ALTER TABLE "TagOnPost" ADD CONSTRAINT "TagOnPost_tagId_fkey" FOREIGN KEY ("tagId") REFERENCES "Tag"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Tag" ADD CONSTRAINT "Tag_imageId_fkey" FOREIGN KEY ("imageId") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE;
diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma
index 640c8731..2c34f3cd 100644
--- a/packages/database/prisma/schema.prisma
+++ b/packages/database/prisma/schema.prisma
@@ -133,12 +133,12 @@ model TagOnPost {
postId String
tagId String
post Post @relation(fields: [postId], references: [id])
- tag Tags @relation(fields: [tagId], references: [id])
+ tag Tag @relation(fields: [tagId], references: [id])
@@id([postId, tagId])
}
-model Tags {
+model Tag {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -235,7 +235,7 @@ model Image {
userId String
user User @relation(fields: [userId], references: [id])
posts Post[]
- tags Tags[]
+ tags Tag[]
}
enum UserType {
diff --git a/packages/database/src/images/type.ts b/packages/database/src/images/type.ts
index 87b7e038..7945e535 100644
--- a/packages/database/src/images/type.ts
+++ b/packages/database/src/images/type.ts
@@ -1,5 +1,6 @@
import { Image, Prisma } from "@prisma/client"
-import { IActionReturn, IGetListResponse } from "src/shared/type"
+
+import { IActionReturn, IGetListResponse } from "../shared/type"
export type ImageOrderBys = "createdAt" | "name"
@@ -7,6 +8,7 @@ export interface IImageFilter {
page?: number
limit?: number
userId?: string
+ search?: string
where?: Prisma.ImageWhereInput
order?: Prisma.ImageOrderByRelevanceInput
}
diff --git a/packages/database/src/index.ts b/packages/database/src/index.ts
index b42b493f..8ff50e01 100644
--- a/packages/database/src/index.ts
+++ b/packages/database/src/index.ts
@@ -20,7 +20,7 @@ import {
IGetListResponse,
PeriodValues,
} from "./shared/type"
-import { createTag, getTag, getTags, getTopTags } from "./tags/queries"
+import { createTag, getTag, getTags } from "./tags/queries"
import type { TTagItem, TTagListItem } from "./tags/selects"
import { tagListSelect } from "./tags/selects"
import { createUser, getUser, updateUser } from "./users/queries"
@@ -34,7 +34,6 @@ export {
createTag,
getTag,
getTags,
- getTopTags,
tagListSelect,
// Posts
diff --git a/packages/database/src/posts/queries.ts b/packages/database/src/posts/queries.ts
index e861f600..c28a37b2 100644
--- a/packages/database/src/posts/queries.ts
+++ b/packages/database/src/posts/queries.ts
@@ -193,7 +193,8 @@ export const createPost = async (
authorId: userId,
postStatus: PostStatus.PUBLISHED,
tagOnPost: {
- create: data.tags?.map((tag) => {
+ // @ts-ignore
+ create: data?.tags?.map((tag: any) => {
if (!tag.__isNew__) {
return {
tag: {
@@ -234,6 +235,7 @@ export const updatePost = async (
userId: string
): Promise> => {
try {
+ // @ts-ignore
const { tags, ...postData } = data
const post = await prisma.post.update({
@@ -245,7 +247,7 @@ export const updatePost = async (
...postData,
tagOnPost: {
deleteMany: {},
- create: tags?.map((tag) => {
+ create: tags?.map((tag: any) => {
if (!tag.__isNew__) {
return {
tag: {
diff --git a/packages/database/src/posts/type.ts b/packages/database/src/posts/type.ts
index ce1fafc7..3245f5c8 100644
--- a/packages/database/src/posts/type.ts
+++ b/packages/database/src/posts/type.ts
@@ -1,6 +1,6 @@
import { PostStatus } from "@prisma/client"
-import { IActionReturn, IGetListResponse } from "src/shared/type"
+import { IActionReturn, IGetListResponse } from "../shared/type"
import { TPostItem } from "./selects"
export type TGetPostsResponse = IActionReturn>
diff --git a/packages/database/src/tags/queries.ts b/packages/database/src/tags/queries.ts
index ad666088..011dc183 100644
--- a/packages/database/src/tags/queries.ts
+++ b/packages/database/src/tags/queries.ts
@@ -1,6 +1,6 @@
"use server"
-import { Prisma, Tags } from "@prisma/client"
+import { Prisma, Tag } from "@prisma/client"
import slugify from "slugify"
import { LIMIT_PER_PAGE } from "../constant"
@@ -9,24 +9,22 @@ import { DEFAULT_LIMIT, DEFAULT_PAGE, IActionReturn, IGetListResponse } from "..
import { tagItemSelect, tagListSelect, TTagItem, TTagListItem } from "./selects"
export const getTags = async (
- tagsFindManyArgs: Prisma.TagsFindManyArgs = {
+ tagsFindManyArgs: Prisma.TagFindManyArgs = {
take: LIMIT_PER_PAGE,
skip: DEFAULT_LIMIT * (DEFAULT_PAGE - 1),
}
): Promise>> => {
try {
const [data, total] = await Promise.all([
- prisma.tags.findMany({
+ prisma.tag.findMany({
...tagsFindManyArgs,
select: tagListSelect,
}),
- prisma.tags.count({
+ prisma.tag.count({
where: tagsFindManyArgs?.where || {},
}),
])
- prisma.tags.findMany()
-
return {
data: {
data,
@@ -35,8 +33,6 @@ export const getTags = async (
},
}
} catch (error) {
- console.log("error", error)
-
throw {
data: {
data: [],
@@ -56,7 +52,7 @@ export const getTag = async ({
tagIdOrSlug,
}: GetTagProps): Promise> => {
try {
- const data = await prisma.tags.findFirst({
+ const data = await prisma.tag.findFirst({
where: {
OR: [
{
@@ -80,8 +76,8 @@ export const getTag = async ({
}
}
-export const createTag = async (tag: Prisma.TagsCreateInput): Promise => {
- return prisma.tags.create({
+export const createTag = async (tag: Prisma.TagCreateInput): Promise => {
+ return prisma.tag.create({
data: {
...tag,
slug: tag.slug || slugify(tag.name.toLocaleLowerCase()) + "-" + Date.now(),
@@ -95,9 +91,9 @@ export const updateTag = async ({
tag,
}: {
tagId: string
- tag: Prisma.TagsUpdateArgs["data"]
+ tag: Prisma.TagUpdateArgs["data"]
}): Promise => {
- return prisma.tags.update({
+ return prisma.tag.update({
where: {
id: tagId,
},
@@ -107,47 +103,10 @@ export const updateTag = async ({
}
export const deleteTag = async (tagId: string): Promise => {
- return prisma.tags.delete({
+ return prisma.tag.delete({
where: {
id: tagId,
},
select: tagItemSelect,
})
}
-
-// Get top 10 tags
-export const getTopTags = async (props?: {
- page?: number
- limit?: number
-}): Promise>> => {
- const { page = DEFAULT_PAGE, limit = DEFAULT_LIMIT } = props || {}
- const query = {
- select: tagListSelect,
- take: Number(limit),
- skip: (page === 0 ? 0 : page - 1) * Number(limit),
- orderBy: {
- tagOnPost: {
- _count: "desc",
- },
- },
- } satisfies Prisma.TagsFindManyArgs
-
- try {
- const data = await prisma.tags.findMany(query)
-
- return {
- data: {
- data,
- total: data.length,
- limit,
- page,
- totalPages: Math.ceil(data.length / limit),
- },
- }
- } catch (error) {
- throw {
- data: [],
- error,
- }
- }
-}
diff --git a/packages/database/src/tags/selects.ts b/packages/database/src/tags/selects.ts
index fd9a7026..c9607e97 100644
--- a/packages/database/src/tags/selects.ts
+++ b/packages/database/src/tags/selects.ts
@@ -15,12 +15,7 @@ export const tagListSelect = {
totalFollowers: true,
updatedAt: true,
createdAt: true,
- _count: {
- select: {
- tagOnPost: true,
- },
- },
-} satisfies Prisma.TagsSelect
+} satisfies Prisma.TagSelect
export const tagItemSelect = {
id: true,
@@ -31,17 +26,23 @@ export const tagItemSelect = {
totalFollowers: true,
updatedAt: true,
createdAt: true,
- _count: {
+ image: {
select: {
- tagOnPost: true,
+ id: true,
+ url: true,
},
},
-} satisfies Prisma.TagsSelect
+ // _count: {
+ // select: {
+ // tagOnPost: true,
+ // },
+ // },
+} satisfies Prisma.TagSelect
-export type TTagItem = Prisma.TagsGetPayload<{
+export type TTagItem = Prisma.TagGetPayload<{
select: typeof tagItemSelect
}>
-export type TTagListItem = Prisma.TagsGetPayload<{
+export type TTagListItem = Prisma.TagGetPayload<{
select: typeof tagListSelect
}>
diff --git a/packages/ui/src/components/molecules/skeleton/posts.tsx b/packages/ui/src/components/molecules/skeleton/posts.tsx
index 4471d238..7a18cb8b 100644
--- a/packages/ui/src/components/molecules/skeleton/posts.tsx
+++ b/packages/ui/src/components/molecules/skeleton/posts.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
-import { Skeleton } from "@/components/ui/skeleton"
-import { cn } from "@/lib/utils"
+import { cn } from "../../../lib/utils"
+import { Skeleton } from "../../ui/skeleton"
interface PostSkeletonProps extends React.HTMLAttributes {
total?: number
diff --git a/packages/ui/src/components/ui/use-toast.ts b/packages/ui/src/components/ui/use-toast.ts
index 2e4c6ea2..9abb52e6 100644
--- a/packages/ui/src/components/ui/use-toast.ts
+++ b/packages/ui/src/components/ui/use-toast.ts
@@ -3,7 +3,7 @@
// Inspired by react-hot-toast library
import * as React from "react"
-import type { ToastActionElement, ToastProps } from "@/components/ui/toast"
+import type { ToastActionElement, ToastProps } from "./toast"
const TOAST_LIMIT = 1
const TOAST_REMOVE_DELAY = 1000000