From 5f74daf0ab69cffc5bf53adfe95f770eefa9f834 Mon Sep 17 00:00:00 2001 From: Lewis Carhart Date: Sat, 5 Apr 2025 10:38:56 -0400 Subject: [PATCH 1/2] refactor: update create organization form to include dynamic slug generation - Enhanced the organization creation process by adding a random suffix to the slug for uniqueness. - Improved code formatting for better readability and consistency. - Maintained modular structure and utilized existing hooks for form handling and submission. --- .../forms/create-organization-form.tsx | 357 +++++++++--------- 1 file changed, 180 insertions(+), 177 deletions(-) diff --git a/apps/app/src/components/forms/create-organization-form.tsx b/apps/app/src/components/forms/create-organization-form.tsx index 479c4014e1..42f56014f3 100644 --- a/apps/app/src/components/forms/create-organization-form.tsx +++ b/apps/app/src/components/forms/create-organization-form.tsx @@ -9,12 +9,12 @@ import { Button } from "@comp/ui/button"; import { Checkbox } from "@comp/ui/checkbox"; import { cn } from "@comp/ui/cn"; import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, } from "@comp/ui/form"; import { Icons } from "@comp/ui/icons"; import { Input } from "@comp/ui/input"; @@ -30,185 +30,188 @@ import type { z } from "zod"; import { LogoSpinner } from "../logo-spinner"; export function OnboardingClient() { - const [isCreatingOrganization, setIsCreatingOrganization] = useState(false); - const router = useRouter(); - const t = useI18n(); + const [isCreatingOrganization, setIsCreatingOrganization] = useState(false); + const router = useRouter(); + const t = useI18n(); - const createOrganization = useAction(createOrganizationAction, { - onSuccess: async () => { - toast.success(t("onboarding.success")); - router.push("/"); - }, - onError: () => { - toast.error(t("common.actions.error")); - }, - onExecute: () => { - setIsCreatingOrganization(true); - }, - }); + const createOrganization = useAction(createOrganizationAction, { + onSuccess: async () => { + toast.success(t("onboarding.success")); + router.push("/"); + }, + onError: () => { + toast.error(t("common.actions.error")); + }, + onExecute: () => { + setIsCreatingOrganization(true); + }, + }); - const onSubmit = async (data: z.infer) => { - await authClient.organization.create({ - name: data.name, - slug: data.name, - }); + const onSubmit = async (data: z.infer) => { + const randomSuffix = Math.floor(100000 + Math.random() * 900000).toString(); + const slug = `${data.name.toLowerCase().replace(/\s+/g, '-')}-${randomSuffix}`; - createOrganization.execute({ - ...data, - }); - }; + await authClient.organization.create({ + name: data.name, + slug, + }); - const form = useForm>({ - resolver: zodResolver(organizationSchema), - defaultValues: { - name: "", - frameworks: [], - }, - mode: "onChange", - }); + createOrganization.execute({ + ...data, + }); + }; - if (isCreatingOrganization) { - return ( -
-
-
-
- -

- {t("onboarding.trigger.title")} -

-

- {t("onboarding.trigger.creating")} -

-
-
-
-
- ); - } + const form = useForm>({ + resolver: zodResolver(organizationSchema), + defaultValues: { + name: "", + frameworks: [], + }, + mode: "onChange", + }); - return ( -
-
-
- - - -
+ if (isCreatingOrganization) { + return ( +
+
+
+
+ +

+ {t("onboarding.trigger.title")} +

+

+ {t("onboarding.trigger.creating")} +

+
+
+
+
+ ); + } -
-

- {t("onboarding.setup")} -

-

- {t("onboarding.description")} -

-
+ return ( +
+
+
+ + + +
-
- - ( - - - {t("onboarding.fields.name.label")} - - - - - - - )} - /> +
+

+ {t("onboarding.setup")} +

+

+ {t("onboarding.description")} +

+
- ( - - - {t("frameworks.overview.grid.title")} - - -
- - {t("frameworks.overview.grid.title")} - - {Object.entries(frameworks).map(([id, framework]) => { - const frameworkId = id as FrameworkId; - return ( - - ); - })} -
-
- -
- )} - /> + + + ( + + + {t("onboarding.fields.name.label")} + + + + + + + )} + /> - - - -
-
- ); + ( + + + {t("frameworks.overview.grid.title")} + + +
+ + {t("frameworks.overview.grid.title")} + + {Object.entries(frameworks).map(([id, framework]) => { + const frameworkId = id as FrameworkId; + return ( + + ); + })} +
+
+ +
+ )} + /> + + + + +
+
+ ); } From 008f9b775538675b4eb675fc49e3945a966f5439 Mon Sep 17 00:00:00 2001 From: Lewis Carhart Date: Sat, 5 Apr 2025 10:43:18 -0400 Subject: [PATCH 2/2] refactor: improve slug generation in create organization form - Enhanced slug generation logic to remove special characters and extra spaces, ensuring cleaner and more consistent slugs. - Maintained existing functionality while improving data sanitization for better user experience. --- apps/app/src/components/forms/create-organization-form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app/src/components/forms/create-organization-form.tsx b/apps/app/src/components/forms/create-organization-form.tsx index 42f56014f3..561a099580 100644 --- a/apps/app/src/components/forms/create-organization-form.tsx +++ b/apps/app/src/components/forms/create-organization-form.tsx @@ -49,7 +49,7 @@ export function OnboardingClient() { const onSubmit = async (data: z.infer) => { const randomSuffix = Math.floor(100000 + Math.random() * 900000).toString(); - const slug = `${data.name.toLowerCase().replace(/\s+/g, '-')}-${randomSuffix}`; + const slug = `${data.name.toLowerCase().trim().replace(/[^\w\s-]/g, '').replace(/[\s_-]+/g, '-')}-${randomSuffix}`; await authClient.organization.create({ name: data.name,