diff --git a/dashboard/src/components/forms/IdentityTraitForm.tsx b/dashboard/src/components/forms/IdentityTraitForm.tsx index 8f863d8..ef4cda5 100644 --- a/dashboard/src/components/forms/IdentityTraitForm.tsx +++ b/dashboard/src/components/forms/IdentityTraitForm.tsx @@ -1,82 +1,108 @@ 'use client'; -import { Form, FormControl, FormField, FormItem, FormLabel } from '@/components/ui/form'; -import { Input } from '@/components/ui/input'; -import { generateZodSchema, KratosSchema, KratosSchemaProperties } from '@/lib/forms/identity-form'; -import { useForm, UseFormReturn } from 'react-hook-form'; +import { KratosSchema, kratosSchemaToZod } from '@/lib/forms/identity-form'; +import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; -import { toast } from 'sonner'; import { Identity } from '@ory/client'; -import { Checkbox } from '@/components/ui/checkbox'; +import { toast } from 'sonner'; +import DynamicForm from '@/components/dynamic-form'; +import { FormControl, FormDescription, FormField, FormItem, FormLabel } from '@/components/ui/form'; +import { Textarea } from '@/components/ui/textarea'; +import { zu } from 'zod_utilz'; +import { updateIdentity } from '@/app/(inside)/user/action'; +import { useState } from 'react'; interface IdentityTraitFormProps { schema: KratosSchema; identity: Identity; } -function renderUiNodes(form: UseFormReturn, properties: KratosSchemaProperties, prefix?: string): any { - - let keyPrefix = prefix ? prefix + '.' : ''; - - return Object.entries(properties).map(([key, value]) => { - if (value.type === 'object') { - return renderUiNodes(form, value.properties!, key); - } else if (value.type === 'boolean') { - return ( - ( - - - {value.title} - - )} - /> - ); - } else { - return ( - ( - - {value.title} - - - - - )} - /> - ); - } - }, - ); -} - export function IdentityTraitForm({ schema, identity }: IdentityTraitFormProps) { - const zodIdentitySchema = generateZodSchema(schema); - const form = useForm>({ - defaultValues: identity.traits, - resolver: zodResolver(zodIdentitySchema), + const [currentIdentity, setCurrentIdentity] = useState(identity); + + const generated = kratosSchemaToZod(schema); + const metadata = z.object({ + metadata_public: zu.stringToJSON(), + metadata_admin: zu.stringToJSON(), }); - function onSubmit(values: z.infer) { - toast.message(JSON.stringify(values, null, 4)); - } + const zodIdentitySchema = generated.merge(metadata); + + const form = useForm>({ + resolver: zodResolver(zodIdentitySchema), + defaultValues: { + ...currentIdentity.traits, + metadata_public: currentIdentity.metadata_public ? JSON.stringify(currentIdentity.metadata_public) : '', + metadata_admin: currentIdentity.metadata_admin ? JSON.stringify(currentIdentity.metadata_admin) : '', + }, + }); + + const onValid = (data: z.infer) => { + + const traits = structuredClone(data); + delete traits['metadata_public']; + delete traits['metadata_admin']; + + updateIdentity({ + id: currentIdentity.id, + body: { + schema_id: currentIdentity.schema_id, + state: currentIdentity.state!, + traits: traits, + metadata_public: data.metadata_public, + metadata_admin: data.metadata_admin, + }, + }) + .then((identity) => { + setCurrentIdentity(identity); + toast.success('Identity updated'); + }) + .catch(() => { + toast.error('Updating identity failed'); + }); + }; + + const onInvalid = (data: z.infer) => { + console.log('data', data); + toast.error('Invalid values'); + }; return ( -
- - { - renderUiNodes(form, schema.properties.traits.properties) - } -
- + + ( + + Public Metadata + +