refactor: use slugify function

This commit is contained in:
Mauricio Siu
2024-06-08 16:41:38 -06:00
parent 72c366aa10
commit dd16baf234
3 changed files with 46 additions and 52 deletions

View File

@@ -27,6 +27,7 @@ import { useForm } from "react-hook-form";
import { toast } from "sonner"; import { toast } from "sonner";
import { z } from "zod"; import { z } from "zod";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { slugify } from "@/lib/slug";
const AddTemplateSchema = z.object({ const AddTemplateSchema = z.object({
name: z.string().min(1, { name: z.string().min(1, {
@@ -54,6 +55,7 @@ interface Props {
export const AddApplication = ({ projectId, projectName }: Props) => { export const AddApplication = ({ projectId, projectName }: Props) => {
const utils = api.useUtils(); const utils = api.useUtils();
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const slug = slugify(projectName);
const { mutateAsync, isLoading, error, isError } = const { mutateAsync, isLoading, error, isError } =
api.application.create.useMutation(); api.application.create.useMutation();
@@ -61,7 +63,7 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
const form = useForm<AddTemplate>({ const form = useForm<AddTemplate>({
defaultValues: { defaultValues: {
name: "", name: "",
appName: `${projectName}-`, appName: `${slug}-`,
description: "", description: "",
}, },
resolver: zodResolver(AddTemplateSchema), resolver: zodResolver(AddTemplateSchema),
@@ -106,7 +108,6 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>} {isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
<Form {...form}> <Form {...form}>
<form <form
id="hook-form" id="hook-form"
@@ -125,7 +126,7 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
{...field} {...field}
onChange={(e) => { onChange={(e) => {
const val = e.target.value?.trim() || ""; const val = e.target.value?.trim() || "";
form.setValue("appName", `${projectName}-${val}`); form.setValue("appName", `${slug}-${val}`);
field.onChange(val); field.onChange(val);
}} }}
/> />
@@ -165,47 +166,6 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
</FormItem> </FormItem>
)} )}
/> />
{/* <FormField
control={form.control}
name="buildType"
render={({ field }) => (
<FormItem className="space-y-3">
<FormLabel>Build Type</FormLabel>
<FormControl>
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value}
className="flex flex-col space-y-1"
>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="dockerfile" />
</FormControl>
<FormLabel className="font-normal">
Dockerfile
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="nixpacks" />
</FormControl>
<FormLabel className="font-normal">Nixpacks</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="heroku_buildpacks" />
</FormControl>
<FormLabel className="font-normal">
Heroku Buildpacks
</FormLabel>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/> */}
</form> </form>
<DialogFooter> <DialogFooter>

View File

@@ -34,12 +34,22 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { slugify } from "@/lib/slug";
const AddComposeSchema = z.object({ const AddComposeSchema = z.object({
composeType: z.enum(["docker-compose", "stack"]).optional(), composeType: z.enum(["docker-compose", "stack"]).optional(),
name: z.string().min(1, { name: z.string().min(1, {
message: "Name is required", message: "Name is required",
}), }),
appName: z
.string()
.min(1, {
message: "App name is required",
})
.regex(/^[a-z](?!.*--)([a-z0-9-]*[a-z])?$/, {
message:
"App name supports letters, numbers, '-' and can only start and end letters, and does not support continuous '-'",
}),
description: z.string().optional(), description: z.string().optional(),
}); });
@@ -47,11 +57,12 @@ type AddCompose = z.infer<typeof AddComposeSchema>;
interface Props { interface Props {
projectId: string; projectId: string;
projectName?: string;
} }
export const AddCompose = ({ projectId }: Props) => { export const AddCompose = ({ projectId, projectName }: Props) => {
const utils = api.useUtils(); const utils = api.useUtils();
const slug = slugify(projectName);
const { mutateAsync, isLoading, error, isError } = const { mutateAsync, isLoading, error, isError } =
api.compose.create.useMutation(); api.compose.create.useMutation();
@@ -60,6 +71,7 @@ export const AddCompose = ({ projectId }: Props) => {
name: "", name: "",
description: "", description: "",
composeType: "docker-compose", composeType: "docker-compose",
appName: `${slug}-`,
}, },
resolver: zodResolver(AddComposeSchema), resolver: zodResolver(AddComposeSchema),
}); });
@@ -74,6 +86,7 @@ export const AddCompose = ({ projectId }: Props) => {
description: data.description, description: data.description,
projectId, projectId,
composeType: data.composeType, composeType: data.composeType,
appName: data.appName,
}) })
.then(async () => { .then(async () => {
toast.success("Compose Created"); toast.success("Compose Created");
@@ -120,14 +133,34 @@ export const AddCompose = ({ projectId }: Props) => {
<FormItem> <FormItem>
<FormLabel>Name</FormLabel> <FormLabel>Name</FormLabel>
<FormControl> <FormControl>
<Input placeholder="Frontend" {...field} /> <Input
placeholder="Frontend"
{...field}
onChange={(e) => {
const val = e.target.value?.trim() || "";
form.setValue("appName", `${slug}-${val}`);
field.onChange(val);
}}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
)} )}
/> />
</div> </div>
<FormField
control={form.control}
name="appName"
render={({ field }) => (
<FormItem>
<FormLabel>AppName</FormLabel>
<FormControl>
<Input placeholder="my-app" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField <FormField
control={form.control} control={form.control}
name="composeType" name="composeType"

View File

@@ -27,10 +27,11 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { slugify } from "@/lib/slug";
import { api } from "@/utils/api"; import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { Database, AlertTriangle } from "lucide-react"; import { Database, AlertTriangle } from "lucide-react";
import { useMemo, useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import { toast } from "sonner"; import { toast } from "sonner";
import { z } from "zod"; import { z } from "zod";
@@ -143,7 +144,7 @@ interface Props {
export const AddDatabase = ({ projectId, projectName }: Props) => { export const AddDatabase = ({ projectId, projectName }: Props) => {
const utils = api.useUtils(); const utils = api.useUtils();
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const slug = slugify(projectName);
const postgresMutation = api.postgres.create.useMutation(); const postgresMutation = api.postgres.create.useMutation();
const mongoMutation = api.mongo.create.useMutation(); const mongoMutation = api.mongo.create.useMutation();
const redisMutation = api.redis.create.useMutation(); const redisMutation = api.redis.create.useMutation();
@@ -155,7 +156,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
type: "postgres", type: "postgres",
dockerImage: "", dockerImage: "",
name: "", name: "",
appName: `${projectName}-`, appName: `${slug}-`,
databasePassword: "", databasePassword: "",
description: "", description: "",
databaseName: "", databaseName: "",
@@ -341,7 +342,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
{...field} {...field}
onChange={(e) => { onChange={(e) => {
const val = e.target.value?.trim() || ""; const val = e.target.value?.trim() || "";
form.setValue("appName", `${projectName}-${val}`); form.setValue("appName", `${slug}-${val}`);
field.onChange(val); field.onChange(val);
}} }}
/> />