From 507e1b9ee4906995155be3072a30ac7c21aa02c0 Mon Sep 17 00:00:00 2001 From: Citali Date: Thu, 29 Jan 2026 16:18:57 +0100 Subject: [PATCH] Add extras and options CRUD, add sidebar, add kanban board, udpate packages --- bun.lock | 38 +- components.json | 3 +- next.config.ts | 1 + package.json | 4 + .../requests/updateCommissionRequestStatus.ts | 27 + src/actions/commissions/types/extras.ts | 30 + src/actions/commissions/types/options.ts | 45 + src/app/(admin)/commissions/kanban/page.tsx | 47 + .../(admin)/commissions/types/[id]/page.tsx | 8 +- .../(admin)/commissions/types/extras/page.tsx | 10 + .../commissions/types/options/page.tsx | 10 + src/app/(admin)/layout.tsx | 59 +- .../commissions/extras/ExtraDialog.tsx | 122 ++ .../commissions/extras/ExtraListClient.tsx | 101 ++ .../kanban/CommissionsKanbanClient.tsx | 207 +++ .../commissions/options/OptionDialog.tsx | 121 ++ .../commissions/options/OptionsListClient.tsx | 101 ++ .../commissions/types/EditTypeForm.tsx | 11 +- src/components/global/MobileSidebar.tsx | 33 + src/components/global/Sidebar.tsx | 108 ++ src/components/global/nav.ts | 64 + src/components/ui/collapsible.tsx | 33 + src/components/ui/kanban.tsx | 1106 +++++++++++++++++ src/components/ui/scroll-area.tsx | 58 + src/lib/commissions/kanban.ts | 44 + src/lib/compose-refs.ts | 62 + src/schemas/commissionType.ts | 28 +- src/types/Board.ts | 16 + 28 files changed, 2455 insertions(+), 42 deletions(-) create mode 100644 src/actions/commissions/requests/updateCommissionRequestStatus.ts create mode 100644 src/actions/commissions/types/extras.ts create mode 100644 src/actions/commissions/types/options.ts create mode 100644 src/app/(admin)/commissions/kanban/page.tsx create mode 100644 src/app/(admin)/commissions/types/extras/page.tsx create mode 100644 src/app/(admin)/commissions/types/options/page.tsx create mode 100644 src/components/commissions/extras/ExtraDialog.tsx create mode 100644 src/components/commissions/extras/ExtraListClient.tsx create mode 100644 src/components/commissions/kanban/CommissionsKanbanClient.tsx create mode 100644 src/components/commissions/options/OptionDialog.tsx create mode 100644 src/components/commissions/options/OptionsListClient.tsx create mode 100644 src/components/global/MobileSidebar.tsx create mode 100644 src/components/global/Sidebar.tsx create mode 100644 src/components/global/nav.ts create mode 100644 src/components/ui/collapsible.tsx create mode 100644 src/components/ui/kanban.tsx create mode 100644 src/components/ui/scroll-area.tsx create mode 100644 src/lib/commissions/kanban.ts create mode 100644 src/lib/compose-refs.ts create mode 100644 src/types/Board.ts diff --git a/bun.lock b/bun.lock index 7899a11..304deb4 100644 --- a/bun.lock +++ b/bun.lock @@ -5,26 +5,30 @@ "": { "name": "admin.gaertan.art", "dependencies": { - "@aws-sdk/client-s3": "^3.962.0", - "@aws-sdk/s3-request-presigner": "^3.962.0", + "@aws-sdk/client-s3": "^3.974.0", + "@aws-sdk/s3-request-presigner": "^3.974.0", "@dnd-kit/core": "^6.3.1", + "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", "@hookform/resolvers": "^5.2.2", "@platejs/basic-nodes": "^52.0.11", "@platejs/code-block": "^52.0.11", "@platejs/indent": "^52.0.11", "@platejs/list": "^52.0.11", - "@platejs/markdown": "^52.0.11", - "@prisma/adapter-pg": "^7.2.0", - "@prisma/client": "^7.2.0", + "@platejs/markdown": "^52.1.0", + "@prisma/adapter-pg": "^7.3.0", + "@prisma/client": "^7.3.0", "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-hover-card": "^1.1.15", "@radix-ui/react-label": "^2.1.8", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slider": "^1.3.6", @@ -35,7 +39,7 @@ "@radix-ui/react-tooltip": "^1.2.8", "@tanstack/react-table": "^8.21.3", "archiver": "^7.0.1", - "better-auth": "^1.4.10", + "better-auth": "^1.4.17", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -48,19 +52,19 @@ "next-themes": "^0.4.6", "node-vibrant": "^4.0.3", "nodemailer": "^7.0.12", - "pg": "^8.16.3", - "platejs": "^52.0.15", + "pg": "^8.17.2", + "platejs": "^52.0.17", "react": "19.2.1", "react-day-picker": "^9.13.0", "react-dom": "19.2.1", - "react-hook-form": "^7.69.0", + "react-hook-form": "^7.71.1", "remark-gfm": "^4.0.1", "remark-math": "^6.0.0", "sonner": "^2.0.7", "tailwind-merge": "^3.4.0", "tailwind-scrollbar-hide": "^4.0.0", "uuid": "^13.0.0", - "zod": "^4.3.4", + "zod": "^4.3.6", }, "devDependencies": { "@biomejs/biome": "2.2.0", @@ -68,13 +72,13 @@ "@types/archiver": "^7.0.0", "@types/culori": "^4.0.1", "@types/date-fns": "^2.6.3", - "@types/node": "^20.19.27", - "@types/nodemailer": "^7.0.4", + "@types/node": "^20.19.30", + "@types/nodemailer": "^7.0.5", "@types/pg": "^8.16.0", - "@types/react": "^19.2.7", + "@types/react": "^19.2.9", "@types/react-dom": "^19.2.3", "@types/uuid": "^11.0.0", - "prisma": "^7.2.0", + "prisma": "^7.3.0", "tailwindcss": "^4.1.18", "tw-animate-css": "^1.4.0", "typescript": "^5.9.3", @@ -212,6 +216,8 @@ "@dnd-kit/core": ["@dnd-kit/core@6.3.1", "", { "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ=="], + "@dnd-kit/modifiers": ["@dnd-kit/modifiers@9.0.0", "", { "dependencies": { "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw=="], + "@dnd-kit/sortable": ["@dnd-kit/sortable@10.0.0", "", { "dependencies": { "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg=="], "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="], @@ -398,6 +404,8 @@ "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="], + "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="], + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], @@ -438,6 +446,8 @@ "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="], + "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="], + "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="], "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g=="], diff --git a/components.json b/components.json index 58dfe9b..fc37c01 100644 --- a/components.json +++ b/components.json @@ -19,6 +19,7 @@ "hooks": "@/hooks" }, "registries": { - "@plate": "https://platejs.org/r/{name}.json" + "@plate": "https://platejs.org/r/{name}.json", + "@diceui": "https://diceui.com/r/{name}.json" } } diff --git a/next.config.ts b/next.config.ts index 45204c9..af9080b 100644 --- a/next.config.ts +++ b/next.config.ts @@ -9,6 +9,7 @@ module.exports = { serverActions: { bodySizeLimit: '50mb', }, + proxyClientMaxBodySize: '50mb', }, output: "standalone", } diff --git a/package.json b/package.json index 1ec2f94..ca66047 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "@aws-sdk/client-s3": "^3.974.0", "@aws-sdk/s3-request-presigner": "^3.974.0", "@dnd-kit/core": "^6.3.1", + "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", "@hookform/resolvers": "^5.2.2", "@platejs/basic-nodes": "^52.0.11", "@platejs/code-block": "^52.0.11", @@ -24,12 +26,14 @@ "@prisma/client": "^7.3.0", "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-hover-card": "^1.1.15", "@radix-ui/react-label": "^2.1.8", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slider": "^1.3.6", diff --git a/src/actions/commissions/requests/updateCommissionRequestStatus.ts b/src/actions/commissions/requests/updateCommissionRequestStatus.ts new file mode 100644 index 0000000..98d06cc --- /dev/null +++ b/src/actions/commissions/requests/updateCommissionRequestStatus.ts @@ -0,0 +1,27 @@ +"use server"; + +import { revalidatePath } from "next/cache"; +import { z } from "zod"; + +import { COMMISSION_STATUSES } from "@/lib/commissions/kanban"; +import { prisma } from "@/lib/prisma"; // adjust to your prisma import +// import { requireAdmin } from "@/lib/auth/requireAdmin"; // recommended if you have it + +const schema = z.object({ + id: z.string().min(1), + status: z.enum(COMMISSION_STATUSES), +}); + +export async function updateCommissionRequestStatus(input: z.infer) { + // await requireAdmin(); // enforce auth/role check here + + const { id, status } = schema.parse(input); + + await prisma.commissionRequest.update({ + where: { id }, + data: { status }, + }); + + // revalidate the board page so a refresh always reflects server truth + revalidatePath("/commissions/board"); +} diff --git a/src/actions/commissions/types/extras.ts b/src/actions/commissions/types/extras.ts new file mode 100644 index 0000000..7dbfd1c --- /dev/null +++ b/src/actions/commissions/types/extras.ts @@ -0,0 +1,30 @@ +"use server"; + +import { prisma } from "@/lib/prisma"; +import { commissionExtraSchema } from "@/schemas/commissionType"; +import { revalidatePath } from "next/cache"; + +const LIST_PATH = "/commissions/extras"; + +export async function createCommissionExtra(input: unknown) { + const data = commissionExtraSchema.parse(input); + const created = await prisma.commissionExtra.create({ data }); + revalidatePath(LIST_PATH); + return created; +} + +export async function updateCommissionExtra(id: string, input: unknown) { + const data = commissionExtraSchema.parse(input); + const updated = await prisma.commissionExtra.update({ where: { id }, data }); + revalidatePath(LIST_PATH); + return updated; +} + +export async function deleteCommissionExtra(id: string) { + // Optional safety: + // const used = await prisma.commissionTypeExtra.count({ where: { extraId: id } }); + // if (used > 0) throw new Error("Extra is linked to types."); + console.log("TBD"); + // await prisma.commissionExtra.delete({ where: { id } }); + // revalidatePath(LIST_PATH); +} diff --git a/src/actions/commissions/types/options.ts b/src/actions/commissions/types/options.ts new file mode 100644 index 0000000..fa747f9 --- /dev/null +++ b/src/actions/commissions/types/options.ts @@ -0,0 +1,45 @@ +"use server"; + +import { prisma } from "@/lib/prisma"; +import { commissionOptionSchema } from "@/schemas/commissionType"; +import { revalidatePath } from "next/cache"; + +const LIST_PATH = "/commissions/options"; + +function toInt(v: string) { + const n = Number.parseInt(v, 10); + return Number.isFinite(n) ? n : 0; +} + +export async function createCommissionOption(input: unknown) { + const data = commissionOptionSchema.parse(input); + const created = await prisma.commissionOption.create({ + data: { + name: data.name, + description: data.description?.trim() ? data.description : null, + sortIndex: toInt(data.sortIndex), + }, + }); + revalidatePath(LIST_PATH); + return created; +} + +export async function updateCommissionOption(id: string, input: unknown) { + const data = commissionOptionSchema.parse(input); + const updated = await prisma.commissionOption.update({ + where: { id }, + data: { + name: data.name, + description: data.description?.trim() ? data.description : null, + sortIndex: toInt(data.sortIndex), + }, + }); + revalidatePath(LIST_PATH); + return updated; +} + +export async function deleteCommissionOption(id: string) { + console.log("TBD"); + // await prisma.commissionOption.delete({ where: { id } }); + // revalidatePath(LIST_PATH); +} diff --git a/src/app/(admin)/commissions/kanban/page.tsx b/src/app/(admin)/commissions/kanban/page.tsx new file mode 100644 index 0000000..16fee62 --- /dev/null +++ b/src/app/(admin)/commissions/kanban/page.tsx @@ -0,0 +1,47 @@ +import CommissionsKanbanClient from "@/components/commissions/kanban/CommissionsKanbanClient"; +import { columnIdForStatus } from "@/lib/commissions/kanban"; +import { prisma } from "@/lib/prisma"; + +import type { BoardItem, ColumnsState } from "@/types/Board"; + +export default async function CommissionsBoardPage() { + const requests = await prisma.commissionRequest.findMany({ + where: { + status: { in: ["NEW", "REVIEWING", "ACCEPTED", "INPROGRESS", "COMPLETED"] }, + }, + orderBy: [{ createdAt: "desc" }], + include: { + type: true, + option: true, + extras: true, + files: true, + }, + }); + + const initial: ColumnsState = { + intake: [], + inProgress: [], + completed: [], + }; + + for (const r of requests) { + const col = columnIdForStatus(r.status) ?? "intake"; + + const item: BoardItem = { + id: r.id, + createdAt: r.createdAt.toISOString(), + status: r.status, + customerName: r.customerName, + customerEmail: r.customerEmail, + message: r.message, + typeName: r.type?.name ?? null, + optionName: r.option?.name ?? null, + extrasCount: r.extras.length, + filesCount: r.files.length, + }; + + initial[col].push(item); + } + + return ; +} diff --git a/src/app/(admin)/commissions/types/[id]/page.tsx b/src/app/(admin)/commissions/types/[id]/page.tsx index 2e1883d..ab4d473 100644 --- a/src/app/(admin)/commissions/types/[id]/page.tsx +++ b/src/app/(admin)/commissions/types/[id]/page.tsx @@ -19,9 +19,9 @@ export default async function CommissionTypesEditPage({ params }: { params: { id const extras = await prisma.commissionExtra.findMany({ orderBy: [{ sortIndex: "asc" }, { name: "asc" }], }) - const customInputs = await prisma.commissionCustomInput.findMany({ - orderBy: [{ sortIndex: "asc" }, { name: "asc" }], - }) + // const customInputs = await prisma.commissionCustomInput.findMany({ + // orderBy: [{ sortIndex: "asc" }, { name: "asc" }], + // }) if (!commissionType) { return
Type not found
@@ -32,7 +32,7 @@ export default async function CommissionTypesEditPage({ params }: { params: { id

Edit Commission Type

- + ); } \ No newline at end of file diff --git a/src/app/(admin)/commissions/types/extras/page.tsx b/src/app/(admin)/commissions/types/extras/page.tsx new file mode 100644 index 0000000..96ab852 --- /dev/null +++ b/src/app/(admin)/commissions/types/extras/page.tsx @@ -0,0 +1,10 @@ +import { ExtraListClient } from "@/components/commissions/extras/ExtraListClient"; +import { prisma } from "@/lib/prisma"; + +export default async function CommissionTypesExtrasPage() { + const extras = await prisma.commissionExtra.findMany({ + orderBy: [{ createdAt: "asc" }, { name: "asc" }], + }); + + return ; +} \ No newline at end of file diff --git a/src/app/(admin)/commissions/types/options/page.tsx b/src/app/(admin)/commissions/types/options/page.tsx new file mode 100644 index 0000000..ec03809 --- /dev/null +++ b/src/app/(admin)/commissions/types/options/page.tsx @@ -0,0 +1,10 @@ +import { OptionsListClient } from "@/components/commissions/options/OptionsListClient"; +import { prisma } from "@/lib/prisma"; + +export default async function CommissionTypesOptionsPage() { + const options = await prisma.commissionOption.findMany({ + orderBy: [{ createdAt: "asc" }, { name: "asc" }], + }); + + return ; +} \ No newline at end of file diff --git a/src/app/(admin)/layout.tsx b/src/app/(admin)/layout.tsx index 3895bed..5ef506e 100644 --- a/src/app/(admin)/layout.tsx +++ b/src/app/(admin)/layout.tsx @@ -1,6 +1,8 @@ +import LogoutButton from "@/components/auth/LogoutButton"; import Footer from "@/components/global/Footer"; -import Header from "@/components/global/Header"; -import { Toaster } from "@/components/ui/sonner"; +import MobileSidebar from "@/components/global/MobileSidebar"; +import ModeToggle from "@/components/global/ModeToggle"; +import Sidebar from "@/components/global/Sidebar"; export default function AdminLayout({ children, @@ -8,17 +10,48 @@ export default function AdminLayout({ children: React.ReactNode; }>) { return ( -
-
-
-
-
- {children} -
-