import { Box, Container, Flex, Heading, Text } from '@radix-ui/themes'; import { useMutation, useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router'; import { toast } from 'react-toastify/unstyled'; import * as v from 'valibot'; import { useResponseErrorHandler } from '../hooks/ResponseHelper'; import { useApi } from '../providers/ApiProvider'; import { formHook } from '../providers/FormProvider'; import { TooltipContentContainer } from '../components/info'; import { SearchParamKeys } from '../lib/constants'; import { useQueryMessage } from '../hooks/useQueryMessage'; import { QueryMessageCode, QueryMessageType } from '../lib/QueryMessages'; const initFormSchema = v.object({ username: v.pipe(v.string(), v.trim(), v.minLength(1, 'Username is required')), password: v.pipe(v.string(), v.minLength(1, 'Password is required')), setup_secret: v.pipe(v.string(), v.minLength(1, 'Setup secret is required')), }); export default function InitRoute() { const navigate = useNavigate(); const { tanstackApiClient } = useApi(); const { defaultResponseErrorHandler } = useResponseErrorHandler(); const { toSearchParamQueryMessage } = useQueryMessage(); const { mutateAsync: initAdmin, isPending } = useMutation({ ...tanstackApiClient.mutation('post', '/api/auth/init_admin').mutationOptions, onSuccess: async () => { const searchParams = new URLSearchParams(); searchParams.set(SearchParamKeys.Message, toSearchParamQueryMessage(QueryMessageCode.InitializationSuccessful, QueryMessageType.Success)); navigate(`/login?${searchParams.toString()}`); }, onError: (error) => { if (defaultResponseErrorHandler(error)) return; console.error('Init failed:', error); }, }); const { queryOptions: healthInfoQuery } = tanstackApiClient.get('/api/health/info'); useQuery({ ...healthInfoQuery, queryFn: async (...args) => { try { const data = await healthInfoQuery.queryFn!(...args); if (data.is_initialized) { navigate('/login', { replace: true }); return data; } return data; } catch (error) { if (defaultResponseErrorHandler(error)) return {} as never; throw error; } }, }); const form = formHook.useAppForm({ defaultValues: { username: '', password: '', setup_secret: '' }, validators: { onBlur: initFormSchema, onSubmit: initFormSchema }, onSubmit: async ({ value }) => { toast.dismiss(); return await initAdmin({ body: { username: value.username, password: value.password, setup_secret: value.setup_secret } }); }, }); return ( <> Initialize YANPM Create the initial admin user
{ e.preventDefault(); form.handleSubmit(); }} > ( <> field.handleChange(e.target.value)} /> )} /> ( <> field.handleChange(e.target.value)} showPasswordToggle /> )} /> ( <> field.handleChange(e.target.value)} infoIconProps={{ children: ( This secret is provided when the API server is first started. Refer to your server logs to find it. ), }} /> )} />
); }