better markdown support, minor layout fixes

This commit is contained in:
2025-06-17 03:21:41 +02:00
parent d176f66865
commit 9f58cc3207
10 changed files with 674 additions and 30 deletions

View File

@@ -41,7 +41,7 @@ export default function CvPage() {
cat.cvEntry.length > 0 ? (
<>
{cat.cvEntry.map((entry) => (
<CollapsibleCvEntryForm key={entry.id} entry={entry} />
<CollapsibleCvEntryForm key={entry.id} entry={entry} categoryId={undefined} />
))}
</>
) : (<></>)

View File

@@ -16,12 +16,15 @@ import { Calendar } from "~/components/ui/calendar";
import { cn } from "~/lib/utils";
import { useEffect, useState } from "react"
import { Checkbox } from "~/components/ui/checkbox"
import MDEditor from '@uiw/react-md-editor'
import { useTheme } from "next-themes"
export default function CreateCvEntryForm(params:{className:string|undefined, categoryId:string|undefined}) {
const { theme } = useTheme()
const categories = trpc.cv.category.list.useQuery()
console.log(params.categoryId)
const [categorySelectPlaceHolder,setCategorySelectPlaceHolder] = useState("Select category")
const [categorySelectDefaultValue,setCategorySelectDefaultValue] = useState("")
const [mdeTab,setMdeTab] = useState<"write" | "preview" | undefined>("write");
useEffect(() => {
console.log('category success effect')
if (categories.data !== undefined) {
@@ -38,6 +41,8 @@ export default function CreateCvEntryForm(params:{className:string|undefined, ca
}
}
},[categories.isSuccess])
const now = new Date();
now.setTime(Date.now());
const form = useForm<z.infer<typeof insertSchemaForm>>({
resolver: zodResolver(insertSchemaForm),
defaultValues: {
@@ -45,6 +50,8 @@ export default function CreateCvEntryForm(params:{className:string|undefined, ca
title: "",
description: "",
categoryId: params.categoryId ? params.categoryId : "",
fromTime: now,
toTime: now,
hideDates: false,
}
@@ -53,7 +60,7 @@ export default function CreateCvEntryForm(params:{className:string|undefined, ca
onSuccess: (data) => { form.setValue("id", data[0] ? data[0].id : "") }
})
function onSubmit(values: z.infer<typeof insertSchemaForm>) {
let { id, title, categoryId, description } = values
let { id, title, categoryId, description, hideDates } = values
let v: z.infer<typeof insertSchema> = {
id: id,
categoryId: categoryId,
@@ -61,6 +68,7 @@ export default function CreateCvEntryForm(params:{className:string|undefined, ca
title: title,
fromTime: format(values.fromTime,'yyyy-MM-dd'),
toTime: format(values.toTime,'yyyy-MM-dd'),
hideDates: hideDates
}
mutation.mutate(v)
form.setValue("id", crypto.randomUUID())
@@ -128,7 +136,11 @@ export default function CreateCvEntryForm(params:{className:string|undefined, ca
Description
</FormLabel>
<FormControl>
<Input placeholder="description" onChange={field.onChange} value={field.value == null ? undefined : field.value} />
<MDEditor
value={field.value ? field.value : ""}
onChange={field.onChange}
data-color-mode={theme ? theme : "dark"}
/>
</FormControl>
</FormItem>
)}

View File

@@ -11,14 +11,18 @@ import { Button } from "~/components/ui/button";
import * as Card from '~/components/ui/card'
import { format } from 'date-fns'
import { Popover, PopoverContent, PopoverTrigger } from "~/components/ui/popover";
import { cn } from "~/lib/utils";
import { cn, type Element } from "~/lib/utils";
import { CalendarIcon, Delete } from "lucide-react";
import { Calendar } from "~/components/ui/calendar";
import { Textarea } from "~/components/ui/textarea";
import { usePathname, useRouter } from "next/navigation";
import { Checkbox } from "~/components/ui/checkbox";
import MDEditor from '@uiw/react-md-editor'
import { useTheme } from "next-themes"
import type { EntryRouterOutputs } from "~/server/routers/cv/entry";
export default function UpdateCvEntryForm(params : { id: string, className: string | undefined }) {
console.log(params)
const { theme } = useTheme()
const id = params.id
const categories = trpc.cv.category.list.useQuery()
const entry = trpc.cv.entry.get.useQuery({ id: id })
@@ -35,25 +39,29 @@ export default function UpdateCvEntryForm(params : { id: string, className: stri
}
}
})
entry.promise.then((v) => {
const updateFormValues = (v:EntryRouterOutputs['get']|Element<EntryRouterOutputs['update']>) => {
form.setValue('update.title', v?.title)
form.setValue('update.description', v?.description);
form.setValue('update.fromTime', new Date(Date.parse(v ? v.fromTime : "")))
form.setValue('update.toTime', new Date(Date.parse(v ? v.toTime : "")))
form.setValue('update.categoryId', v?.categoryId)
form.setValue('update.hideDates', v?.hideDates)
}
entry.promise.then((v) => {
updateFormValues(v)
})
const updateMutation = trpc.cv.entry.update.useMutation({
onSuccess: () => {
if (pathname.includes('list')) {
router.refresh()
} else {
router.back()
onSuccess: (v) => {
if (v[0] !== undefined) {
updateFormValues(v[0])
}
}
})
const deleteMutation = trpc.cv.entry.delete.useMutation({
onSuccess: () => {
if (!pathname.includes('list')) {
router.back()
}
}
})
const deleteEntry = (id: string) => {
@@ -137,7 +145,12 @@ export default function UpdateCvEntryForm(params : { id: string, className: stri
Description
</FormLabel>
<FormControl>
<Textarea placeholder="description" onChange={field.onChange} value={field.value == null ? undefined : field.value} />
<MDEditor
value={field.value ? field.value : ""}
onChange={field.onChange}
data-color-mode={theme ? theme : "dark"}
previewOptions={{skipHtml:false}}
/>
</FormControl>
</FormItem>
)}