Compare commits
No commits in common. "93c0348564d83dd4b15c1f17a60437412dbc8806" and "a507fe84a4f47b82309d7fded96e4605b20620f2" have entirely different histories.
93c0348564
...
a507fe84a4
@ -4,10 +4,6 @@ import CreateCountry from "./_components/admin/CreateCountry";
|
|||||||
import AllCountries from "./_components/AllCountries";
|
import AllCountries from "./_components/AllCountries";
|
||||||
import CreateRegion from "./_components/admin/CreateRegion";
|
import CreateRegion from "./_components/admin/CreateRegion";
|
||||||
import AllRegions from "./_components/AllRegions";
|
import AllRegions from "./_components/AllRegions";
|
||||||
import CreateSubRegion from "./_components/admin/CreateSubRegion";
|
|
||||||
import AllSubRegions from "./_components/AllSubRegions";
|
|
||||||
import CreateProducer from "./_components/admin/CreateProducer";
|
|
||||||
import AllProducers from "./_components/allProducers";
|
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
@ -18,10 +14,6 @@ export default function App() {
|
|||||||
<AllCountries />
|
<AllCountries />
|
||||||
<CreateRegion />
|
<CreateRegion />
|
||||||
<AllRegions />
|
<AllRegions />
|
||||||
<CreateSubRegion />
|
|
||||||
<AllSubRegions />
|
|
||||||
<CreateProducer />
|
|
||||||
<AllProducers />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Delete } from "lucide-react";
|
import { Delete } from "lucide-react";
|
||||||
import { deleteCountry } from "~/server/actions/deleteCountry";
|
import { deleteCountry } from "~/server/actions/deleteCountry";
|
||||||
import getAllCountries from "~/server/actions/getAllCountries";
|
import { db } from "~/server/db";
|
||||||
|
|
||||||
export default async function AllCountries() {
|
export default async function AllCountries() {
|
||||||
const countries = await getAllCountries();
|
const countries = await db.query.countries.findMany();
|
||||||
return (
|
return (
|
||||||
<div className="pt-4">
|
<div className="pt-4">
|
||||||
<h1 className="text-2xl">All Countries:</h1>
|
<h1 className="text-2xl">All Countries:</h1>
|
||||||
|
@ -1,24 +1,29 @@
|
|||||||
import { Delete } from "lucide-react";
|
import { db } from "~/server/db";
|
||||||
import deleteRegion from "~/server/actions/deleteRegion";
|
|
||||||
import getAllCountries from "~/server/actions/getAllCountries";
|
|
||||||
import getAllRegions from "~/server/actions/getAllRegions";
|
|
||||||
|
|
||||||
export default async function AllRegions() {
|
export default async function AllRegions() {
|
||||||
const allRegions = await getAllRegions();
|
const allRegions = await db.query.regions.findMany();
|
||||||
const allCountries = await getAllCountries();
|
const allCountries = await db.query.countries.findMany();
|
||||||
return (
|
return (
|
||||||
<div className="pt-4">
|
<div className="pt-4">
|
||||||
<h1 className="text-2xl">All Regions:</h1>
|
<h1 className="text-2xl">All Regions:</h1>
|
||||||
{allRegions.map((region) => (
|
{allRegions[0] ? (
|
||||||
<div key={region.id} className="flex gap-1">
|
<>
|
||||||
<p>{region.name}</p>
|
<ul>
|
||||||
<form action={deleteRegion.bind(null, region.id)}>
|
{allRegions.map((region) => (
|
||||||
<button>
|
<li key={region.id}>
|
||||||
<Delete />
|
{region.name} -{" "}
|
||||||
</button>
|
{
|
||||||
</form>
|
allCountries.find(
|
||||||
</div>
|
(country) => country.id === region.countryId,
|
||||||
))}
|
)?.name
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<p>There are no regions in the db.</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
import { Delete } from "lucide-react";
|
|
||||||
import deleteSubRegion from "~/server/actions/deleteSubRegion";
|
|
||||||
import getAllSubRegions from "~/server/actions/getAllSubRegions";
|
|
||||||
|
|
||||||
export default async function AllSubRegions() {
|
|
||||||
const allSubRegions = await getAllSubRegions();
|
|
||||||
return (
|
|
||||||
<div className="pt-4">
|
|
||||||
<h1 className="text-2xl">All Sub Regions:</h1>
|
|
||||||
{allSubRegions.map((subRegion) => (
|
|
||||||
<div key={subRegion.id} className="flex gap-1">
|
|
||||||
<p>{subRegion.name}</p>
|
|
||||||
<form action={deleteSubRegion.bind(null, subRegion.id)}>
|
|
||||||
<button>
|
|
||||||
<Delete />
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -2,9 +2,9 @@ import CreateCountryForm from "./CreateCountryForm";
|
|||||||
|
|
||||||
export default function CreateCountry() {
|
export default function CreateCountry() {
|
||||||
return (
|
return (
|
||||||
<div className="container flex w-full flex-col justify-center py-4">
|
<>
|
||||||
<h1 className="pt-4 text-2xl">Fill the form to create a new country</h1>
|
<h1 className="pt-4 text-2xl">Fill the form to create a new country</h1>
|
||||||
<CreateCountryForm />
|
<CreateCountryForm />
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import getAllCountries from "~/server/actions/getAllCountries";
|
|
||||||
import CreateProducerForm from "./CreateProducerForm";
|
|
||||||
|
|
||||||
export default async function CreateProducer() {
|
|
||||||
const allCountries = await getAllCountries();
|
|
||||||
return (
|
|
||||||
<div className="container flex w-full flex-col justify-center py-4">
|
|
||||||
<h1 className="pt-4 text-2xl">Fill the form to create a new producer</h1>
|
|
||||||
<CreateProducerForm allCountries={allCountries} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import clsx from "clsx";
|
|
||||||
import { Check, CircleX } from "lucide-react";
|
|
||||||
import { useFormState } from "react-dom";
|
|
||||||
import { Input } from "~/components/ui/input";
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "~/components/ui/select";
|
|
||||||
import { Textarea } from "~/components/ui/textarea";
|
|
||||||
import { addProducer } from "~/server/actions/addProducer";
|
|
||||||
import SubmitButton from "../SubmitButton";
|
|
||||||
|
|
||||||
type Country = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function CreateProducerForm(props: { allCountries: Country[] }) {
|
|
||||||
const { allCountries } = props;
|
|
||||||
const [formState, formAction] = useFormState(addProducer, {
|
|
||||||
message: "",
|
|
||||||
errors: undefined,
|
|
||||||
fieldValues: {
|
|
||||||
name: "",
|
|
||||||
description: "",
|
|
||||||
imageUrl: "",
|
|
||||||
countryId: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
<form action={formAction}>
|
|
||||||
<Input
|
|
||||||
name="name"
|
|
||||||
id="name"
|
|
||||||
placeholder="Enter the name of the producer..."
|
|
||||||
className={clsx({ "border-red-500": formState.errors?.name })}
|
|
||||||
/>
|
|
||||||
{formState.message !== "" && !formState.errors?.name ? (
|
|
||||||
<Check className="text-green-500" />
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
{formState.errors?.name ? (
|
|
||||||
<div className="flex min-w-96 items-center gap-1 text-red-500">
|
|
||||||
<CircleX />
|
|
||||||
<span className="text-sm">{formState.errors?.name}</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
<Textarea
|
|
||||||
name="description"
|
|
||||||
id="description"
|
|
||||||
placeholder="Enter a description of the producer..."
|
|
||||||
className={clsx({ "border-red-500": formState.errors?.description })}
|
|
||||||
/>
|
|
||||||
{formState.message !== "" && !formState.errors?.description ? (
|
|
||||||
<Check className="text-green-500" />
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
{formState.errors?.description ? (
|
|
||||||
<div className="flex min-w-96 items-center gap-1 text-red-500">
|
|
||||||
<CircleX />
|
|
||||||
<span className="text-sm">{formState.errors?.description}</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
<Input
|
|
||||||
name="imageUrl"
|
|
||||||
id="imageUrl"
|
|
||||||
placeholder="Image URL"
|
|
||||||
className={clsx({ "border-red-500": formState.errors?.imageUrl })}
|
|
||||||
/>
|
|
||||||
{formState.message !== "" && !formState.errors?.imageUrl ? (
|
|
||||||
<Check className="text-green-500" />
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
{formState.errors?.imageUrl ? (
|
|
||||||
<div className="flex min-w-96 items-center gap-1 text-red-500">
|
|
||||||
<CircleX />
|
|
||||||
<span className="text-sm">{formState.errors?.imageUrl}</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
<Select name="countryId">
|
|
||||||
<SelectTrigger className={`w-[180px] `}>
|
|
||||||
<SelectValue placeholder="select country" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{allCountries.map((country) => (
|
|
||||||
<SelectItem key={country.id} value={country.id}>
|
|
||||||
{country.name}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<SubmitButton text={"producer"} />
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,13 +1,13 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
import { db } from "~/server/db";
|
||||||
import CreateRegionForm from "./CreateRegionForm";
|
import CreateRegionForm from "./CreateRegionForm";
|
||||||
import getAllCountries from "~/server/actions/getAllCountries";
|
|
||||||
|
|
||||||
export default async function CreateRegion() {
|
export default async function CreateRegion() {
|
||||||
const allCountries = await getAllCountries();
|
const allCountries = await db.query.countries.findMany();
|
||||||
return (
|
return (
|
||||||
<div className="container flex w-full flex-col justify-center py-4">
|
<>
|
||||||
<h1 className="pt-4 text-2xl">Fill the form to create a new region</h1>
|
<h1 className="pt-4 text-2xl">Fill the form to create a new region</h1>
|
||||||
<CreateRegionForm countries={allCountries} />
|
<CreateRegionForm countries={allCountries} />
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import getAllRegions from "~/server/actions/getAllRegions";
|
|
||||||
import CreateSubRegionForm from "./CreateSubRegionForm";
|
|
||||||
import getAllCountries from "~/server/actions/getAllCountries";
|
|
||||||
|
|
||||||
const allRegions = await getAllRegions();
|
|
||||||
const allCountries = await getAllCountries();
|
|
||||||
|
|
||||||
export default async function CreateSubRegion() {
|
|
||||||
return (
|
|
||||||
<div className="container flex w-full flex-col justify-center py-4">
|
|
||||||
<h1 className="pt-4 text-2xl">
|
|
||||||
Fill the form to create a new Sub Region
|
|
||||||
</h1>
|
|
||||||
<CreateSubRegionForm
|
|
||||||
allRegions={allRegions}
|
|
||||||
allCountries={allCountries}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import clsx from "clsx";
|
|
||||||
import { ChangeEvent, useEffect, useRef, useState } from "react";
|
|
||||||
import { useFormState } from "react-dom";
|
|
||||||
import { Input } from "~/components/ui/input";
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "~/components/ui/select";
|
|
||||||
import { addSubRegion } from "~/server/actions/addSubRegion";
|
|
||||||
import SubmitButton from "../SubmitButton";
|
|
||||||
import { Check, CircleX } from "lucide-react";
|
|
||||||
|
|
||||||
type Region = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
countryId: string;
|
|
||||||
};
|
|
||||||
type Country = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function CreateSubRegionForm(props: {
|
|
||||||
allRegions: Region[];
|
|
||||||
allCountries: Country[];
|
|
||||||
}) {
|
|
||||||
const { allRegions, allCountries } = props;
|
|
||||||
const [selectCountryId, setSelectCountryId] = useState<string | undefined>(
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
const [selectCountryRegions, setSelectCountryRegions] = useState<Region[]>(
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
const [formState, formActions] = useFormState(addSubRegion, {
|
|
||||||
message: "",
|
|
||||||
errors: undefined,
|
|
||||||
fieldValues: {
|
|
||||||
name: "",
|
|
||||||
regionId: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectCountryId) {
|
|
||||||
const regions = allRegions.filter(
|
|
||||||
(region) => region.countryId === selectCountryId,
|
|
||||||
);
|
|
||||||
setSelectCountryRegions(regions);
|
|
||||||
}
|
|
||||||
}, [selectCountryId]);
|
|
||||||
|
|
||||||
const formRef = useRef<HTMLFormElement>(null);
|
|
||||||
useEffect(() => {
|
|
||||||
if (formState.message === "success") {
|
|
||||||
formRef.current?.reset();
|
|
||||||
}
|
|
||||||
}, [formState.message]);
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
{/* country selector */}
|
|
||||||
<Select
|
|
||||||
name="country"
|
|
||||||
onValueChange={(value) => setSelectCountryId(value)}
|
|
||||||
>
|
|
||||||
<SelectTrigger className={`w-[180px] `}>
|
|
||||||
<SelectValue placeholder="select country" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{allCountries.map((country) => (
|
|
||||||
<SelectItem key={country.id} value={country.id}>
|
|
||||||
{country.name}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<form ref={formRef} action={formActions}>
|
|
||||||
{/* region selector */}
|
|
||||||
<div className="flex max-w-3xl items-center gap-2">
|
|
||||||
<Select name="regionId">
|
|
||||||
<SelectTrigger
|
|
||||||
className={`w-[180px] ${clsx({ "border-red-500": formState.errors?.regionId })}`}
|
|
||||||
>
|
|
||||||
<SelectValue placeholder="select region" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{selectCountryRegions.map((region) => (
|
|
||||||
<SelectItem key={region.id} value={region.id}>
|
|
||||||
{region.name}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
{formState.message === "success" && !formState.errors?.regionId ? (
|
|
||||||
<Check className="text-green-500" />
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
{formState.errors?.regionId ? (
|
|
||||||
<div className="flex min-w-40 items-center gap-1 text-red-500">
|
|
||||||
<CircleX className="text-red-500" />
|
|
||||||
<span className="text-sm">{formState.errors?.regionId}</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="flex max-w-3xl items-center gap-2">
|
|
||||||
<Input
|
|
||||||
name="name"
|
|
||||||
id="name"
|
|
||||||
placeholder="Name the sub region"
|
|
||||||
className={`${clsx({ "border-red-500": formState.errors?.name })}`}
|
|
||||||
/>
|
|
||||||
{formState.message === "success" && !formState.errors?.name ? (
|
|
||||||
<Check className="text-green-500" />
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
{formState.errors?.name ? (
|
|
||||||
<div className="flex min-w-40 items-center gap-1 text-red-500">
|
|
||||||
<CircleX className="text-red-500" />
|
|
||||||
<span className="text-sm">{formState.errors?.name}</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<SubmitButton text={"sub region"} />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import { Delete } from "lucide-react";
|
|
||||||
import deleteProducer from "~/server/actions/deleteProducer";
|
|
||||||
import getAllProducers from "~/server/actions/getAllProducers";
|
|
||||||
|
|
||||||
export default async function AllProducers() {
|
|
||||||
const allProducers = await getAllProducers();
|
|
||||||
return (
|
|
||||||
<div className="pt-4">
|
|
||||||
<h1 className="text-2xl">All Producers:</h1>
|
|
||||||
{allProducers.map((producer) => (
|
|
||||||
<div key={producer.id} className="flex gap-1">
|
|
||||||
<p>{producer.name}</p>
|
|
||||||
<form action={deleteProducer.bind(null, producer.id)}>
|
|
||||||
<button>
|
|
||||||
<Delete />
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { cn } from "~/lib/utils"
|
|
||||||
|
|
||||||
export interface TextareaProps
|
|
||||||
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
|
||||||
|
|
||||||
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
||||||
({ className, ...props }, ref) => {
|
|
||||||
return (
|
|
||||||
<textarea
|
|
||||||
className={cn(
|
|
||||||
"flex min-h-[80px] w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-slate-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-800 dark:bg-slate-950 dark:ring-offset-slate-950 dark:placeholder:text-slate-400 dark:focus-visible:ring-slate-300",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
ref={ref}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Textarea.displayName = "Textarea"
|
|
||||||
|
|
||||||
export { Textarea }
|
|
@ -1,77 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { db } from "../db";
|
|
||||||
import { producers } from "../db/schema";
|
|
||||||
import { ZodError, z } from "zod";
|
|
||||||
import { revalidatePath } from "next/cache";
|
|
||||||
|
|
||||||
export const addProducer = async (prevstate: any, formData: FormData) => {
|
|
||||||
//assign formdaata to variables.
|
|
||||||
const name = (formData.get("name") as string).toLowerCase();
|
|
||||||
const description = (formData.get("description") as string).toLowerCase();
|
|
||||||
const imageUrl = (formData.get("imageUrl") as string).toLowerCase();
|
|
||||||
const countryId = formData.get("countryId") as string;
|
|
||||||
|
|
||||||
//check if producer already exists in country
|
|
||||||
const exists = await db
|
|
||||||
.select({ name: producers.name })
|
|
||||||
.from(producers)
|
|
||||||
.where(eq(producers.name, name));
|
|
||||||
|
|
||||||
//Define the schema for the form data
|
|
||||||
const schema = z.object({
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "Name is required")
|
|
||||||
.refine(() => !exists[0], {
|
|
||||||
message: `${name} already exists in selected country`,
|
|
||||||
}),
|
|
||||||
description: z.string(),
|
|
||||||
imageUrl: z.string(),
|
|
||||||
countryId: z.string().min(1, "No country selected"),
|
|
||||||
});
|
|
||||||
//Parse the form data using the schema for validation, and check if the name already exists
|
|
||||||
try {
|
|
||||||
schema.parse({
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
imageUrl,
|
|
||||||
countryId,
|
|
||||||
});
|
|
||||||
//If the name doesn't exist, add the country to the database abd revalidate the page
|
|
||||||
await db
|
|
||||||
.insert(producers)
|
|
||||||
.values({ name, description, imageUrl, countryId });
|
|
||||||
revalidatePath("/");
|
|
||||||
//Return a success message
|
|
||||||
return {
|
|
||||||
message: "success",
|
|
||||||
errors: undefined,
|
|
||||||
fieldValues: {
|
|
||||||
name: "",
|
|
||||||
description: "",
|
|
||||||
imageUrl: "",
|
|
||||||
countryId: "",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
const zodError = error as ZodError;
|
|
||||||
const errorMap = zodError.flatten().fieldErrors;
|
|
||||||
//Return an error object with the field values and errors.
|
|
||||||
return {
|
|
||||||
message: "error",
|
|
||||||
errors: {
|
|
||||||
name: errorMap["name"]?.[0] ?? "",
|
|
||||||
description: errorMap["description"]?.[0] ?? "",
|
|
||||||
imageUrl: errorMap["imageUrl"]?.[0] ?? "",
|
|
||||||
countryId: errorMap["countryId"]?.[0] ?? "",
|
|
||||||
},
|
|
||||||
fieldValues: {
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
imageUrl,
|
|
||||||
countryId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,64 +0,0 @@
|
|||||||
"use server";
|
|
||||||
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { db } from "../db";
|
|
||||||
import { subRegions } from "../db/schema";
|
|
||||||
import { ZodError, z } from "zod";
|
|
||||||
import { revalidatePath } from "next/cache";
|
|
||||||
|
|
||||||
export const addSubRegion = async (prevstate: any, formData: FormData) => {
|
|
||||||
//assign formdaata to variables.
|
|
||||||
const name = (formData.get("name") as string).toLowerCase();
|
|
||||||
const regionId = formData.get("regionId") as string;
|
|
||||||
|
|
||||||
//check if region already exists in country
|
|
||||||
const exists = await db
|
|
||||||
.select({ name: subRegions.name })
|
|
||||||
.from(subRegions)
|
|
||||||
.where(eq(subRegions.regionId, regionId) && eq(subRegions.name, name));
|
|
||||||
|
|
||||||
//Define the schema for the form data
|
|
||||||
const schema = z.object({
|
|
||||||
regionId: z.string().min(1, "No region selected"),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "Name is required")
|
|
||||||
.refine(() => !exists[0], {
|
|
||||||
message: `${name} already exists in selected region`,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
//Parse the form data using the schema for validation, and check if the name already exists
|
|
||||||
try {
|
|
||||||
schema.parse({
|
|
||||||
regionId,
|
|
||||||
name,
|
|
||||||
});
|
|
||||||
//If the name doesn't exist, add the country to the database abd revalidate the page
|
|
||||||
await db.insert(subRegions).values({ regionId, name });
|
|
||||||
revalidatePath("/");
|
|
||||||
//Return a success message
|
|
||||||
return {
|
|
||||||
message: "success",
|
|
||||||
errors: undefined,
|
|
||||||
fieldValues: {
|
|
||||||
name: "",
|
|
||||||
regionId: "",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
const zodError = error as ZodError;
|
|
||||||
const errorMap = zodError.flatten().fieldErrors;
|
|
||||||
//Return an error object with the field values and errors.
|
|
||||||
return {
|
|
||||||
message: "error",
|
|
||||||
errors: {
|
|
||||||
name: errorMap["name"]?.[0] ?? "",
|
|
||||||
regionId: errorMap["regionId"]?.[0] ?? "",
|
|
||||||
},
|
|
||||||
fieldValues: {
|
|
||||||
name,
|
|
||||||
regionId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,10 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { db } from "../db";
|
|
||||||
import { producers } from "../db/schema";
|
|
||||||
import { revalidatePath } from "next/cache";
|
|
||||||
|
|
||||||
export default async function deleteProducer(id: string) {
|
|
||||||
await db.delete(producers).where(eq(producers.id, id));
|
|
||||||
revalidatePath("/");
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { db } from "../db";
|
|
||||||
import { regions } from "../db/schema";
|
|
||||||
import { revalidatePath } from "next/cache";
|
|
||||||
|
|
||||||
export default async function deleteRegion(id: string) {
|
|
||||||
await db.delete(regions).where(eq(regions.id, id));
|
|
||||||
revalidatePath("/");
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { db } from "../db";
|
|
||||||
import { subRegions } from "../db/schema";
|
|
||||||
import { revalidatePath } from "next/cache";
|
|
||||||
|
|
||||||
export default async function deleteSubRegion(id: string) {
|
|
||||||
await db.delete(subRegions).where(eq(subRegions.id, id));
|
|
||||||
revalidatePath("/");
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { db } from "../db";
|
|
||||||
|
|
||||||
export default async function getAllCountries() {
|
|
||||||
const allCountries = await db.query.countries.findMany();
|
|
||||||
return allCountries;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import { db } from "../db";
|
|
||||||
|
|
||||||
export default async function getAllProducers() {
|
|
||||||
const allProducers = await db.query.producers.findMany();
|
|
||||||
return allProducers;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { db } from "../db";
|
|
||||||
|
|
||||||
export default async function getAllRegions() {
|
|
||||||
const allRegions = await db.query.regions.findMany();
|
|
||||||
return allRegions;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import { db } from "../db";
|
|
||||||
|
|
||||||
export default async function getAllSubRegions() {
|
|
||||||
const allSubRegions = await db.query.subRegions.findMany();
|
|
||||||
return allSubRegions;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user