1
0
Fork 0

feat: render notes as markdown

user-stream
Lea 2023-08-11 20:19:53 +02:00 committed by insert
parent 03fffc9849
commit edd1f9d297
4 changed files with 741 additions and 112 deletions

View File

@ -8,6 +8,9 @@ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }
import { useSession } from "next-auth/react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
dayjs.extend(relativeTime);
export default function SafetyNotesCard({ objectId, type, title }: {
@ -20,6 +23,7 @@ export default function SafetyNotesCard({ objectId, type, title }: {
const [value, setValue] = useState<SafetyNotes | null>(null);
const [ready, setReady] = useState(false);
const [error, setError] = useState<string | null>(null);
const [editing, setEditing] = useState(false);
useEffect(() => {
fetchSafetyNote(objectId, type)
@ -39,41 +43,63 @@ export default function SafetyNotesCard({ objectId, type, title }: {
<CardTitle>{title ?? type.charAt(0).toUpperCase() + type.slice(1) + " notes"}</CardTitle>
</CardHeader>
<CardContent>
<Textarea
placeholder={
error
? error
: ready
? "Enter notes here... (save on unfocus)"
: "Fetching notes..."
}
className="!min-h-[80px] max-h-[50vh]"
disabled={!ready || error != null}
value={ready ? draft : undefined} // not defaulting to undefined causes next to complain
onChange={(e) => setDraft(e.currentTarget.value)}
onBlur={async () => {
if (draft === value?.text ?? "") return;
try {
await updateSafetyNote(objectId, type, draft);
setValue({
_id: { id: objectId, type: type },
edited_at: new Date(Date.now()),
edited_by: session.data?.user?.email || "",
text: draft,
});
toast({
title: "Updated notes",
});
} catch (err) {
toast({
title: "Failed to update notes",
description: String(err),
variant: "destructive",
});
{
editing
? <Textarea
placeholder={
error
? error
: ready
? "Enter notes here... (save on unfocus)"
: "Fetching notes..."
}
}}
/>
className="!min-h-[80px] max-h-[50vh]"
disabled={!ready || error != null}
value={ready ? draft : undefined} // not defaulting to undefined causes next to complain
autoFocus
onChange={(e) => setDraft(e.currentTarget.value)}
onBlur={async () => {
if (draft === value?.text ?? "") return setEditing(false);
try {
await updateSafetyNote(objectId, type, draft);
setValue({
_id: { id: objectId, type: type },
edited_at: new Date(Date.now()),
edited_by: session.data?.user?.email || "",
text: draft,
});
setEditing(false);
toast({
title: "Updated notes",
});
} catch (err) {
setEditing(false);
toast({
title: "Failed to update notes",
description: String(err),
variant: "destructive",
});
}
}}
/>
: <div onClick={() => setEditing(true)}>
{
error
? <>{error}</>
: value?.text
? <ReactMarkdown
className="prose prose-a:text-[#fd6671] prose-img:max-h-96"
remarkPlugins={[remarkGfm]}
>
{value.text}
</ReactMarkdown>
: ready
? <i>Click to add a note</i>
: <i>Fetching notes...</i>
}
</div>
}
</CardContent>
<CardFooter className="-my-2">
<CardDescription>

View File

@ -39,7 +39,9 @@
"postcss": "8.4.27",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-markdown": "^8.0.7",
"redis": "^4.6.7",
"remark-gfm": "^3.0.1",
"revolt-api": "^0.6.5",
"sass": "^1.64.1",
"tailwind-merge": "^1.14.0",
@ -49,6 +51,7 @@
"ulid": "^2.3.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",
"@types/lodash.debounce": "^4.0.7",
"revolt.js": "7.0.0-beta.9"
}

File diff suppressed because it is too large Load Diff

View File

@ -72,5 +72,5 @@ module.exports = {
},
},
},
plugins: [require("tailwindcss-animate")],
plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")],
}