From 9d18b6da02f3bcde3ad0f9d8945cbc6349872f1b Mon Sep 17 00:00:00 2001 From: Citali Date: Sat, 27 Dec 2025 12:59:42 +0100 Subject: [PATCH] Add guidelines --- .../20251227110121_com_2/migration.sql | 13 ++ prisma/schema.prisma | 13 +- .../commissions/guidelines/getGuidelines.ts | 11 ++ .../commissions/guidelines/saveGuidelines.ts | 16 +++ src/app/commissions/guidelines/page.tsx | 17 +++ .../commissions/guidelines/Editor.tsx | 113 ++++++++++++++++++ src/components/global/TopNav.tsx | 4 + 7 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 prisma/migrations/20251227110121_com_2/migration.sql create mode 100644 src/actions/commissions/guidelines/getGuidelines.ts create mode 100644 src/actions/commissions/guidelines/saveGuidelines.ts create mode 100644 src/app/commissions/guidelines/page.tsx create mode 100644 src/components/commissions/guidelines/Editor.tsx diff --git a/prisma/migrations/20251227110121_com_2/migration.sql b/prisma/migrations/20251227110121_com_2/migration.sql new file mode 100644 index 0000000..65e0722 --- /dev/null +++ b/prisma/migrations/20251227110121_com_2/migration.sql @@ -0,0 +1,13 @@ +-- CreateTable +CREATE TABLE "CommissionGuidelines" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "markdown" TEXT NOT NULL, + "isActive" BOOLEAN NOT NULL DEFAULT true, + + CONSTRAINT "CommissionGuidelines_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "CommissionGuidelines_isActive_idx" ON "CommissionGuidelines"("isActive"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 805ecfa..e306cd5 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -355,11 +355,22 @@ model CommissionRequest { sortIndex Int @default(0) } +model CommissionGuidelines { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + markdown String + isActive Boolean @default(true) + + @@index([isActive]) +} + model TermsOfService { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - version Int @default(autoincrement()) markdown String + version Int @default(autoincrement()) } diff --git a/src/actions/commissions/guidelines/getGuidelines.ts b/src/actions/commissions/guidelines/getGuidelines.ts new file mode 100644 index 0000000..fef8306 --- /dev/null +++ b/src/actions/commissions/guidelines/getGuidelines.ts @@ -0,0 +1,11 @@ +'use server'; + +import { prisma } from "@/lib/prisma"; + +export async function getActiveGuidelines(): Promise { + const guidelines = await prisma.commissionGuidelines.findFirst({ + where: { isActive: true }, + orderBy: { createdAt: 'desc' }, + }); + return guidelines?.markdown ?? null; +} diff --git a/src/actions/commissions/guidelines/saveGuidelines.ts b/src/actions/commissions/guidelines/saveGuidelines.ts new file mode 100644 index 0000000..b4f42ae --- /dev/null +++ b/src/actions/commissions/guidelines/saveGuidelines.ts @@ -0,0 +1,16 @@ +'use server'; + +import { prisma } from "@/lib/prisma"; + +export async function saveGuidelines(markdown: string) { + await prisma.commissionGuidelines.updateMany({ + where: { isActive: true }, + data: { isActive: false }, + }); + + await prisma.commissionGuidelines.create({ + data: { + markdown, + }, + }); +} \ No newline at end of file diff --git a/src/app/commissions/guidelines/page.tsx b/src/app/commissions/guidelines/page.tsx new file mode 100644 index 0000000..8820352 --- /dev/null +++ b/src/app/commissions/guidelines/page.tsx @@ -0,0 +1,17 @@ +import { getActiveGuidelines } from "@/actions/commissions/guidelines/getGuidelines"; +import GuidelinesEditor from "@/components/commissions/guidelines/Editor"; + +export default async function CommissionGuidelinesPage() { + const markdown = await getActiveGuidelines(); + + return ( +
+
+

Terms of Service

+
+
+ +
+
+ ); +} \ No newline at end of file diff --git a/src/components/commissions/guidelines/Editor.tsx b/src/components/commissions/guidelines/Editor.tsx new file mode 100644 index 0000000..96a1447 --- /dev/null +++ b/src/components/commissions/guidelines/Editor.tsx @@ -0,0 +1,113 @@ +"use client" + +import type { Value } from 'platejs'; + +import { saveGuidelines } from '@/actions/commissions/guidelines/saveGuidelines'; +import { BasicBlocksKit } from '@/components/editor/plugins/basic-blocks-kit'; +import { BasicMarksKit } from '@/components/editor/plugins/basic-marks-kit'; +import { CodeBlockKit } from '@/components/editor/plugins/code-block-kit'; +import { ListKit } from '@/components/editor/plugins/list-kit'; +import { MarkdownKit } from '@/components/editor/plugins/markdown-kit'; +import { Editor, EditorContainer } from '@/components/ui/editor'; +import { FixedToolbar } from '@/components/ui/fixed-toolbar'; +import { BulletedListToolbarButton, NumberedListToolbarButton } from '@/components/ui/list-toolbar-button'; +import { MarkToolbarButton } from '@/components/ui/mark-toolbar-button'; +import { ToolbarButton } from '@/components/ui/toolbar'; +import { + Bold, + Braces, + Code, + Heading1, + Heading2, + Heading3, + Italic, + Quote, + Save, + Strikethrough, + Underline +} from "lucide-react"; +import { Plate, usePlateEditor } from 'platejs/react'; +import { useEffect } from 'react'; + +const initialValue: Value = [ +]; + + +export default function GuidelinesEditor({ markdown }: { markdown: string | null }) { + // const [isSaving, setIsSaving] = useState(false); + const editor = usePlateEditor({ + plugins: [ + ...BasicBlocksKit, + ...CodeBlockKit, + ...ListKit, + ...BasicMarksKit, + ...MarkdownKit, + ], + value: initialValue, + }); + + useEffect(() => { + if (markdown && editor.api.markdown.deserialize) { + const markdownValue = editor.api.markdown.deserialize(markdown); + // console.log(markdownValue); + editor.children = markdownValue; + } + }, [editor, markdown]); + + const handleSave = async () => { + // console.log(editor); + if (!editor.api.markdown.serialize) return; + // setIsSaving(true); + const markdown = editor.api.markdown.serialize(); + await saveGuidelines(markdown); + // setIsSaving(false); + }; + + return ( + {/* Provides editor context */} + + {/* Blocks */} + editor.tf.h1.toggle()} tooltip="Heading 1"> + + + editor.tf.h2.toggle()} tooltip="Heading 2"> + + + editor.tf.h3.toggle()} tooltip="Heading 3"> + + + editor.tf.blockquote.toggle()} tooltip="Blockquote"> + + + editor.tf.code_block.toggle()} tooltip="Code Block"> + + + + + {/* Mark Toolbar Buttons */} + + + + + + + + + + + + + + + + {/* Save Button */} + + + + + {/* Styles the editor area */} + + + + ); +} \ No newline at end of file diff --git a/src/components/global/TopNav.tsx b/src/components/global/TopNav.tsx index 29a6ba7..175b243 100644 --- a/src/components/global/TopNav.tsx +++ b/src/components/global/TopNav.tsx @@ -33,6 +33,10 @@ const commissionItems = [ { title: "Types", href: "/commissions/types", + }, + { + title: "Guidelines", + href: "/commissions/guidelines", } ]