sourcebot/packages/web/src/app/onboard/components/orgCreateForm.tsx

109 lines
4.5 KiB
TypeScript
Raw Normal View History

2025-02-12 01:27:02 +00:00
"use client"
import { checkIfOrgDomainExists } from "../../../actions"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage } from "@/components/ui/form"
import { isServiceError } from "@/lib/utils"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import logoDark from "@/public/sb_logo_dark_large.png";
import logoLight from "@/public/sb_logo_light_large.png";
import Image from "next/image";
import { useState } from "react";
const onboardingFormSchema = z.object({
name: z.string()
.min(2, { message: "Organization name must be at least 3 characters long." })
.max(30, { message: "Organization name must be at most 30 characters long." }),
domain: z.string()
.min(2, { message: "Organization domain must be at least 3 characters long." })
2025-02-12 02:40:42 +00:00
.max(20, { message: "Organization domain must be at most 20 characters long." })
.regex(/^[a-zA-Z-]+$/, { message: "Organization domain must contain only letters and hyphens." })
.regex(/^[^-].*[^-]$/, { message: "Organization domain must not start or end with a hyphen." }),
2025-02-12 01:27:02 +00:00
})
export type OnboardingFormValues = z.infer<typeof onboardingFormSchema>
const defaultValues: Partial<OnboardingFormValues> = {
name: "",
domain: "",
}
interface OrgCreateFormProps {
setOrgCreateData: (data: OnboardingFormValues) => void;
}
export function OrgCreateForm({ setOrgCreateData }: OrgCreateFormProps) {
const form = useForm<OnboardingFormValues>({ resolver: zodResolver(onboardingFormSchema), defaultValues })
const [errorMessage, setErrorMessage] = useState<string | null>(null);
async function submitOrgInfoForm(data: OnboardingFormValues) {
const res = await checkIfOrgDomainExists(data.domain);
if (res) {
setErrorMessage("Organization domain already exists. Please try a different one.");
return;
} else {
setOrgCreateData(data);
}
}
return (
<div className="space-y-6">
<div className="flex justify-center">
<Image
src={logoDark}
className="h-16 w-auto hidden dark:block"
alt={"Sourcebot logo"}
priority={true}
/>
<Image
src={logoLight}
className="h-16 w-auto block dark:hidden"
alt={"Sourcebot logo"}
priority={true}
/>
</div>
<h1 className="text-2xl font-bold">Let's create your organization</h1>
<Form {...form}>
<form onSubmit={form.handleSubmit(submitOrgInfoForm)} className="space-y-8">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Organization Name</FormLabel>
<FormControl>
<Input placeholder="Aperture Laboratories Inc." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="domain"
render={({ field }) => (
<FormItem>
<FormLabel>Organization Domain</FormLabel>
<FormControl>
<div className="flex items-center">
<Input placeholder="aperature" {...field} className="w-1/2" />
<span className="ml-2">.sourcebot.dev</span>
</div>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{errorMessage && <p className="text-red-500">{errorMessage}</p>}
<div className="flex justify-center">
<Button type="submit">Create</Button>
</div>
</form>
</Form>
</div>
)
}