mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
Q & A + journal (#174)
* tasks * task input * community route * added thread and list for community QA * answers thread * journal sidebar section * journal calendar * fix: stuff * fix: stuff * fix: stuff * chore: disable comunitty toggle * fix: typo import header --------- Co-authored-by: marshennikovaolga <marshennikova@gmail.com> Co-authored-by: Aslam H <iupin5212@gmail.com>
This commit is contained in:
114
web/components/routes/journal/JournalRoute.tsx
Normal file
114
web/components/routes/journal/JournalRoute.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
"use client"
|
||||
|
||||
import { useState, useEffect } from "react"
|
||||
import { JournalEntry, JournalEntryLists } from "@/lib/schema/journal"
|
||||
import { useAccount } from "@/lib/providers/jazz-provider"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { calendarFormatDate } from "@/lib/utils"
|
||||
import { Calendar } from "@/components/ui/calendar"
|
||||
|
||||
export function JournalRoute() {
|
||||
const [date, setDate] = useState<Date>(new Date())
|
||||
const { me } = useAccount({ root: { journalEntries: [] } })
|
||||
const [newNote, setNewNote] = useState<JournalEntry | null>(null)
|
||||
|
||||
const notes = me?.root?.journalEntries || (me ? JournalEntryLists.create([], { owner: me }) : [])
|
||||
|
||||
useEffect(() => {
|
||||
console.log("me:", me)
|
||||
}, [me])
|
||||
|
||||
const selectDate = (selectedDate: Date | undefined) => {
|
||||
if (selectedDate) {
|
||||
setDate(selectedDate)
|
||||
}
|
||||
}
|
||||
|
||||
const createNewNote = () => {
|
||||
if (me) {
|
||||
const newEntry = JournalEntry.create(
|
||||
{
|
||||
title: "",
|
||||
content: "",
|
||||
date: date,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
},
|
||||
{ owner: me._owner }
|
||||
)
|
||||
setNewNote(newEntry)
|
||||
}
|
||||
}
|
||||
|
||||
const handleNewNoteChange = (field: keyof JournalEntry, value: string) => {
|
||||
if (newNote) {
|
||||
setNewNote(prevNote => {
|
||||
if (prevNote) {
|
||||
return JournalEntry.create({ ...prevNote, [field]: value }, { owner: me!._owner })
|
||||
}
|
||||
return prevNote
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const saveNewNote = () => {
|
||||
if (newNote && me?.root?.journalEntries) {
|
||||
me.root.journalEntries.push(newNote)
|
||||
setNewNote(null)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-auto flex-col">
|
||||
<div className="relative flex flex-1 overflow-hidden">
|
||||
<div className="flex-grow overflow-y-auto p-6">
|
||||
{newNote ? (
|
||||
<div className="mb-6 rounded-lg border p-4 shadow-sm">
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Title"
|
||||
value={newNote.title}
|
||||
onChange={e => handleNewNoteChange("title", e.target.value)}
|
||||
className="mb-2 w-full text-xl font-semibold"
|
||||
/>
|
||||
<Textarea
|
||||
placeholder="Content"
|
||||
value={newNote.content as string}
|
||||
onChange={e => handleNewNoteChange("content", e.target.value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<Button onClick={saveNewNote} className="mt-2">
|
||||
Save Note
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
{notes.map((entry, index) => (
|
||||
<div key={index} className="mb-6 rounded-lg border p-4 shadow-sm">
|
||||
<h2 className="mb-2 text-xl font-semibold">{entry?.title}</h2>
|
||||
<div className="prose prose-sm max-w-none">
|
||||
{entry?.content &&
|
||||
(typeof entry.content === "string" ? (
|
||||
<div dangerouslySetInnerHTML={{ __html: entry.content }} />
|
||||
) : (
|
||||
<pre>{JSON.stringify(entry.content, null, 2)}</pre>
|
||||
))}
|
||||
</div>
|
||||
<p className="mt-2 text-sm opacity-70">{entry?.date && calendarFormatDate(new Date(entry.date))}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="w-[22%] border-l p-2">
|
||||
<Calendar mode="single" selected={date} onSelect={selectDate} className="rounded-md border" />
|
||||
<Button onClick={createNewNote} className="mt-4 w-full">
|
||||
New Note
|
||||
</Button>
|
||||
<div className="p-2 text-sm opacity-50">
|
||||
<p>Total notes: {notes.length}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user