diff --git a/.env.example b/.env.example index f4e7408..a09c803 100644 --- a/.env.example +++ b/.env.example @@ -7,8 +7,8 @@ POSTGRES_USER=postgres POSTGRES_PASSWORD=password DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?schema=public" -GOOGLE_CLIENT_ID= -GOOGLE_CLIENT_SECRET= +# GOOGLE_CLIENT_ID= +# GOOGLE_CLIENT_SECRET= -FACEBOOK_CLIENT_ID= -FACEBOOK_CLIENT_SECRET= +# FACEBOOK_CLIENT_ID= +# FACEBOOK_CLIENT_SECRET= diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ded27a5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/node_modules": true + } +} \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 2e76a42..780ba42 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,5 @@ version: "3.8" -name: nextjs-template +# name: nextjs-template services: postgres: diff --git a/package-lock.json b/package-lock.json index 7dc0e98..4fff275 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,8 @@ "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", "@next-auth/prisma-adapter": "1.0.7", - "@prisma/client": "5.1.1", - "@tanstack/react-table": "8.9.3", - "framer-motion": "10.16.1", + "@prisma/client": "^5.2.0", + "framer-motion": "10.16.0", "jotai": "2.3.1", "next": "13.4.19", "next-auth": "4.23.1", @@ -28,14 +27,18 @@ "swr": "2.2.1" }, "devDependencies": { - "@types/node": "20.5.2", + "@tanstack/react-table": "^8.9.3", + "@types/node": "20.5.1", "@types/react": "18.2.20", "@types/react-dom": "18.2.7", "eslint": "8.47.0", "eslint-config-next": "13.4.19", "eslint-config-prettier": "9.0.0", + "lodash": "^4.17.21", "prettier": "3.0.2", - "prisma": "5.1.1", + "prisma": "^5.2.0", + "suneditor": "^2.45.1", + "suneditor-react": "^3.4.1", "ts-node": "10.9.1", "typescript": "5.1.6" } @@ -1864,12 +1867,12 @@ } }, "node_modules/@prisma/client": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.1.1.tgz", - "integrity": "sha512-fxcCeK5pMQGcgCqCrWsi+I2rpIbk0rAhdrN+ke7f34tIrgPwA68ensrpin+9+fZvuV2OtzHmuipwduSY6HswdA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.2.0.tgz", + "integrity": "sha512-AiTjJwR4J5Rh6Z/9ZKrBBLel3/5DzUNntMohOy7yObVnVoTNVFi2kvpLZlFuKO50d7yDspOtW6XBpiAd0BVXbQ==", "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e" + "@prisma/engines-version": "5.2.0-25.2804dc98259d2ea960602aca6b8e7fdc03c1758f" }, "engines": { "node": ">=16.13" @@ -1884,16 +1887,16 @@ } }, "node_modules/@prisma/engines": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.1.1.tgz", - "integrity": "sha512-NV/4nVNWFZSJCCIA3HIFJbbDKO/NARc9ej0tX5S9k2EVbkrFJC4Xt9b0u4rNZWL4V+F5LAjvta8vzEUw0rw+HA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.2.0.tgz", + "integrity": "sha512-dT7FOLUCdZmq+AunLqB1Iz+ZH/IIS1Fz2THmKZQ6aFONrQD/BQ5ecJ7g2wGS2OgyUFf4OaLam6/bxmgdOBDqig==", "devOptional": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e.tgz", - "integrity": "sha512-owZqbY/wucbr65bXJ/ljrHPgQU5xXTSkmcE/JcbqE1kusuAXV/TLN3/exmz21SZ5rJ7WDkyk70J2G/n68iogbQ==" + "version": "5.2.0-25.2804dc98259d2ea960602aca6b8e7fdc03c1758f", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.2.0-25.2804dc98259d2ea960602aca6b8e7fdc03c1758f.tgz", + "integrity": "sha512-jsnKT5JIDIE01lAeCj2ghY9IwxkedhKNvxQeoyLs6dr4ZXynetD0vTy7u6wMJt8vVPv8I5DPy/I4CFaoXAgbtg==" }, "node_modules/@rushstack/eslint-patch": { "version": "1.3.2", @@ -1913,6 +1916,7 @@ "version": "8.9.3", "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.9.3.tgz", "integrity": "sha512-Ng9rdm3JPoSCi6cVZvANsYnF+UoGVRxflMb270tVj0+LjeT/ZtZ9ckxF6oLPLcKesza6VKBqtdF9mQ+vaz24Aw==", + "dev": true, "dependencies": { "@tanstack/table-core": "8.9.3" }, @@ -1932,6 +1936,7 @@ "version": "8.9.3", "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.9.3.tgz", "integrity": "sha512-NpHZBoHTfqyJk0m/s/+CSuAiwtebhYK90mDuf5eylTvgViNOujiaOaxNDxJkQQAsVvHWZftUGAx1EfO1rkKtLg==", + "dev": true, "engines": { "node": ">=12" }, @@ -1984,9 +1989,9 @@ } }, "node_modules/@types/node": { - "version": "20.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.2.tgz", - "integrity": "sha512-5j/lXt7unfPOUlrKC34HIaedONleyLtwkKggiD/0uuMfT8gg2EOpg0dz4lCD15Ga7muC+1WzJZAjIB9simWd6Q==", + "version": "20.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", + "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", "dev": true }, "node_modules/@types/parse-json": { @@ -3513,9 +3518,9 @@ } }, "node_modules/framer-motion": { - "version": "10.16.1", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.1.tgz", - "integrity": "sha512-K6TXr5mZtitC/dxQCBdg7xzdN0d5IAIrlaqCPKtIQVdzVPGC0qBuJKXggHX1vjnP5gPOFwB1KbCCTWcnFc3kWg==", + "version": "10.16.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.0.tgz", + "integrity": "sha512-R+88Mkr/1dr7XHjacwptfJyrywRzQ1HZX3YSZtN4tFMBq1O8GGCbDEv31Nf/H08o0hUXLC87GkxsR/1bZgwXfw==", "dependencies": { "tslib": "^2.4.0" }, @@ -4397,6 +4402,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5013,13 +5024,13 @@ "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" }, "node_modules/prisma": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.1.1.tgz", - "integrity": "sha512-WJFG/U7sMmcc6TjJTTifTfpI6Wjoh55xl4AzopVwAdyK68L9/ogNo8QQ2cxuUjJf/Wa82z/uhyh3wMzvRIBphg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.2.0.tgz", + "integrity": "sha512-FfFlpjVCkZwrqxDnP4smlNYSH1so+CbfjgdpioFzGGqlQAEm6VHAYSzV7jJgC3ebtY9dNOhDMS2+4/1DDSM7bQ==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.1.1" + "@prisma/engines": "5.2.0" }, "bin": { "prisma": "build/index.js" @@ -5674,6 +5685,23 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, + "node_modules/suneditor": { + "version": "2.45.1", + "resolved": "https://registry.npmjs.org/suneditor/-/suneditor-2.45.1.tgz", + "integrity": "sha512-fLxc0nLwd77vaPuf78D+VAFNAgX9hLps6h96JA/LUCpqt4LeYnEaIE1RfJojX+BhSA+krl5qZ8pdgqcoo3dN3g==", + "dev": true + }, + "node_modules/suneditor-react": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/suneditor-react/-/suneditor-react-3.6.1.tgz", + "integrity": "sha512-12f9KLnEB6pAdyHJINTzRBg3UOWVZZ+jVYSEtwdBTDYQW4amUZr0xOnpikbBAlxb9rcTYV5RHAsad3gnNhLsuA==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "suneditor": "^2.44.10" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index b96ff31..120604d 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,8 @@ "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", "@next-auth/prisma-adapter": "1.0.7", - "@prisma/client": "5.1.1", - "@tanstack/react-table": "8.9.3", - "framer-motion": "10.16.1", + "@prisma/client": "^5.2.0", + "framer-motion": "10.16.0", "jotai": "2.3.1", "next": "13.4.19", "next-auth": "4.23.1", @@ -30,14 +29,18 @@ "swr": "2.2.1" }, "devDependencies": { - "@types/node": "20.5.2", + "@tanstack/react-table": "^8.9.3", + "@types/node": "20.5.1", "@types/react": "18.2.20", "@types/react-dom": "18.2.7", "eslint": "8.47.0", "eslint-config-next": "13.4.19", "eslint-config-prettier": "9.0.0", + "lodash": "^4.17.21", "prettier": "3.0.2", - "prisma": "5.1.1", + "prisma": "^5.2.0", + "suneditor": "^2.45.1", + "suneditor-react": "^3.4.1", "ts-node": "10.9.1", "typescript": "5.1.6" } diff --git a/prisma/migrations/20230715184123_init/migration.sql b/prisma/migrations/20230715184123_init/migration.sql index 7ae4196..1b7176d 100644 --- a/prisma/migrations/20230715184123_init/migration.sql +++ b/prisma/migrations/20230715184123_init/migration.sql @@ -36,7 +36,18 @@ CREATE TABLE "User" ( CONSTRAINT "User_pkey" PRIMARY KEY ("id") ); +-- CreateTable +CREATE TABLE "Post" ( + "id" TEXT NOT NULL, + "title": TEXT, + "createdAt" TIMESTAMP(3) NOT NULL, + "updatedAt" TIMESTAMP(3) NOT NULL, + "published" BOOLEAN, + "authorId" TEXT, + "content" TEXT, + CONSTRAINT "Post_pkey" PRIMARY KEY ("id") +); -- CreateTable CREATE TABLE "VerificationToken" ( "identifier" TEXT NOT NULL, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index bbce590..cfdf5bc 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -51,6 +51,7 @@ model User { role UserRole @default(USER) accounts Account[] sessions Session[] + Post Post[] } model VerificationToken { @@ -60,3 +61,14 @@ model VerificationToken { @@unique([identifier, token]) } + +model Post { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + published Boolean @default(false) + title String @db.VarChar(255) + content String + authorId String + author User? @relation(fields: [authorId], references: [id]) +} diff --git a/src/components/CustomSunEditor/index.tsx b/src/components/CustomSunEditor/index.tsx new file mode 100644 index 0000000..6f16beb --- /dev/null +++ b/src/components/CustomSunEditor/index.tsx @@ -0,0 +1,60 @@ +import { type FC, useRef } from 'react'; +import SunEditor, { buttonList } from 'suneditor-react'; +import SunEditorCore from 'suneditor/src/lib/core'; +import 'suneditor/dist/css/suneditor.min.css'; + +type PropTypes = { + autoFocus?: boolean; + width?: string; + height?: string; + onChange?: ((content: string) => void) | undefined; + placeholder?: string; + onSave?: ((content: string) => void) | undefined; +}; +const PagePostEditor: FC = (props) => { + const { + autoFocus = true, + width = '100%', + height = '300px', + onChange, + placeholder, + onSave, + } = props; + const editor = useRef(); + // The sunEditor parameter will be set to the core suneditor instance when this function is called + const getSunEditorInstance = (sunEditor: SunEditorCore) => { + editor.current = sunEditor; + }; + + return ( + + ); +}; +export default PagePostEditor; diff --git a/src/components/Navbar/index.tsx b/src/components/Navbar/index.tsx index d5df323..73d2d17 100644 --- a/src/components/Navbar/index.tsx +++ b/src/components/Navbar/index.tsx @@ -14,7 +14,7 @@ export const Navbar = () => { Server Admin - + Pages ); diff --git a/src/components/Post/PostList.tsx b/src/components/Post/PostList.tsx new file mode 100644 index 0000000..4ef4923 --- /dev/null +++ b/src/components/Post/PostList.tsx @@ -0,0 +1,78 @@ +import { Box, Spinner } from '@chakra-ui/react'; +import { useSWR } from '@/hooks'; +import _ from 'lodash'; +import { VirtualTable } from '../VirtualTable'; +import { useMemo, useState } from 'react'; +import Router from 'next/router'; +import { ColumnDef } from '@tanstack/react-table'; +import { Post } from '@prisma/client'; + +const defaultColumns: ColumnDef[] = [ + { + header: 'id', + size: 10, + cell(props) { + return <>{props.row.original.id}; + }, + }, + { + header: 'title', + cell(props) { + return <>{props.row.original.title}; + }, + }, + { + header: 'content', + cell(props) { + return ( + + {props.row.original.content} + + ); + }, + }, + { + header: 'createdAt', + cell(props) { + return <>{props.row.original.createdAt}; + }, + }, +]; +const fetcher = async (url: string) => await fetch(url).then((r) => r.json()); +export const PostList = () => { + const { data, error, isLoading } = useSWR('/api/pages/posts', fetcher); + const [columns] = useState(defaultColumns); + + const dataTable: Post[] = useMemo(() => { + if (data?.length) { + return _.cloneDeep(data); + } + return []; + }, [data]); + if (isLoading) + return ( + + + + ); + if (error) return <>{JSON.stringify(error)}; + return ( + + + Router.push({ + pathname: '/post/' + row.item.id, + }) + } + /> + + ); +}; diff --git a/src/components/Post/index.ts b/src/components/Post/index.ts new file mode 100644 index 0000000..1821f94 --- /dev/null +++ b/src/components/Post/index.ts @@ -0,0 +1 @@ +export { PostList } from './PostList'; diff --git a/src/components/index.ts b/src/components/index.ts index acd8727..1292253 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -2,4 +2,5 @@ export * from '@chakra-ui/react'; export * from './AccessDenied'; export * from './Layout'; export * from './NextLink'; +// export * from './CustomSunEditor'; export * from './VirtualTable'; diff --git a/src/pages/api/auth/[...nextauth].ts b/src/pages/api/auth/[...nextauth].ts index ffa1c87..234b9b2 100644 --- a/src/pages/api/auth/[...nextauth].ts +++ b/src/pages/api/auth/[...nextauth].ts @@ -4,27 +4,27 @@ import GoogleProvider from 'next-auth/providers/google'; import { PrismaAdapter } from '@next-auth/prisma-adapter'; import { prisma } from '@/utils/prisma'; -if ( - !process.env.GOOGLE_CLIENT_ID || - !process.env.GOOGLE_CLIENT_SECRET || - !process.env.FACEBOOK_CLIENT_ID || - !process.env.FACEBOOK_CLIENT_SECRET || - !process.env.NEXTAUTH_SECRET -) { - throw new Error('Environment variables are not defined'); -} +// if ( +// !process.env.GOOGLE_CLIENT_ID || +// !process.env.GOOGLE_CLIENT_SECRET || +// !process.env.FACEBOOK_CLIENT_ID || +// !process.env.FACEBOOK_CLIENT_SECRET || +// !process.env.NEXTAUTH_SECRET +// ) { +// throw new Error('Environment variables are not defined'); +// } export const authOptions: NextAuthOptions = { adapter: PrismaAdapter(prisma), providers: [ GoogleProvider({ - clientId: process.env.GOOGLE_CLIENT_ID, - clientSecret: process.env.GOOGLE_CLIENT_SECRET, + clientId: process.env.GOOGLE_CLIENT_ID ?? '', + clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? '', }), FacebookProvider({ - clientId: process.env.FACEBOOK_CLIENT_ID, - clientSecret: process.env.FACEBOOK_CLIENT_SECRET, + clientId: process.env.FACEBOOK_CLIENT_ID ?? '', + clientSecret: process.env.FACEBOOK_CLIENT_SECRET ?? '', }), ], @@ -44,7 +44,7 @@ export const authOptions: NextAuthOptions = { user: { ...session.user, id: user.id, - role: user.role, + // role: user.role ?? '', }, }; }, diff --git a/src/pages/api/pages/[pid].ts b/src/pages/api/pages/[pid].ts new file mode 100644 index 0000000..808733e --- /dev/null +++ b/src/pages/api/pages/[pid].ts @@ -0,0 +1,20 @@ +import { prisma } from '@/utils/prisma'; +import type { NextApiRequest, NextApiResponse } from 'next'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + const { pid } = req.query; + + try { + const getPost = await prisma.post.findUnique({ + where: { + id: pid?.toString(), + }, + }); + return res.status(200).json(getPost); + } catch (error) { + return res.status(400).json(error); + } +} diff --git a/src/pages/api/pages/posts.ts b/src/pages/api/pages/posts.ts new file mode 100644 index 0000000..e703f2a --- /dev/null +++ b/src/pages/api/pages/posts.ts @@ -0,0 +1,27 @@ +import { prisma } from '@/utils/prisma'; +import { Post } from '@prisma/client'; +// import { Post } from '@prisma/client'; +import type { NextApiRequest, NextApiResponse } from 'next'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + if (req.method === 'GET') { + const posts = await prisma.post.findMany(); + + res.status(200).json(posts); + } + if (req.method === 'POST') { + const { title, published, authorId, content } = req.body; + const newPost = await prisma.post.create({ + data: { + title, + published, + authorId, + content, + }, + }); + res.status(200).json(newPost); + } +} diff --git a/src/pages/api/posts/route.ts b/src/pages/api/posts/route.ts new file mode 100644 index 0000000..efc6b43 --- /dev/null +++ b/src/pages/api/posts/route.ts @@ -0,0 +1,21 @@ +import { prisma } from '@/utils/prisma'; +import { Post } from '@prisma/client'; +import { NextResponse } from 'next/server'; + +export const POST = async (request: Post) => { + console.log(request); + return NextResponse.json({ name: 'hello' }); + try { + const body = await request; + console.log(body); + const newPost = await prisma.post.create({ + data: body, + }); + return NextResponse.json(newPost); + } catch (error) { + return NextResponse.json( + { message: 'POST error==>', error }, + { status: 500 } + ); + } +}; diff --git a/src/pages/post/[id].tsx b/src/pages/post/[id].tsx new file mode 100644 index 0000000..c200265 --- /dev/null +++ b/src/pages/post/[id].tsx @@ -0,0 +1,28 @@ +import { Box, Heading, Spinner } from '@chakra-ui/react'; +import { useRouter } from 'next/router'; +import { useSWR } from '@/hooks'; +import { Post } from '@prisma/client'; +const fetcher = async (url: string) => await fetch(url).then((r) => r.json()); + +const PagePost = () => { + const route = useRouter(); + const { id } = route.query; + const { data, error, isLoading } = useSWR('/api/pages/' + id, fetcher); + if (isLoading) + return ( + + + + ); + if (error) return {JSON.stringify(error)}; + return ( + + {data?.title} + + {data?.createdAt?.toString()} + + + + ); +}; +export default PagePost; diff --git a/src/pages/post/pageposteditor.tsx b/src/pages/post/pageposteditor.tsx new file mode 100644 index 0000000..d6eb126 --- /dev/null +++ b/src/pages/post/pageposteditor.tsx @@ -0,0 +1,79 @@ +'use client'; +import { useState } from 'react'; +import { + Checkbox, + Container, + Divider, + Heading, + Input, + useToast, +} from '@chakra-ui/react'; +import dynamic from 'next/dynamic'; +import { PostList } from '@/components/Post'; + +// import { PrismaClient } from '@prisma/client'; +const SunEditor = dynamic(() => import('../../components/CustomSunEditor'), { + ssr: false, +}); + +export default function PagePostEditor() { + const toast = useToast(); + const [title, setTitle] = useState(''); + const [published, setPublished] = useState(true); + + const handleSave = async (content: string) => { + const data = await fetch('/api/pages/posts', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + title: title.trim(), + content, + published, + authorId: 'test-123', + }), + }); + if (data.status === 200) { + toast({ + status: 'success', + title: 'Successfully', + duration: 2000, + isClosable: true, + position: 'top-right', + }); + } else { + toast({ + status: 'error', + description: data.statusText, + duration: 3000, + isClosable: true, + }); + } + }; + return ( + + Tạo bài viết + setTitle(e.target.value)} + placeholder="Tiêu đề..." + w="50%" + size="sm" + my={1} + /> + setPublished(e.target.checked)} + isChecked={published} + size="lg" + mt={1} + ml={1} + > + {published ? 'Công khai' : 'Riêng tư'} + + +
+ + +
+ ); +} diff --git a/src/types/index.ts b/src/types/index.ts index 9d30876..b513919 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -11,3 +11,6 @@ export enum HttpMethod { PUT = 'PUT', TRACE = 'TRACE', } +export enum UserRole { + ADMIN = 'ADMIN', +} diff --git a/tsconfig.json b/tsconfig.json index 61c19ab..9d6b99e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,6 @@ "@/*": ["./src/*"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] }