before remove routers

This commit is contained in:
2025-07-30 09:28:25 +02:00
parent b58024b66a
commit 2816842b5d
20 changed files with 1202 additions and 900 deletions

View File

@@ -1,70 +1,27 @@
import Link from "next/link";
import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger } from "~/components/ui/sidebar";
import SimpleSidebarGroup from "~/components/ui/simple-sidebar-group";
export default async function AdminSideBar() {
return (
<>
<SidebarProvider>
<Sidebar className="z-[51]">
<SidebarTrigger className="absolute z-[52] left-65 top-100" />
<SidebarTrigger className="absolute z-[52] left-65 top-100" />
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>
CV
</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={"/admin/cv/category/create"}> Create Category </Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={"/admin/cv/entry/create"}> Create Entry </Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={"/admin/cv/category/list"}> Category List </Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={"/admin/cv/entry/list"}> Entry List </Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
<SidebarGroup>
<SidebarGroupLabel>
Projects
</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={"/admin/project/create"}> Create Project </Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
<SidebarGroup>
<SidebarGroupLabel>
Blog
</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={"/"}> Some Blog Action </Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
<SimpleSidebarGroup lable="CV">
<Link href={"/admin/cv/category/create"}> Create Category </Link>
<Link href={"/admin/cv/entry/create"}> Create Entry </Link>
<Link href={"/admin/cv/category/list"}> Category List </Link>
<Link href={"/admin/cv/entry/list"}> Entry List </Link>
</SimpleSidebarGroup>
<SimpleSidebarGroup lable="Projects">
<Link href={"/admin/project/create"}> Create Project </Link>
<Link href={"/admin/project/techStack/create"}> Create Stack </Link>
</SimpleSidebarGroup>
<SimpleSidebarGroup lable="Blog">
<Link href={"/"}> Some Blog Action </Link>
</SimpleSidebarGroup>
</SidebarContent>
</Sidebar>
</SidebarProvider>

View File

@@ -7,6 +7,6 @@ export default async function Page({params}:{params: Promise<{id:string}>}) {
console.log(params)
const {id} = await params;
return (
<UpdateCvCategoryForm id={id} className={undefined}/>
<UpdateCvCategoryForm id={id} />
)
}

View File

@@ -6,7 +6,7 @@ import type { CategoryRouterOutputs } from "~/server/routers/cv/category";
import { type Element } from "~/lib/utils";
import UpdateCvCategoryForm from "./UpdateForm";
import CreateCvCategoryForm from "./CreateForm";
export default function CollapsibleCvCategoryForm(params:{category:Element<CategoryRouterOutputs['list']>|undefined}) {
export default function CollapsibleCvCategoryForm(params:{category?:Element<CategoryRouterOutputs['list']>}) {
return (
<Collapsible >
<CollapsibleTrigger asChild>

View File

@@ -9,20 +9,35 @@ import { Select, SelectContent, SelectTrigger, SelectItem, SelectValue } from "~
import { trpc } from "~/app/_trpc/Client";
import { Button } from "~/components/ui/button";
import * as Card from '~/components/ui/card'
export default function CreateCvCategoryForm(params:{className:string|undefined}) {
const form = useForm<z.infer<typeof insertSchema>>({
resolver: zodResolver(insertSchema),
import type { IterableElement } from 'type-fest'
import { usePathname, useRouter } from "next/navigation";
import { entitySchemas } from "~/lib/utils";
import type { RouterOutputs } from "~/server/routers/_app";
export default function CreateCvCategoryForm(params:{className?:string,category?:IterableElement<RouterOutputs['cv']['categoryv2']['select']>}) {
const schemas = entitySchemas('cvCategory')
const pathname = usePathname();
const router = useRouter();
const form = useForm<z.infer<typeof schemas.insert>>({
resolver: zodResolver(schemas.insert),
defaultValues: {
id: crypto.randomUUID(),
layoutPosition: "col1"
}
})
const mutation = trpc.cv.category.create.useMutation()
function onSubmit(values: z.infer<typeof insertSchema>) {
mutation.mutate(values)
form.setValue("id",crypto.randomUUID())
const createMutation = trpc.cv.categoryv2.insert.useMutation()
function onSubmit(values: z.infer<typeof schemas.insert>) {
const res = createMutation.mutate(values)
}
const updateMutation = trpc.cv.categoryv2.update.useMutation()
const deleteMutation = trpc.cv.categoryv2.delete.useMutation({
onSuccess: () => {
if (pathname.includes('list')) {
router.refresh()
} else {
router.back()
}
}
})
return (
<Card.Card className={params.className ? params.className : "w-5/6 lg:w-1/2"}>
<Card.CardHeader>
@@ -76,8 +91,8 @@ export default function CreateCvCategoryForm(params:{className:string|undefined}
>
</FormField>
<Button type="submit"> Create </Button>
<FormMessage className={mutation.status == "success" ? "text-green-500" : "text-red-500"}>
{mutation.error ? mutation.error.message : mutation.status}
<FormMessage className={createMutation.status == "success" ? "text-green-500" : "text-red-500"}>
{createMutation.error ? createMutation.error.message : createMutation.status}
</FormMessage>
</form>
</Form>

View File

@@ -12,11 +12,10 @@ import * as Card from '~/components/ui/card'
import { useRouter, usePathname } from "next/navigation";
import { Delete } from "lucide-react";
import { cn } from "~/lib/utils";
export default function UpdateCvCategoryForm(params: { id: string, className: string | undefined }) {
export default function UpdateCvCategoryForm(params: { id: string, className?: string }) {
const router = useRouter();
const pathname = usePathname();
const id = params.id;
console.log(id)
const category = trpc.cv.category.get.useQuery({ id: id })
const form = useForm<z.infer<typeof updateRouteSchema>>({
resolver: zodResolver(updateRouteSchema),

View File

@@ -41,21 +41,21 @@ export default function CvPage() {
cat.cvEntry.length > 0 ? (
<>
{cat.cvEntry.map((entry) => (
<CollapsibleCvEntryForm key={entry.id} entry={entry} categoryId={undefined} />
<CollapsibleCvEntryForm key={entry.id} entry={entry}/>
))}
</>
) : (<></>)
}
</div>
<div className="flex flex-col w-full">
<CollapsibleCvEntryForm entry={undefined} categoryId={cat.id} />
<CollapsibleCvEntryForm categoryId={cat.id} />
</div>
</div>
</Card.CardContent>
</Card.Card>
)
})}
<CollapsibleCvCategoryForm category={undefined} />
<CollapsibleCvCategoryForm />
</>
}
</div>

View File

@@ -6,7 +6,7 @@ import type { CategoryRouterOutputs } from "~/server/routers/cv/category";
import { type Element } from "~/lib/utils";
import UpdateCvEntryForm from "./UpdateForm";
import CreateCvEntryForm from "./CreateForm";
export default function CollapsibleCvEntryForm(params:{entry:Element<Element<CategoryRouterOutputs['list']>['cvEntry']>|EntryRouterOutputs['get']|Element<EntryRouterOutputs['list']>|undefined, categoryId: string|undefined}) {
export default function CollapsibleCvEntryForm(params:{entry?:Element<Element<CategoryRouterOutputs['list']>['cvEntry']>|EntryRouterOutputs['get']|Element<EntryRouterOutputs['list']>, categoryId?: string}) {
return (
<Collapsible>
<CollapsibleTrigger asChild>

View File

@@ -13,7 +13,7 @@ import type { Entries } from 'type-fest'
import { type Element } from "~/lib/utils";
import type { ProjectRouterOutputs } from "~/server/routers/project";
import { Suspense } from "react";
export default function CreateUpdateProjectForm(params:{className:string|undefined, project:Element<ProjectRouterOutputs['list']>|undefined}) {
export default function CreateUpdateProjectForm(params:{className?:string, project?:Element<ProjectRouterOutputs['list']>}) {
const [techStacks,] = trpc.project.stack.list.useSuspenseQuery()
const form = useForm<z.infer<typeof insertSchema>>({
resolver: zodResolver(insertSchema),
@@ -26,8 +26,8 @@ export default function CreateUpdateProjectForm(params:{className:string|undefin
})
const updateMutation = trpc.project.update.useMutation({
onSuccess: (data) => {
if (null !== data) {
let entries = Object.entries(data) as Entries<typeof data>
if (data.length > 0 && data[0] !== undefined) {
let entries = Object.entries(data[0]) as Entries<typeof data[0]>
entries.forEach( (entry) => {
form.setValue(entry[0],entry[1])
})

View File

@@ -1,7 +1,7 @@
import CreateUpdateProjectForm from "../_components/CreateForm";
import CreateUpdateProjectForm from "../_components/CreateUpdateProjectForm";
export default function Page() {
return (
<CreateUpdateProjectForm className="" project={undefined}/>
<CreateUpdateProjectForm />
)
}

View File

@@ -0,0 +1,27 @@
import { ChevronsUpDown, Plus } from "lucide-react"
import { Button } from "~/components/ui/button";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "~/components/ui/collapsible";
import { type Element } from "~/lib/utils";
import CreateUpdateProjectForm from "./CreateForm";
import type { ProjectRouterOutputs } from "~/server/routers/project";
export default function CollapsibleForm(params:{project:Element<ProjectRouterOutputs['list']>|undefined}) {
return (
<Collapsible >
<CollapsibleTrigger asChild>
<Button variant={"ghost"}>
{ params.project ?
<>{params.project.title} <ChevronsUpDown/></> : <>New <Plus/></>
}
</Button>
</CollapsibleTrigger>
<CollapsibleContent className="autoAlpha">
{
params.project ?
<CreateUpdateProjectForm className="w-full" project={params.project}/> :
<CreateUpdateProjectForm className="w-full" project={params.project}/>
}
</CollapsibleContent>
</Collapsible>
)
}

View File

@@ -0,0 +1,100 @@
"use client"
import { insertSchema } from "~/lib/schema/project/techStack"
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { z } from "zod";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "~/components/ui/form";
import { trpc } from "~/app/_trpc/Client";
import { Button } from "~/components/ui/button";
import * as Card from '~/components/ui/card'
import type { Entries } from 'type-fest'
import { type Element } from "~/lib/utils";
import type { StackRouter, StackRouterOutputs } from "~/server/routers/project/techStack";
import { stackItemEnum } from "~/server/db/schema";
import { ToggleGroup, ToggleGroupItem } from "~/components/ui/toggle-group";
export default function CreateUpdateForm(params:{className:string|undefined, techStack?:Element<StackRouterOutputs['list']>}) {
const form = useForm<z.infer<typeof insertSchema>>({
resolver: zodResolver(insertSchema),
defaultValues: {
id: params.techStack ? params.techStack.id : crypto.randomUUID(),
stackItems: params.techStack ? params.techStack.stackItems : [],
}
})
const createMutation = trpc.project.stack.create.useMutation({
onSuccess: (data) => { form.setValue("id", data[0] ? data[0].id : "") }
})
const updateMutation = trpc.project.stack.update.useMutation({
onSuccess: (data) => {
if (data.length > 0 && data[0] !== undefined) {
let entries = Object.entries(data[0]) as Entries<typeof data[0]>
entries.forEach( (entry) => {
form.setValue(entry[0],entry[1])
})
}
}
})
function onSubmit(values: z.infer<typeof insertSchema>) {
params.techStack ?
updateMutation.mutate({by: {id: values.id}, update: { ...values}}) :
createMutation.mutate(values)
}
return (
<Card.Card className={params.className ? params.className : "w-5/6 lg:w-1/2"}>
<Card.CardHeader>
<Card.CardTitle>
{params.techStack ? "Update" : "Create"} Tech Stack
</Card.CardTitle>
</Card.CardHeader>
<Card.CardContent>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8"
>
<FormField
control={form.control}
name="stackItems"
render={({ field }) => (
<FormItem>
<FormLabel>
Stack Items
</FormLabel>
<FormControl>
<ToggleGroup
variant="outline"
type="multiple"
onValueChange={field.onChange}
className="flex flex-wrap"
>
{stackItemEnum.enumValues.map((v) => {
return (
<ToggleGroupItem className="w-fit" key={v} value={v}>
{v}
</ToggleGroupItem>
)
})}
</ToggleGroup>
</FormControl>
</FormItem>
)}
/>
<Button type="submit"> {params.techStack ? "Update" : "Create"} </Button>
<FormMessage className={updateMutation.status == "success" || createMutation.status == "success" ? "text-green-500" : "text-red-500"}>
{ params.techStack ?
(
<>{updateMutation.error ? updateMutation.error.message : updateMutation.status}</>
) :
(
<>{createMutation.error ? createMutation.error.message : createMutation.status}</>
)
}
</FormMessage>
</form>
</Form>
</Card.CardContent>
</Card.Card>
)
}

View File

@@ -0,0 +1,7 @@
import CreateUpdateForm from "../_components/CreateUpdateForm";
export default function Page() {
return (
<CreateUpdateForm className=""/>
)
}