Merge branch 'main' of https://gitea.rannes.dev/rannes.dev/wine-shop
All checks were successful
Vercel Production Deployment / Deploy-Production (push) Successful in 1m4s

This commit is contained in:
ChrQR 2024-06-02 11:43:13 +02:00
commit ec47559cd2
6 changed files with 86 additions and 48 deletions

View File

@ -2,6 +2,7 @@ import { db } from "~/server/db";
export default async function AllRegions() { export default async function AllRegions() {
const allRegions = await db.query.regions.findMany(); const allRegions = await db.query.regions.findMany();
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>
@ -9,7 +10,14 @@ export default async function AllRegions() {
<> <>
<ul> <ul>
{allRegions.map((region) => ( {allRegions.map((region) => (
<li key={region.id}>{region.name}</li> <li key={region.id}>
{region.name} -{" "}
{
allCountries.find(
(country) => country.id === region.countryId,
)?.name
}
</li>
))} ))}
</ul> </ul>
</> </>

View File

@ -2,22 +2,16 @@
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
import { addCountry } from "~/server/actions/addCountry"; import { addCountry } from "~/server/actions/addCountry";
import SubmitButton from "../SubmitButton"; import SubmitButton from "../SubmitButton";
import { useRef } from "react"; import { useFormState } from "react-dom";
const initialState = {
name: "" as string,
};
export default function CreateCountryForm() { export default function CreateCountryForm() {
const ref = useRef<HTMLFormElement>(null); const [state, formAction] = useFormState(addCountry, null);
const handleSubmit = async (formData: FormData) => {
ref.current?.reset();
await addCountry(formData);
};
return ( return (
<form ref={ref} action={handleSubmit}> <form action={formAction}>
<Input name="name" required /> <Input name="name" />
<SubmitButton text={"Country"} /> <SubmitButton text={"Country"} />
{state?.message}
</form> </form>
); );
} }

View File

@ -1,7 +1,7 @@
"use client"; "use client";
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
import SubmitButton from "../SubmitButton"; import SubmitButton from "../SubmitButton";
import { useRef } from "react"; import { useActionState } from "react";
import { addRegion } from "~/server/actions/addRegion"; import { addRegion } from "~/server/actions/addRegion";
import { import {
Select, Select,
@ -11,7 +11,6 @@ import {
SelectValue, SelectValue,
} from "~/components/ui/select"; } from "~/components/ui/select";
import { useFormState } from "react-dom"; import { useFormState } from "react-dom";
import { init } from "next/dist/compiled/webpack/webpack";
interface Country { interface Country {
id: string; id: string;
@ -21,10 +20,9 @@ interface Country {
export default function CreateRegionForm(props: { countries: Country[] }) { export default function CreateRegionForm(props: { countries: Country[] }) {
const [state, formAction] = useFormState(addRegion, null); const [state, formAction] = useFormState(addRegion, null);
const { countries } = props; const { countries } = props;
const ref = useRef<HTMLFormElement>(null);
return ( return (
<form ref={ref} action={formAction}> <form action={formAction}>
<Input name="name" required /> <Input name="name" />
<Select name="country"> <Select name="country">
<SelectTrigger className="w-[180px]"> <SelectTrigger className="w-[180px]">
<SelectValue placeholder="Country" /> <SelectValue placeholder="Country" />

View File

@ -3,15 +3,41 @@
import { revalidatePath } from "next/cache"; import { revalidatePath } from "next/cache";
import { db } from "../db"; import { db } from "../db";
import { countries } from "../db/schema"; import { countries } from "../db/schema";
import * as z from "zod";
type NewCountry = { const schema = z.object({
name: string; name: z.string().min(1, { message: "Name is required" }),
}; });
export const addCountry = async (formData: FormData) => { export async function addCountry(prevstate: any, formData: FormData) {
const newCountry: NewCountry = { const name = formData.get("name") as string;
name: (formData.get("name") as string).toLowerCase(), const newCountry = schema.safeParse({ name: name.toLowerCase() });
if (!newCountry.success) {
const errors = newCountry.error.issues.map((issue) =>
console.log(issue.message),
);
return {
message: errors,
data: newCountry.data,
}; };
} else {
const confirmCreate = await db
.insert(countries)
.values(newCountry.data)
.onConflictDoNothing()
.returning({ name: countries.name });
if (!confirmCreate[0]) {
return {
message: `${newCountry.data.name} already exists`,
data: newCountry.data,
};
} else {
revalidatePath("/"); revalidatePath("/");
await db.insert(countries).values(newCountry).returning(); return {
message: `${confirmCreate[0].name} added`,
data: newCountry.data,
}; };
}
}
}

View File

@ -11,27 +11,26 @@ const schema = z.object({
}); });
export const addRegion = async (prevstate: any, formData: FormData) => { export const addRegion = async (prevstate: any, formData: FormData) => {
const newRegion = schema.safeParse({ const regionData = {
name: (formData.get("name") as string).toLowerCase(), name: (formData.get("name") as string).toLowerCase(),
countryId: formData.get("country") as string, countryId: formData.get("country") as string,
}); };
const newRegion = schema.safeParse(regionData);
if (!newRegion.success) { if (!newRegion.success) {
return { return {
message: "failed", message: newRegion.error.issues[0]?.message,
errors: newRegion.error, data: newRegion.data,
data: null,
}; };
} }
const confirmedRegion = await db const confirmedRegion = await db
.insert(regions) .insert(regions)
.values(newRegion.data) .values(newRegion.data)
.onConflictDoNothing({ target: regions.name }) .onConflictDoNothing()
.returning({ name: regions.name }); .returning({ name: regions.name });
if (!confirmedRegion[0]?.name) { if (!confirmedRegion[0]) {
return { return {
message: "region already exists", message: `${newRegion.data.name} already exists`,
errors: newRegion.error, data: newRegion.data,
data: null,
}; };
} else { } else {
const message = `${newRegion.data.name} added`; const message = `${newRegion.data.name} added`;

View File

@ -7,6 +7,7 @@ import {
text, text,
timestamp, timestamp,
uuid, uuid,
unique,
} from "drizzle-orm/pg-core"; } from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm"; import { relations } from "drizzle-orm";
@ -81,11 +82,17 @@ export const winesRelations = relations(wines, ({ one }) => ({
}), }),
})); }));
export const subRegions = createTable("subRegion", { export const subRegions = createTable(
"subRegion",
{
id: uuid("id").primaryKey().notNull().defaultRandom(), id: uuid("id").primaryKey().notNull().defaultRandom(),
name: text("name").notNull().unique(), name: text("name").notNull().unique(),
regionId: uuid("regionId").notNull(), regionId: uuid("regionId").notNull(),
}); },
(t) => ({
uniqueSubRegion: unique().on(t.name, t.regionId),
}),
);
export const subRegionsRelations = relations(subRegions, ({ many, one }) => ({ export const subRegionsRelations = relations(subRegions, ({ many, one }) => ({
wines: many(wines), wines: many(wines),
@ -95,11 +102,17 @@ export const subRegionsRelations = relations(subRegions, ({ many, one }) => ({
}), }),
})); }));
export const regions = createTable("region", { export const regions = createTable(
"region",
{
id: uuid("id").primaryKey().notNull().defaultRandom(), id: uuid("id").primaryKey().notNull().defaultRandom(),
name: text("name").notNull().unique(), name: text("name").notNull(),
countryId: uuid("countryId").notNull(), countryId: uuid("countryId").notNull(),
}); },
(t) => ({
uniqueRegion: unique().on(t.name, t.countryId),
}),
);
export const regionsRelations = relations(regions, ({ many, one }) => ({ export const regionsRelations = relations(regions, ({ many, one }) => ({
wines: many(wines), wines: many(wines),