Refactor appName generation in dashboard components

- Updated the appName generation logic in `AddApplication`, `AddCompose`, and `AddDatabase` components to use the `slugify` function for improved consistency and readability.
- Enhanced the `slugify` function to return a default value of "service" if the input is empty, ensuring robustness in name generation.
- Improved project name validation in `handle-project.tsx` to enforce stricter rules on naming conventions.
This commit is contained in:
Mauricio Siu 2025-05-04 20:14:49 -06:00
parent 7e365e1947
commit 86b56e2597
5 changed files with 24 additions and 18 deletions

View File

@ -145,10 +145,8 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
{...field}
onChange={(e) => {
const val = e.target.value?.trim() || "";
form.setValue(
"appName",
`${slug}-${val.toLowerCase().replaceAll(" ", "-")}`,
);
const serviceName = slugify(val);
form.setValue("appName", `${slug}-${serviceName}`);
field.onChange(val);
}}
/>

View File

@ -152,10 +152,8 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
{...field}
onChange={(e) => {
const val = e.target.value?.trim() || "";
form.setValue(
"appName",
`${slug}-${val.toLowerCase()}`,
);
const serviceName = slugify(val);
form.setValue("appName", `${slug}-${serviceName}`);
field.onChange(val);
}}
/>

View File

@ -363,10 +363,9 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
{...field}
onChange={(e) => {
const val = e.target.value?.trim() || "";
form.setValue(
"appName",
`${slug}-${val.toLowerCase()}`,
);
const serviceName = slugify(val);
console.log(serviceName);
form.setValue("appName", `${slug}-${serviceName}`);
field.onChange(val);
}}
/>

View File

@ -33,12 +33,23 @@ import { z } from "zod";
const AddProjectSchema = z.object({
name: z
.string()
.min(1, {
message: "Name is required",
})
.regex(/^[a-zA-Z]/, {
.min(1, "Project name is required")
.refine(
(name) => {
const trimmedName = name.trim();
const validNameRegex =
/^[\p{L}\p{N}_-][\p{L}\p{N}\s_-]*[\p{L}\p{N}_-]$/u;
return validNameRegex.test(trimmedName);
},
{
message:
"Project name must start and end with a letter, number, hyphen or underscore. Spaces are allowed in between.",
},
)
.refine((name) => !/^\d/.test(name.trim()), {
message: "Project name cannot start with a number",
}),
})
.transform((name) => name.trim()),
description: z.string().optional(),
});

View File

@ -5,7 +5,7 @@ export const slugify = (text: string | undefined) => {
return "";
}
const cleanedText = text.trim().replace(/[^a-zA-Z0-9\s]/g, "");
const cleanedText = text.trim().replace(/[^a-zA-Z0-9\s]/g, "") || "service";
return slug(cleanedText, {
lower: true,