update all deps
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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]}/>
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
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 (
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
@@ -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>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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}>
|
||||||
{categories.data.filter((cat) => cat.layoutPosition == 'sidebar').length > 0 ?
|
{(sidebarCategories.data?.length ? sidebarCategories.data?.length : 0) > 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.map((cat) => {
|
{sidebarCategories.data?.map((cat) => {
|
||||||
|
if (cat !== undefined) {
|
||||||
return (
|
return (
|
||||||
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
||||||
)
|
)
|
||||||
|
}
|
||||||
})}
|
})}
|
||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
</> :
|
</> :
|
||||||
<></>
|
<></>
|
||||||
}
|
}
|
||||||
<div className="h-full w-full flex flex-wrap flex-row p-[1rem] pt-[2rem] ">
|
<div className="h-full w-full flex flex-wrap flex-row p-4 pt-8 ">
|
||||||
<div id="mainwrap" className="flex w-full flex-col gap-[1rem] lg:px-[15vw]">
|
<div id="mainwrap" className="flex w-full flex-col gap-4 lg:px-[15vw]">
|
||||||
<div id="header" className="flex w-full h-fit flex-row gap-[1rem] flex-wrap">
|
<div id="header" className="flex w-full h-fit flex-row gap-4 flex-wrap">
|
||||||
{headerCategories.map((cat) => {
|
{headerCategories.data?.map((cat) => {
|
||||||
return (
|
return (
|
||||||
<CvCategory layout="row" initialData={cat} key={cat.id} />
|
<CvCategory layout="row" 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="colwrapper" className="flex flex-col lg:flex-row w-full h-3/4 gap-4">
|
||||||
{col1Categories.length > 0 ?
|
<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`}>
|
||||||
<div id="col1" className={`flex flex-col w-full ${col2Categories.length > 0 ? "lg:w-1/2" : ""} h-full gap-[1rem]`}>
|
{col1Categories.data?.map((cat) => {
|
||||||
{col1Categories.map((cat) => {
|
|
||||||
return (
|
return (
|
||||||
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div> :
|
</div>
|
||||||
<></>
|
<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`}>
|
||||||
}
|
{col2Categories.data?.map((cat) => {
|
||||||
{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 (
|
return (
|
||||||
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div> :
|
</div>
|
||||||
<></>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
'use client'
|
|
||||||
export default function RootLayout({
|
|
||||||
children,
|
|
||||||
}: Readonly<{ children: React.ReactNode}>) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{children}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -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}
|
||||||
|
</ThemeProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
</GsapProvider>
|
</GsapProvider>
|
||||||
</ThemeProvider>
|
|
||||||
</TrpcProvider>
|
</TrpcProvider>
|
||||||
</ClerkProvider>
|
</ClerkProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
@@ -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>;
|
||||||
|
|||||||
34
src/server/routers/cvCategory.ts
Normal file
34
src/server/routers/cvCategory.ts
Normal 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();
|
||||||
|
})
|
||||||
|
});
|
||||||
16
src/server/routers/cvEntry.ts
Normal file
16
src/server/routers/cvEntry.ts
Normal 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;
|
||||||
|
}),
|
||||||
|
});
|
||||||
4
src/server/routers/project.ts
Normal file
4
src/server/routers/project.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { router } from "~/server/trpc";
|
||||||
|
|
||||||
|
export const projectRouter = router({
|
||||||
|
});
|
||||||
5
src/server/routers/techStack.ts
Normal file
5
src/server/routers/techStack.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { router } from "~/server/trpc";
|
||||||
|
|
||||||
|
|
||||||
|
export const techStackRouter = router({
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user