diff --git a/apps/api/src/util/package.ts b/apps/api/src/util/package.ts index 82dad612..ba5ca96a 100644 --- a/apps/api/src/util/package.ts +++ b/apps/api/src/util/package.ts @@ -1,2 +1 @@ -export const LIB_VERSION = '1.1.0'; -export const LIB_LICENSE = undefined; +export const LIB_VERSION = "1.1.0";export const LIB_LICENSE = undefined; diff --git a/apps/dashboard/next.config.ts b/apps/dashboard/next.config.ts index e15a5c69..7fb29260 100644 --- a/apps/dashboard/next.config.ts +++ b/apps/dashboard/next.config.ts @@ -2,9 +2,22 @@ import type { NextConfig } from 'next'; import path from 'path'; const nextConfig: NextConfig = { - experimental: {}, + experimental: { + turbo: {}, + }, + transpilePackages: [ + '@tiptap/react', + '@tiptap/starter-kit', + '@tiptap/extension-underline', + '@tiptap/extension-link', + '@tiptap/extension-superscript', + '@tiptap/extension-subscript', + '@tiptap/extension-highlight', + '@tiptap/extension-text-align', + ], output: 'standalone', poweredByHeader: false, + reactStrictMode: true, outputFileTracingRoot: path.join(__dirname, '../../'), }; diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 64c48ff4..07bb79f6 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -23,8 +23,9 @@ "@mantine/notifications": "^7.13.2", "@mantine/nprogress": "^7.13.2", "@mantine/spotlight": "^7.13.2", - "@tabler/icons-react": "^3.9.0", + "@mantine/tiptap": "^7.13.2", "@repo/db": "*", + "@tabler/icons-react": "^3.9.0", "clsx": "^2.1.1", "dayjs": "^1.11.11", "mantine-contextmenu": "^7.11.0", @@ -33,6 +34,7 @@ "moment-timezone": "^0.5.45", "next": "15.0.2", "next-auth": "^4.24.7", + "next-transpile-modules": "^10.0.1", "react": "19.0.0-rc-02c0e824-20241028", "react-dom": "19.0.0-rc-02c0e824-20241028", "recharts": "2", @@ -60,4 +62,4 @@ "@types/react": "npm:types-react@19.0.0-rc.1", "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1" } -} \ No newline at end of file +} diff --git a/apps/dashboard/src/app/actions.ts b/apps/dashboard/src/app/actions.ts new file mode 100644 index 00000000..948ddbf1 --- /dev/null +++ b/apps/dashboard/src/app/actions.ts @@ -0,0 +1,44 @@ +'use server'; + +import prisma from '@/util/db'; +import { revalidatePath } from 'next/cache'; + +export const addFaqQuestion = async (data: { question: string; answer: string }) => { + const { question, answer } = data; + + const faq = await prisma.fAQQuestion.create({ + data: { + question, + answer, + }, + }); + + revalidatePath('/am/faq'); + return faq; +}; + +export const editFaqQuestion = async (data: { question: string; answer: string; id: string }) => { + const faq = await prisma.fAQQuestion.update({ + where: { + id: data.id, + }, + data: { + question: data.question, + answer: data.answer, + }, + }); + + revalidatePath('/am/faq'); + return faq; +}; + +export const deleteFaqQuestion = async (id: any) => { + const faq = await prisma.fAQQuestion.delete({ + where: { + id, + }, + }); + + revalidatePath('/am/faq'); + return faq; +}; diff --git a/apps/dashboard/src/app/am/faq/datatable.tsx b/apps/dashboard/src/app/am/faq/datatable.tsx index f8b56ec8..61703f2d 100644 --- a/apps/dashboard/src/app/am/faq/datatable.tsx +++ b/apps/dashboard/src/app/am/faq/datatable.tsx @@ -3,9 +3,10 @@ import { ActionIcon, Code, Group } from '@mantine/core'; import { IconEdit, IconExternalLink } from '@tabler/icons-react'; -import { DataTable } from 'mantine-datatable'; import { FAQQuestion } from '@repo/db'; +import { DataTable } from 'mantine-datatable'; import Link from 'next/link'; +import { EditFaqQuestionButton } from './interactivity'; export default function FAQDatatabe({ faq }: { faq: FAQQuestion[] }) { return ( @@ -22,11 +23,9 @@ export default function FAQDatatabe({ faq }: { faq: FAQQuestion[] }) { accessor: '', title: '', textAlign: 'right', - render: (question) => ( + render: (question: FAQQuestion) => ( - - - + } + onClick={() => + modals.open({ + id: 'add-faq-question', + title: 'Add new FAQ Question', + centered: true, + size: 'lg', + children: , + }) + } + > + Add New + + ); +} + +export function EditFaqQuestionButton(props: FAQQuestion) { + return ( + + modals.open({ + id: 'edit-faq-question', + title: 'Edit FAQ Question', + centered: true, + size: 'lg', + children: , + }) + } + > + + + ); +} + +function EditFaqQuestionModal( + props: { + isAdd?: boolean; + } & FAQQuestion, +) { + const form = useForm({ + initialValues: { id: props.id, question: props.question, answer: props.answer, links: props.links }, + }); + const [[addFaqQuestionAction,editFaqQuestionAction, deleteFaqQuestionAction], isPending] = useFormActions([ + addFaqQuestion, + editFaqQuestion, + deleteFaqQuestion, + ]); + + const handleSubmit = (values: FAQQuestion) => { + if (props.isAdd) { + addFaqQuestionAction(values); + } else { + editFaqQuestionAction(values); + } + modals.closeAll(); + }; + + return ( +
+ + + + + {!props.isAdd ? ( + + + + + ) : ( + + )} + + ); +} diff --git a/apps/dashboard/src/app/am/faq/page.tsx b/apps/dashboard/src/app/am/faq/page.tsx index 0ebc2e99..061c8571 100644 --- a/apps/dashboard/src/app/am/faq/page.tsx +++ b/apps/dashboard/src/app/am/faq/page.tsx @@ -1,14 +1,10 @@ -import { - Box, - Button, - Group, - Title -} from '@mantine/core'; -import { IconExternalLink, IconPlus } from '@tabler/icons-react'; +import { Box, Button, Group, Title } from '@mantine/core'; -import prisma from '@/util/db'; -import Link from 'next/link'; +import { AddFaqQuestionButton } from './interactivity'; import FAQDatatabe from './datatable'; +import { IconExternalLink } from '@tabler/icons-react'; +import Link from 'next/link'; +import prisma from '@/util/db'; export default async function Page() { const faq = await prisma.fAQQuestion.findMany(); @@ -18,9 +14,7 @@ export default async function Page() { FAQ Questions - + diff --git a/apps/dashboard/src/app/layout.tsx b/apps/dashboard/src/app/layout.tsx index 564c1981..55e7c2df 100644 --- a/apps/dashboard/src/app/layout.tsx +++ b/apps/dashboard/src/app/layout.tsx @@ -6,16 +6,18 @@ import '@mantine/dates/styles.layer.css'; import '@mantine/notifications/styles.layer.css'; import '@mantine/nprogress/styles.layer.css'; import '@mantine/spotlight/styles.layer.css'; +import '@mantine/tiptap/styles.layer.css'; import 'mantine-datatable/styles.layer.css'; import { ColorSchemeScript, MantineProvider } from '@mantine/core'; +import AppLayout from '@/components/layout'; import AuthProvider from '@/components/AuthProvider'; +import { Inter } from 'next/font/google'; +import { ModalsProvider } from '@mantine/modals'; +import { Notifications } from '@mantine/notifications'; import SWRSetup from '@/components/core/SWRSetup'; -import AppLayout from '@/components/layout'; import { getSession } from '@/util/auth'; -import { Notifications } from '@mantine/notifications'; -import { Inter } from 'next/font/google'; import localFont from 'next/font/local'; export const interFont = Inter({ @@ -36,14 +38,16 @@ export default async function RootLayout({ children }: { children: React.ReactNo return ( - + - - {children} + + + {children} + diff --git a/apps/dashboard/src/components/input/FormButton.tsx b/apps/dashboard/src/components/input/FormButton.tsx new file mode 100644 index 00000000..8a067cd7 --- /dev/null +++ b/apps/dashboard/src/components/input/FormButton.tsx @@ -0,0 +1,18 @@ +"use client" + +import { Button, ButtonProps, PolymorphicComponentProps } from '@mantine/core'; +import { useEffect, useState } from 'react'; + +import { useFormStatus } from 'react-dom'; + +export function FormButton(props: PolymorphicComponentProps<"button", ButtonProps>) { + const {pending} = useFormStatus(); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + console.log(new Date().toISOString(), "pending: "+pending) + setIsLoading(pending); + }, [pending]); + + return