Files
gregorlohaus.com/src/app/cv/_components/CvEntry.tsx

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>
)
}