import * as React from 'react' import { Box, Button, Dialog, Flex, Stack } from '@sanity/ui' import { useSelector } from '@xstate/react' import { z, ZodError } from 'zod' import { FormInputText } from '../Forms/FormInputText' import { useGlobalState } from '../../contexts/GlobalStateContext' const settingsFormSchema = z.object({ clientId: z .string({ required_error: "Your app's ID is required" }) .min(1, "Your app's ID is required"), clientSecret: z .string({ required_error: "Your app's secret is required" }) .min(1, "Your app's secret is required"), redirectUrl: z .string({ required_error: "Your app's redirect uri is required", }) .url('Your redirect url must be a URL'), }) /** * TODO: add zod for form validation */ export const DialogSettings = () => { const [formErrors, setFormErrors] = React.useState({ clientId: '', clientSecret: '', redirectUrl: '', }) const formRef = React.useRef(null!) const globalState = useGlobalState() const { send } = globalState const isSavingSettings = useSelector(globalState, (state) => state.matches('settings.settingsSaving') ) const settings = useSelector(globalState, (state) => state.context.settings) const handleDialogClose = () => { send('SETTINGS_HIDE') } const handleFormData = (formData: FormData) => { try { const payload: Record = {} formData.forEach((val, key) => (payload[key] = val)) const parsedPayload = settingsFormSchema.parse(payload) send({ type: 'SETTINGS_SAVING', payload: parsedPayload }) } catch (err) { if (err instanceof ZodError) { const zodErrors = err.issues.reduce((acc, issue) => { const input = issue.path .slice(-1)[0] .toString() as keyof typeof formErrors acc[input] = issue.message return acc }, {} as typeof formErrors) setFormErrors((s) => ({ ...s, ...zodErrors })) } } } const handleSubmit: React.FormEventHandler = (e) => { e.preventDefault() const formData = new FormData(e.target as HTMLFormElement) handleFormData(formData) } const handleSaveClick = () => { const formData = new FormData(formRef.current as unknown as HTMLFormElement) handleFormData(formData) } return ( } width={1} > ) } interface DialogSettingsFooterProps { onClick: () => void isSavingSettings: boolean } const DialogSettingsFooter = ({ onClick, isSavingSettings, }: DialogSettingsFooterProps) => (