diff --git a/.prettierrc b/.prettierrc index ab57dca..f9e575c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -11,7 +11,9 @@ "arrowParens": "always", "importOrder": [ "^@/components(.*)$", + "^@/types(.*)$", "^@/lib(.*)$", + "^@/providers(.*)$", "^@/styles(.*)$", "^[./]" ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c05e736..98ca98f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4489,7 +4489,7 @@ snapshots: debug: 4.3.6 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.0.1(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.6 @@ -4501,7 +4501,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index d2f8422..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/favicon.ico b/src/app/favicon.ico index 718d6fe..e20a7a8 100644 Binary files a/src/app/favicon.ico and b/src/app/favicon.ico differ diff --git a/src/app/form/[id]/done/page.tsx b/src/app/form/[id]/done/page.tsx new file mode 100644 index 0000000..c87c00c --- /dev/null +++ b/src/app/form/[id]/done/page.tsx @@ -0,0 +1,15 @@ +import { Box } from '@/components' + +export default function Page() { + return ( +
+ +

+ คำตอบของคุณถูกบันทึกแล้ว +

+
+

ขอบคุณสำหรับคำตอบ

+
+
+ ) +} diff --git a/src/app/form/[id]/layout.tsx b/src/app/form/[id]/layout.tsx index fbf0c86..43c9f7f 100644 --- a/src/app/form/[id]/layout.tsx +++ b/src/app/form/[id]/layout.tsx @@ -1,14 +1,23 @@ -import FormProvider from '@/providers/form-provider' +import { getFormSchema } from '@/lib/form/get-form-schema' + +import { FormSchemaProvider } from '@/providers/form-schema-provider' + +export async function generateMetadata({ + params: { id }, +}: { + params: { id: string } +}) { + const form = await getFormSchema(id) + + return { + title: form.heading, + } +} export default async function FormLayout({ children, }: Readonly<{ children: React.ReactNode }>) { - return {children} - return ( -
- {children} -
- ) + return {children} } diff --git a/src/app/form/[id]/page.tsx b/src/app/form/[id]/page.tsx index a3d6dd8..622c98b 100644 --- a/src/app/form/[id]/page.tsx +++ b/src/app/form/[id]/page.tsx @@ -1,19 +1,21 @@ 'use client' -import { useForm } from '@/providers/form-provider' +import { useRouter } from 'next/navigation' import { useEffect } from 'react' import { Toaster, toast } from 'react-hot-toast' -import { FormContainer } from '@/components/form/form-container' -import { FormHeader } from '@/components/form/form-header' -import { FormQuestion } from '@/components/form/form-question' +import { Box } from '@/components' +import { Field } from '@/components/form/field' + +import { useFormSchema } from '@/providers/form-schema-provider' interface PageProps { params: { id: string } } export default function Page({ params: { id } }: PageProps) { - const { form, setID } = useForm() + const { formSchema, setID } = useFormSchema() + const router = useRouter() useEffect(() => { setID(id) @@ -37,7 +39,8 @@ export default function Page({ params: { id } }: PageProps) { toast.error(errorData.error) return } - window.location.href = `${process.env.NEXT_PUBLIC_BASE_URL}/form/done` + + router.push(`/form/${id}/done`) } const handleReset = (e: React.FormEvent) => { @@ -47,19 +50,27 @@ export default function Page({ params: { id } }: PageProps) { return (
- - + +

+ {formSchema.heading} +

+
+

+ {formSchema.subheading} +

+
+
- {form.columns.map((column) => ( + {formSchema.columns.map((column) => (
- +
))}
@@ -77,7 +88,7 @@ export default function Page({ params: { id } }: PageProps) {
- + ) } diff --git a/src/app/form/api/route.ts b/src/app/form/api/route.ts index d9e04f5..2b58bec 100644 --- a/src/app/form/api/route.ts +++ b/src/app/form/api/route.ts @@ -1,6 +1,6 @@ import { checkIdParams } from '@/lib/form/check-form' +import { getFormIds } from '@/lib/form/get-form-ids' import { getFormSchema } from '@/lib/form/get-form-schema' -import { getNocoID } from '@/lib/form/get-nocoID' export async function GET(request: Request) { // checking id @@ -23,7 +23,7 @@ export async function POST(request: Request) { const body = await request.json() - const tableIdResponse = await getNocoID(id) + const tableIdResponse = await getFormIds(id) if (tableIdResponse === null) { return Response.json({ error: 'No matching form name' }, { status: 400 }) } diff --git a/src/app/form/done/page.tsx b/src/app/form/done/page.tsx deleted file mode 100644 index 6ca7e22..0000000 --- a/src/app/form/done/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { FormHeader } from '@/components/form/form-header' - -export default function Page() { - return ( -
- -
- ) -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 5b80db8..6d1d642 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -16,8 +16,8 @@ const ibmPlexSansThai = IBM_Plex_Sans_Thai({ // TODO: Add your own metadata export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', + title: 'Intania Form', + description: 'Form wrapper for Chula Intania', } export default function RootLayout({ diff --git a/src/app/page.tsx b/src/app/page.tsx index 2315334..80ba33b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,3 @@ export default function Home() { - return ( -
-

Hello World!

-
- ) + return
Unauthorized
} diff --git a/src/components/box.tsx b/src/components/box.tsx new file mode 100644 index 0000000..9378f3e --- /dev/null +++ b/src/components/box.tsx @@ -0,0 +1,11 @@ +interface BoxProps { + children: React.ReactNode +} + +export const Box = ({ children }: BoxProps): JSX.Element => { + return ( +
+ {children} +
+ ) +} diff --git a/src/components/checkbox.tsx b/src/components/checkbox.tsx new file mode 100644 index 0000000..e17d242 --- /dev/null +++ b/src/components/checkbox.tsx @@ -0,0 +1,32 @@ +'use client' + +import toast from 'react-hot-toast' + +import type { FormColumn } from '@/types' + +interface CheckboxProps { + column: FormColumn +} + +export const Checkbox = ({ column }: CheckboxProps): JSX.Element => { + return ( +
+ +
+ ) +} diff --git a/src/components/form/form-question.tsx b/src/components/form/field.tsx similarity index 67% rename from src/components/form/form-question.tsx rename to src/components/form/field.tsx index 60a0273..03e831c 100644 --- a/src/components/form/form-question.tsx +++ b/src/components/form/field.tsx @@ -1,8 +1,8 @@ -import { FormColumn } from '@/types/form' +import { FormComponent } from '@/components/form/form-component' -import { getFormComponent } from '@/components/form/form-component' +import type { FormColumn } from '@/types' -export function FormQuestion({ column }: { column: FormColumn }) { +export function Field({ column }: { column: FormColumn }) { return (
@@ -14,7 +14,7 @@ export function FormQuestion({ column }: { column: FormColumn }) { {column.description}

- {getFormComponent(column)} + {FormComponent(column)}
) } diff --git a/src/components/form/form-component.tsx b/src/components/form/form-component.tsx index fa00227..bd59266 100644 --- a/src/components/form/form-component.tsx +++ b/src/components/form/form-component.tsx @@ -1,133 +1,30 @@ -import { FormColumn } from '@/types/form' -import { UIDataType } from '@/types/ui-data' -import React from 'react' -import { toast } from 'react-hot-toast' +import { Checkbox, Input, SingleSelect, Textarea } from '@/components' -import { Input } from '@/components/input' +import type { FormColumn } from '@/types' -export const getFormComponent = (column: FormColumn): React.ReactNode => { - if (!Object.values(UIDataType).includes(column.uidt)) { - return ( -

- This system does not support {column.uidt}. -

- ) - } +export const FormComponent = (column: FormColumn): React.ReactNode => { switch (column.uidt) { case 'SingleLineText': - return ( - - ) + return case 'PhoneNumber': return ( ) case 'Number': return ( - + ) case 'Checkbox': - return ( -
- -
- ) + return case 'SingleSelect': - return ( -
- -

- จำเป็นต้องเลือก -

-
- ) + return case 'LongText': - return ( -
-