50 lines
1.6 KiB
TypeScript
50 lines
1.6 KiB
TypeScript
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "~/components/ui/card"
|
|
import { cn } from "~/lib/utils"
|
|
import Markdown from 'react-markdown'
|
|
import { format } from 'date-fns'
|
|
import rehypeHighlight from 'rehype-highlight'
|
|
import rehypeRaw from 'rehype-raw'
|
|
import type { ArrayElement } from "type-fest"
|
|
import AnimateTextIn from "~/app/_components/Animated/AnimateIn"
|
|
import AnimatePopUp from "~/app/_components/Animated/AnimatePopUp"
|
|
import type { CvCategoryData } from "./CvCategory"
|
|
|
|
export type CvEntryData = ArrayElement<CvCategoryData['cvEntry']>
|
|
|
|
export default function CvEntry({ entry, className, position = 0 }: {
|
|
entry: CvEntryData,
|
|
className?: string,
|
|
position?: number
|
|
}) {
|
|
return (
|
|
<Card className={className ? cn("w-fit", className) : "w-fit"}>
|
|
{entry.title ?
|
|
<CardHeader>
|
|
<AnimateTextIn position={position} animation="slide">
|
|
<CardTitle> {entry.title} </CardTitle>
|
|
</AnimateTextIn>
|
|
</CardHeader> :
|
|
<></>
|
|
}
|
|
{entry.description ?
|
|
<CardContent className="text-sm lg:text-base">
|
|
<AnimatePopUp position={position + 0.2}>
|
|
<article className="prose prose-zinc dark:prose-invert max-w-none">
|
|
<Markdown rehypePlugins={[rehypeHighlight, rehypeRaw]}>{entry.description}</Markdown>
|
|
</article>
|
|
</AnimatePopUp>
|
|
</CardContent> :
|
|
<></>
|
|
}
|
|
{!entry.hideDates ?
|
|
<CardFooter className="text-sm">
|
|
<AnimateTextIn position={position + 0.4}>
|
|
{`von ${format(new Date(entry.fromTime), 'M. yyyy')} bis zum ${format(new Date(entry.toTime), 'M. yyyy')}`}
|
|
</AnimateTextIn>
|
|
</CardFooter> :
|
|
<></>
|
|
}
|
|
</Card>
|
|
)
|
|
}
|