cv page in pretty good state, markdown/html support added to description
This commit is contained in:
@@ -4,6 +4,7 @@ import CvEntry, { type CvEntryProps } from "./CvEntry"
|
||||
import type { servTrpc } from "~/app/_trpc/ServerClient"
|
||||
import type { inferProcedureOutput } from "@trpc/server"
|
||||
import type { RouterOutputs } from "~/server/routers/_app"
|
||||
import { cn } from "~/lib/utils"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"
|
||||
type CvCategoryProps = {
|
||||
initialData: RouterOutputs['cv']['category']['get'],
|
||||
@@ -14,14 +15,14 @@ export default function CvCategory(props:CvCategoryProps) {
|
||||
const query = trpc.cv.category.get.useQuery({id: props.initialData? props.initialData.id : ""});
|
||||
if (query.data !== undefined) {
|
||||
return (
|
||||
<Card className="gsapan">
|
||||
<Card className={props.layout == "row" ? "w-full" : ""}>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
{query.data?.name}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
{(query.data?.cvEntry.length ? query.data?.cvEntry.length : 0 ) > 0 ?
|
||||
<CardContent>
|
||||
<CardContent className={cn(props.layout == "row" ? "flex flex-row" : "flex flex-col","gap-[1rem]")}>
|
||||
{query.data?.cvEntry.map((entry) => (
|
||||
<CvEntry key={entry.id} initialData={entry}/>
|
||||
))}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { trpc } from "~/app/_trpc/Client"
|
||||
import { Card, CardAction, 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 type { Element } from "~/lib/utils"
|
||||
import type { cvEntry } from "~/server/db/schema"
|
||||
import type { CategoryRouterOutputs } from "~/server/routers/cv/category"
|
||||
import type { EntryRouterOutputs } from "~/server/routers/cv/entry"
|
||||
import Markdown from 'marked-react'
|
||||
import { useEffect, useState } from "react"
|
||||
import Markdown from 'react-markdown'
|
||||
import rehypeRaw from 'rehype-raw'
|
||||
import { format } from 'date-fns'
|
||||
|
||||
export default function CvEntry(params: {
|
||||
initialData: EntryRouterOutputs['get'] | Element<Element<CategoryRouterOutputs['list']>['cvEntry']>
|
||||
}) {
|
||||
@@ -18,17 +19,29 @@ export default function CvEntry(params: {
|
||||
data ?
|
||||
<>
|
||||
<Card className="w-fit">
|
||||
<CardHeader>
|
||||
<CardTitle> {data.title} </CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div>
|
||||
<Markdown>{data.description ? data.description : undefined}</Markdown>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter className="text-sm">
|
||||
{`${data.fromTime}-${data.toTime}`}
|
||||
</CardFooter>
|
||||
{
|
||||
data.title ?
|
||||
<CardHeader>
|
||||
<CardTitle> {data.title} </CardTitle>
|
||||
</CardHeader> :
|
||||
<></>
|
||||
}
|
||||
{
|
||||
data.description ?
|
||||
<CardContent>
|
||||
<div>
|
||||
<Markdown rehypePlugins={[rehypeRaw]}>{data.description}</Markdown>
|
||||
</div>
|
||||
</CardContent> :
|
||||
<></>
|
||||
}
|
||||
{
|
||||
!data.hideDates ?
|
||||
<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')}`}
|
||||
</CardFooter> :
|
||||
<></>
|
||||
}
|
||||
</Card>
|
||||
</> :
|
||||
<>
|
||||
|
||||
@@ -7,6 +7,9 @@ import { SidebarContent, SidebarProvider, Sidebar } from "~/components/ui/sideb
|
||||
import SidebarTriggerDisappearsOnMobile from "./_components/SidebarTriggerDisappearsOnMobile";
|
||||
import CvCategory from "./_components/CvCategory";
|
||||
export default function CvPage() {
|
||||
//TODO fix display when one column is empty
|
||||
// useState to store filtered categories
|
||||
// should make this easier
|
||||
const categories = trpc.cv.category.list.useQuery();
|
||||
const gsap = useGsapContext()
|
||||
const container = useRef<HTMLDivElement>(null)
|
||||
@@ -60,9 +63,9 @@ export default function CvPage() {
|
||||
</> :
|
||||
<></>
|
||||
}
|
||||
<div className="h-full w-full flex flex-wrap flex-row p-2 ">
|
||||
<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]">
|
||||
<div id="header" className="flex w-full h-fit flex-row">
|
||||
<div id="header" className="flex w-full h-fit flex-row gap-[1rem]">
|
||||
{categories.data.filter((cat) => cat.layoutPosition == 'header').map((cat) => {
|
||||
return (
|
||||
<CvCategory layout="row" initialData={cat} key={cat.id} />
|
||||
@@ -70,7 +73,7 @@ export default function CvPage() {
|
||||
})}
|
||||
</div>
|
||||
<div id="colwrapper" className="flex flex-col md:flex-row w-full h-3/4 gap-[1rem]">
|
||||
<div id="col1" className="flex flex-col w-full h-full">
|
||||
<div id="col1" className="flex flex-col w-full md:w-1/2 h-full gap-[1rem]">
|
||||
{categories.data.filter((cat) => cat.layoutPosition == 'col1').map((cat) => {
|
||||
return (
|
||||
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
||||
@@ -78,7 +81,7 @@ export default function CvPage() {
|
||||
})}
|
||||
</div>
|
||||
{categories.data.filter((cat) => cat.layoutPosition == 'col2').length > 0 ?
|
||||
<div id="col2" className="flex flex-wrap flex-col w-full lg:w-1/2 h-full">
|
||||
<div id="col2" className="flex flex-col w-full md:w-1/2 h-full gap-[1rem]">
|
||||
{categories.data.filter((cat) => cat.layoutPosition == 'col2').map((cat) => {
|
||||
return (
|
||||
<CvCategory layout="col" initialData={cat} key={cat.id} />
|
||||
|
||||
Reference in New Issue
Block a user