update all deps

This commit is contained in:
2026-03-10 19:17:15 +01:00
parent 4b1084d826
commit 7a8736d9c5
17 changed files with 173 additions and 201 deletions

View File

@@ -9,41 +9,38 @@ export default function TopNav() {
<div className="fixed lg:w-full right-0 z-50 lg:bg-background"> <div className="fixed lg:w-full right-0 z-50 lg:bg-background">
<nav className="flex flex-col-reverse lg:flex-row flex-wrap w-20 lg:w-full outline-1 lg:h-10 h-full"> <nav className="flex flex-col-reverse lg:flex-row flex-wrap w-20 lg:w-full outline-1 lg:h-10 h-full">
<div className="flex flex-wrap lg:h-full w-20 lg:w-fit lg:flex-row"> <div className="flex flex-wrap lg:h-full w-20 lg:w-fit lg:flex-row">
<Button className="flex h-fit lg:h-full w-full lg:w-20" asChild variant="outline"> <Button className="flex h-10 lg:h-full w-full lg:w-20" asChild variant="outline">
<Link href={"/blog"}> Blog </Link> <Link href={"/blog"}> Blog </Link>
</Button> </Button>
<Button asChild className="flex h-full w-full lg:w-20" variant="outline"> <Button asChild className="flex h-10 lg:h-full w-full lg:w-20" variant="outline">
<Link href={"/cv"}> CV </Link> <Link href={"/cv"}> CV </Link>
</Button> </Button>
<Button asChild className="flex h-full w-full lg:w-20" variant="outline"> <Button asChild className="flex h-10 lg:h-full w-full lg:w-20" variant="outline">
<Link href={"/projects"}> Projects </Link> <Link href={"/projects"}> Projects </Link>
</Button> </Button>
<Button asChild className="flex h-full w-full lg:w-20" variant="outline">
<Link href={"/fun"}> Fun </Link>
</Button>
</div> </div>
<div className="flex flex-col-reverse flex-wrap lg:h-full w-20 lg:w-fit lg:flex-row lg:ml-auto"> <div className="flex flex-col-reverse flex-wrap lg:h-full w-20 lg:w-fit lg:flex-row lg:ml-auto">
<AdminWrap> <AdminWrap>
<Button className="flex h-full w-full lg:w-20" variant="outline"> <Button className="flex h-10 lg:h-full w-full lg:w-20" variant="outline">
<Link className="" href={"/admin"}> Admin </Link> <Link className="" href={"/admin"}> Admin </Link>
</Button> </Button>
</AdminWrap> </AdminWrap>
<Show when="signed-in"> <Show when="signed-in">
<Button asChild className="flex h-full w-full lg:w-20" variant={"outline"}> <Button asChild className="flex h-10 lg:h-full w-full lg:w-20" variant={"outline"}>
<SignOutButton /> <SignOutButton />
</Button> </Button>
</Show> </Show>
<Show when="signed-out"> <Show when="signed-out">
<Button asChild className="flex h-full cursor-pointer lg:w-20" variant={"outline"}> <Button asChild className="flex h-10 lg:h-full cursor-pointer lg:w-20" variant={"outline"}>
<SignInButton mode="modal" /> <SignInButton mode="modal" />
</Button> </Button>
<Button asChild className="flex h-full cursor-pointer lg:w-20" variant={"outline"}> <Button asChild className="flex h-10 lg:h-full cursor-pointer lg:w-20" variant={"outline"}>
<SignUpButton mode="modal" /> <SignUpButton mode="modal" />
</Button> </Button>
</Show> </Show>
<ThemeSwitch /> <ThemeSwitch />
<Show when="signed-in"> <Show when="signed-in">
<Button asChild className="flex h-full cursor-pointer lg:w-20 content-center" variant={"outline"}> <Button asChild className="flex h-10 lg:h-full cursor-pointer lg:w-20 content-center" variant={"outline"}>
<div> <div>
<UserButton /> <UserButton />
</div> </div>

View File

@@ -7,7 +7,7 @@ import CreateUpdateCvCategoryForm from "../_components/CreateUpdateForm";
export default function Page() { export default function Page() {
const {id} = useParams<{id: string}>(); const {id} = useParams<{id: string}>();
const {data} = trpc.category.select.useQuery({id: id}) const {data} = trpc.category.getById.useQuery(id)
if (data !== undefined && data.length > 0) { if (data !== undefined && data.length > 0) {
return ( return (
<CreateUpdateCvCategoryForm entity={data[0]}/> <CreateUpdateCvCategoryForm entity={data[0]}/>

View File

@@ -6,7 +6,7 @@ import { trpc } from "~/app/_trpc/Client";
import type { IterableElement } from 'type-fest' import type { IterableElement } from 'type-fest'
import { entitySchemas, makeOnSuccess } from "~/lib/utils"; import { entitySchemas, makeOnSuccess } from "~/lib/utils";
import type { RouterOutputs } from "~/server/routers/_app"; import type { RouterOutputs } from "~/server/routers/_app";
import { CollapsibleForm, FormScaffold } from '~/app/_components/Form/Components'; import { FormScaffold } from '~/app/_components/Form/Components';
import { useState } from 'react'; import { useState } from 'react';
import { SelectFormField, TextInputFormField } from '~/app/_components/Form/Fields'; import { SelectFormField, TextInputFormField } from '~/app/_components/Form/Fields';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';

View File

@@ -6,24 +6,24 @@ import type { inferProcedureOutput } from "@trpc/server"
import type { RouterOutputs } from "~/server/routers/_app" import type { RouterOutputs } from "~/server/routers/_app"
import { cn } from "~/lib/utils" import { cn } from "~/lib/utils"
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"
import type { ArrayElement } from "type-fest"
type CvCategoryProps = { type CvCategoryProps = {
initialData: RouterOutputs['cv']['category']['get'], initialData: ArrayElement<RouterOutputs['categoryv2']['listByLayoutPosition']>,
layout: "row"|"col", layout: "row"|"col",
children?: React.ReactElement<Parameters<typeof CvEntry>> children?: React.ReactElement<Parameters<typeof CvEntry>>
} }
export default function CvCategory(props:CvCategoryProps) { export default function CvCategory(props:CvCategoryProps) {
const query = trpc.category.select.useQuery({id: props.initialData? props.initialData.id : ""}); const category = trpc.categoryv2.getById.useQuery(props.initialData? props.initialData.id : "");
if (query.data !== undefined) {
return ( return (
<Card className={cn(props.layout == "row" ? "w-full" : "","gsapan")}> <Card className={cn(props.layout == "row" ? "w-full" : "","gsapan")}>
<CardHeader> <CardHeader>
<CardTitle> <CardTitle>
{query.data[0].name} {category.data?.name}
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
{(query.data?.at(0)?.cvEntry.length ? query.data?.cvEntry.length : 0 ) > 0 ? {(category.data?.cvEntry.length ? category.data?.cvEntry.length : 0 ) > 0 ?
<CardContent className={cn(props.layout == "row" ? "flex flex-row flex-wrap justify-center lg:justify-between" : "flex flex-col","gap-[1rem]","overflow-scroll")}> <CardContent className={cn(props.layout == "row" ? "flex flex-row flex-wrap justify-center lg:justify-between" : "flex flex-col","gap-4","overflow-scroll")}>
{query.data?.cvEntry.map((entry) => ( {category.data?.cvEntry.map((entry) => (
<CvEntry className={props.layout == "row" ? "w-full lg:w-fit" : undefined} key={entry.id} initialData={entry}/> <CvEntry className={props.layout == "row" ? "w-full lg:w-fit" : undefined} key={entry.id} initialData={entry}/>
))} ))}
</CardContent> </CardContent>
@@ -32,15 +32,4 @@ export default function CvCategory(props:CvCategoryProps) {
} }
</Card> </Card>
) )
} else {
return (
<Card className="gsapan">
<CardHeader>
<CardTitle>
Loading ...
</CardTitle>
</CardHeader>
</Card>
);
}
} }

View File

@@ -1,25 +1,25 @@
import { trpc } from "~/app/_trpc/Client" import { trpc } from "~/app/_trpc/Client"
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "~/components/ui/card" import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "~/components/ui/card"
import { Skeleton } from "~/components/ui/skeleton" import { Skeleton } from "~/components/ui/skeleton"
import { cn, type Element } from "~/lib/utils" import { cn, type Defined } from "~/lib/utils"
import type { CategoryRouterOutputs } from "~/server/routers/cv/category"
import type { EntryRouterOutputs } from "~/server/routers/cv/entry"
import Markdown from 'react-markdown' import Markdown from 'react-markdown'
import { format } from 'date-fns' import { format } from 'date-fns'
import rehypeHighlight from 'rehype-highlight' import rehypeHighlight from 'rehype-highlight'
import rehypeRaw from 'rehype-raw' import rehypeRaw from 'rehype-raw'
import type { RouterOutputs } from "~/server/routers/_app"
import type { ArrayElement } from "type-fest"
export default function CvEntry(params: { export default function CvEntry(params: {
initialData: EntryRouterOutputs['get'] | Element<Element<CategoryRouterOutputs['list']>['cvEntry']> initialData: ArrayElement<Defined<RouterOutputs['categoryv2']['getById']>['cvEntry']>,
className?: string className?: string
}) { }) {
const query = trpc.cv.entry.get.useQuery({ id: params.initialData?.id ? params.initialData.id : "" }) const query = trpc.entryv2.getById.useQuery(params.initialData.id);
const { data } = query const { data, isError, error } = query
return ( return (
<> <>
{ {
data ? data ?
<> <>
<Card className={params.className ? cn("w-fit",params.className) : "w-fit"}> <Card className={params.className ? cn("w-fit", params.className) : "w-fit"}>
{ {
data.title ? data.title ?
<CardHeader> <CardHeader>
@@ -31,17 +31,17 @@ export default function CvEntry(params: {
data.description ? data.description ?
<CardContent className="text-sm lg:text-base"> <CardContent className="text-sm lg:text-base">
<div> <div>
<Markdown rehypePlugins={[rehypeHighlight,rehypeRaw]}>{data.description}</Markdown> <Markdown rehypePlugins={[rehypeHighlight, rehypeRaw]}>{data.description}</Markdown>
</div> </div>
</CardContent> : </CardContent> :
<></> <></>
} }
{ {
!data.hideDates ? !data.hideDates ?
<CardFooter className="text-sm"> <CardFooter className="text-sm">
{`von ${format((new Date()).setTime(Date.parse(data.fromTime)), 'M. yyyy')} bis zum ${format((new Date()).setTime(Date.parse(data.toTime)), 'M. yyyy')}`} {`von ${format((new Date()).setTime(Date.parse(data.fromTime)), 'M. yyyy')} bis zum ${format((new Date()).setTime(Date.parse(data.toTime)), 'M. yyyy')}`}
</CardFooter> : </CardFooter> :
<></> <></>
} }
</Card> </Card>
</> : </> :
@@ -55,13 +55,12 @@ export default function CvEntry(params: {
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div> <div>
<Skeleton className="h-4 w-[250px]" /> <Skeleton className="h-4 w-60" />
<Skeleton className="h-4 w-[200px]" /> <Skeleton className="h-4 w-50" />
<Skeleton className="h-4 w-[200px]" /> <Skeleton className="h-4 w-50" />
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
</> </>
} }
</> </>

View File

@@ -2,25 +2,15 @@
import { useGSAP } from "@gsap/react"; import { useGSAP } from "@gsap/react";
import { useGsapContext } from "../_providers/GsapProvicer"; import { useGsapContext } from "../_providers/GsapProvicer";
import { trpc } from "../_trpc/Client"; import { trpc } from "../_trpc/Client";
import { useEffect, useRef, useState } from "react"; import { useRef } from "react";
import { SidebarContent, SidebarProvider, Sidebar } from "~/components/ui/sidebar"; import { SidebarContent, SidebarProvider, Sidebar } from "~/components/ui/sidebar";
import SidebarTriggerDisappearsOnMobile from "./_components/SidebarTriggerDisappearsOnMobile"; import SidebarTriggerDisappearsOnMobile from "./_components/SidebarTriggerDisappearsOnMobile";
import CvCategory from "./_components/CvCategory"; import CvCategory from "./_components/CvCategory";
import type { CategoryRouterOutputs } from "~/server/routers/cv/category";
export default function CvPage() { export default function CvPage() {
const [sidebarCategories,setSidebarCategories] = useState<CategoryRouterOutputs['list']>([]); const sidebarCategories = trpc.categoryv2.listByLayoutPosition.useQuery("sidebar");
const [headerCategories,setHeaderCategories] = useState<CategoryRouterOutputs['list']>([]); const col1Categories = trpc.categoryv2.listByLayoutPosition.useQuery("col1");
const [col1Categories,setCol1Categories] = useState<CategoryRouterOutputs['list']>([]); const headerCategories = trpc.categoryv2.listByLayoutPosition.useQuery("header");
const [col2Categories,setCol2Categories] = useState<CategoryRouterOutputs['list']>([]); const col2Categories = trpc.categoryv2.listByLayoutPosition.useQuery("col2");
const categories = trpc.cv.category.list.useQuery();
useEffect(() => {
if (categories.data !== undefined) {
setSidebarCategories(categories.data.filter((cat) => cat.layoutPosition == "sidebar"))
setHeaderCategories(categories.data.filter((cat) => cat.layoutPosition == "header"))
setCol1Categories(categories.data.filter((cat) => cat.layoutPosition == "col1"))
setCol2Categories(categories.data.filter((cat) => cat.layoutPosition == "col2"))
}
},[categories.data])
const gsap = useGsapContext() const gsap = useGsapContext()
const container = useRef<HTMLDivElement>(null) const container = useRef<HTMLDivElement>(null)
enum Direction { enum Direction {
@@ -53,66 +43,55 @@ export default function CvPage() {
dir = dir + 1 dir = dir + 1
} }
}) })
}, { scope: container, dependencies: [col1Categories,col2Categories,headerCategories,sidebarCategories], revertOnUpdate: true }) }, { scope: container, dependencies: [headerCategories.data, sidebarCategories.data], revertOnUpdate: true })
if (categories.data !== undefined) { return (
return ( <>
<> <SidebarProvider ref={container}>
<SidebarProvider ref={container}> {(sidebarCategories.data?.length ? sidebarCategories.data?.length : 0) > 0 ?
{categories.data.filter((cat) => cat.layoutPosition == 'sidebar').length > 0 ? <>
<> <SidebarTriggerDisappearsOnMobile />
<SidebarTriggerDisappearsOnMobile /> <Sidebar className="gsapan ">
<Sidebar className="gsapan "> <SidebarContent className="p-2 lg:pt-[3.2rem]">
<SidebarContent className="p-2 lg:pt-[3.2rem]"> {sidebarCategories.data?.map((cat) => {
{sidebarCategories.map((cat) => { if (cat !== undefined) {
return ( return (
<CvCategory layout="col" initialData={cat} key={cat.id} /> <CvCategory layout="col" initialData={cat} key={cat.id} />
) )
})} }
</SidebarContent> })}
</Sidebar> </SidebarContent>
</> : </Sidebar>
<></> </> :
} <></>
<div className="h-full w-full flex flex-wrap flex-row p-[1rem] pt-[2rem] "> }
<div id="mainwrap" className="flex w-full flex-col gap-[1rem] lg:px-[15vw]"> <div className="h-full w-full flex flex-wrap flex-row p-4 pt-8 ">
<div id="header" className="flex w-full h-fit flex-row gap-[1rem] flex-wrap"> <div id="mainwrap" className="flex w-full flex-col gap-4 lg:px-[15vw]">
{headerCategories.map((cat) => { <div id="header" className="flex w-full h-fit flex-row gap-4 flex-wrap">
{headerCategories.data?.map((cat) => {
return (
<CvCategory layout="row" initialData={cat} key={cat.id} />
)
})}
</div>
<div id="colwrapper" className="flex flex-col lg:flex-row w-full h-3/4 gap-4">
<div id="col1" className={`flex flex-col w-full ${col1Categories.data?.length ? col1Categories.data?.length : 0 > 0 ? "lg:w-1/2" : ""} h-full gap-4`}>
{col1Categories.data?.map((cat) => {
return ( return (
<CvCategory layout="row" initialData={cat} key={cat.id} /> <CvCategory layout="col" initialData={cat} key={cat.id} />
) )
})} })}
</div> </div>
<div id="colwrapper" className="flex flex-col lg:flex-row w-full h-3/4 gap-[1rem]"> <div id="col2" className={`flex flex-col w-full ${col2Categories.data?.length ? col2Categories.data?.length : 0 > 0 ? "lg:w-1/2" : ""} h-full gap-4`}>
{col1Categories.length > 0 ? {col2Categories.data?.map((cat) => {
<div id="col1" className={`flex flex-col w-full ${col2Categories.length > 0 ? "lg:w-1/2" : ""} h-full gap-[1rem]`}> return (
{col1Categories.map((cat) => { <CvCategory layout="col" initialData={cat} key={cat.id} />
return ( )
<CvCategory layout="col" initialData={cat} key={cat.id} /> })}
)
})}
</div> :
<></>
}
{col2Categories.length > 0 ?
<div id="col2" className={`flex flex-col w-full ${col1Categories.length > 0 ? "lg:w-1/2" : ""} h-full gap-[1rem]`}>
{col2Categories.map((cat) => {
return (
<CvCategory layout="col" initialData={cat} key={cat.id} />
)
})}
</div> :
<></>
}
</div> </div>
</div> </div>
</div> </div>
</SidebarProvider> </div>
</> </SidebarProvider>
) </>
} else { )
return (
<>
</>
)
}
} }

View File

@@ -1,30 +0,0 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faChessBishop,faChessPawn,faChessKing,faChessQueen,faChessKnight,faChessRook } from "@fortawesome/free-solid-svg-icons"
type piece = "pawn" | "bishop" | "king" | "queen" | "knight" | "rook"
type color = "black" | "white"
type ChessPieceProps = {
piece: piece,
pieceColor: color,
color: color
}
export default function ChessField(props:ChessPieceProps) {
let fontSize = "2em";
let className = props.color == "black" ? "bg-slate-600" : "bg-slate-200"
className += " h-10 w-10 flex place-content-center items-center text-center p-auto"
const pieceColor = props.pieceColor == "black" ? "#3d3d3d" : "#b5b5b5"
switch(props.piece) {
case "pawn":
return <div className={className}> <FontAwesomeIcon icon={faChessPawn} style={{color:pieceColor, fontSize:fontSize}}/> </div>
case "bishop":
return <div className={className}> <FontAwesomeIcon icon={faChessBishop} style={{color:pieceColor,fontSize:fontSize}}/> </div>
case "king":
return <div className={className}> <FontAwesomeIcon icon={faChessKing} style={{color:pieceColor,fontSize:fontSize}}/> </div>
case "queen":
return <div className={className}> <FontAwesomeIcon icon={faChessQueen} style={{color:pieceColor,fontSize:fontSize}}/> </div>
case "knight":
return <div className={className}> <FontAwesomeIcon icon={faChessKnight} style={{color:pieceColor,fontSize:fontSize}}/> </div>
case "rook":
return <div className={className}> <FontAwesomeIcon icon={faChessRook} style={{color:pieceColor,fontSize:fontSize}}/> </div>
}
}

View File

@@ -1,10 +0,0 @@
'use client'
export default function RootLayout({
children,
}: Readonly<{ children: React.ReactNode}>) {
return (
<>
{children}
</>
)
}

View File

@@ -1,12 +0,0 @@
'use client'
import { usePathname } from "next/navigation"
import ChessField from "./_components/ChessPiece"
export default function Page() {
const pathName = usePathname()
return (
<div>
<ChessField color="black" piece="pawn" pieceColor="white"/>
<ChessField color="white" piece="king" pieceColor="black"/>
</div>
)
}

View File

@@ -13,7 +13,7 @@ import GsapProvider from "./_providers/GsapProvicer";
import { CodeHighlightStyle } from "./_components/CodeHighlightSyle"; import { CodeHighlightStyle } from "./_components/CodeHighlightSyle";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
const inter = Inter({subsets:['latin'],variable:'--font-sans'}); const inter = Inter({ subsets: ['latin'], variable: '--font-sans' });
config.autoAddCss = false; config.autoAddCss = false;
@@ -37,22 +37,22 @@ export default async function RootLayout({
return ( return (
<ClerkProvider> <ClerkProvider>
<TrpcProvider> <TrpcProvider>
<ThemeProvider> <GsapProvider>
<GsapProvider> <html lang="en" className={cn(geist.variable, "font-sans", inter.variable)} suppressHydrationWarning>
<html lang="en" className={cn(geist.variable, "font-sans", inter.variable)} suppressHydrationWarning> <head>
<head> <CodeHighlightStyle />
<CodeHighlightStyle/> </head>
</head> <body className="flex flex-col bg-background text-foreground">
<body className="flex flex-col bg-background text-foreground"> <ThemeProvider>
<TopNav /> <TopNav />
<main className="absolute lg:top-10 h-[100vh] w-[100vw]"> <main className="absolute lg:top-10 h-screen w-screen">
{children} {children}
</main> </main>
{modal} {modal}
</body> </ThemeProvider>
</html> </body>
</GsapProvider> </html>
</ThemeProvider> </GsapProvider>
</TrpcProvider> </TrpcProvider>
</ClerkProvider> </ClerkProvider>
); );

View File

@@ -9,6 +9,8 @@ export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)) return twMerge(clsx(inputs))
} }
export type Defined<T> = T extends undefined ? never : T;
export type Schema = typeof schema; export type Schema = typeof schema;
export type SchemaKeys<S> = { export type SchemaKeys<S> = {
@@ -68,12 +70,7 @@ export function makeOnSuccess<T extends FieldValues>(uc: 'update' | 'create' | '
} }
} }
export function entitySchemas<T extends SchemaKeys<Schema>>(table: T) export function entitySchemas<T extends SchemaKeys<Schema>>(table: T) {
: {
insert: Pretty<BuildSchema<'insert', Schema[T]['_']['columns'], undefined>>
update: Pretty<BuildSchema<'update', Schema[T]['_']['columns'], undefined>>
select: Pretty<BuildSchema<'select', Schema[T]['_']['columns'], undefined>>
} {
const insertSchema = createInsertSchema<Schema[T]>(schema[table]); const insertSchema = createInsertSchema<Schema[T]>(schema[table]);
const updateSchema = createUpdateSchema<Schema[T]>(schema[table]); const updateSchema = createUpdateSchema<Schema[T]>(schema[table]);
const selectSchema = createSelectSchema<Schema[T]>(schema[table]); const selectSchema = createSelectSchema<Schema[T]>(schema[table]);

View File

@@ -1,20 +1,24 @@
import type { inferRouterOutputs } from "@trpc/server"; import type { inferRouterOutputs } from "@trpc/server";
import { router } from "../trpc"; import { router } from "../trpc";
import type { inferReactQueryProcedureOptions } from "@trpc/react-query"; import type { inferReactQueryProcedureOptions } from "@trpc/react-query";
import { projectRouter } from "./project";
import { techStackRouter } from "./techStack";
import { cvCategoryRouter } from "./cvCategory";
import { cvEntryRouter } from "./cvEntry";
import { trpcCrudRouterFromDrizzleEntity } from "../lib"; import { trpcCrudRouterFromDrizzleEntity } from "../lib";
import type { inferRouterMeta } from "@trpc/server/unstable-core-do-not-import"; import { cvCategory } from "../dbschema/schema";
const { router : project } = trpcCrudRouterFromDrizzleEntity('project')
const { router : techStack } = trpcCrudRouterFromDrizzleEntity('techStack')
const { router : category } = trpcCrudRouterFromDrizzleEntity('cvCategory')
const { router : entry } = trpcCrudRouterFromDrizzleEntity('cvEntry')
export const trpcRouter = router({ export const trpcRouter = router({
project: project, project: trpcCrudRouterFromDrizzleEntity('project').router,
techStack: techStack, projectv2: projectRouter,
category: category, techStack: trpcCrudRouterFromDrizzleEntity('techStack').router,
entry: entry techStackv2: techStackRouter,
}) category: trpcCrudRouterFromDrizzleEntity('cvCategory').router,
categoryv2: cvCategoryRouter,
entry: trpcCrudRouterFromDrizzleEntity('cvEntry').router,
entryv2: cvEntryRouter,
});
export type TrpcRouter = typeof trpcRouter export type TrpcRouter = typeof trpcRouter;
export type RouterOutputs = inferRouterOutputs<TrpcRouter> export type RouterOutputs = inferRouterOutputs<TrpcRouter>;
export type ReactQueryOptions = inferReactQueryProcedureOptions<TrpcRouter> export type ReactQueryOptions = inferReactQueryProcedureOptions<TrpcRouter>;

View File

@@ -0,0 +1,34 @@
import { publicProcedure, router } from "~/server/trpc";
import { db } from "~/server/db";
import { cvCategory } from "~/server/dbschema/schema";
import { eq } from "drizzle-orm";
import { z } from 'zod';
import { createInsertSchema, createUpdateSchema } from "drizzle-zod";
import { TRPCError } from "@trpc/server";
export const cvCategoryRouter = router({
listByLayoutPosition: publicProcedure.input(z.enum(cvCategory.layoutPosition.enumValues)).query(async ({input}) => {
console.log(input);
const res = await db.select().from(cvCategory).where(eq(cvCategory.layoutPosition,input));
console.log(res);
return res;
}),
getById: publicProcedure.input(z.string()).query(async ({input}) => {
const res = await db.query.cvCategory.findFirst({
with: {
cvEntry: true
},
where(fields, operators) {
return operators.eq(fields.id, input)
},
})
return res;
}),
insert: publicProcedure.input(createInsertSchema(cvCategory)).mutation(async ({input}) => {
let res = await db.insert(cvCategory).values(input).returning().execute();
return res.at(0)
}),
updateById: publicProcedure.input(z.object({id: z.string(),data: createUpdateSchema(cvCategory)})).mutation(async ({input}) => {
let res = await db.update(cvCategory).set(input.data).where(eq(cvCategory.id,input.id)).execute();
})
});

View File

@@ -0,0 +1,16 @@
import { publicProcedure, router } from "~/server/trpc";
import { db } from "~/server/db";
import { z } from 'zod';
export const cvEntryRouter = router({
getById: publicProcedure.input(z.string()).query(async ({input}) => {
const res = await db.query.cvEntry.findFirst({
with: {
category: true
},
where(fields, operators) {
return operators.eq(fields.id, input)
},
})
return res;
}),
});

View File

@@ -0,0 +1,4 @@
import { router } from "~/server/trpc";
export const projectRouter = router({
});

View File

@@ -0,0 +1,5 @@
import { router } from "~/server/trpc";
export const techStackRouter = router({
});