Initial commit: deardiary project setup
This commit is contained in:
86
frontend/src/pages/Journal.tsx
Normal file
86
frontend/src/pages/Journal.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { api, Journal } from '../lib/api';
|
||||
|
||||
export default function JournalPage() {
|
||||
const { date } = useParams<{ date: string }>();
|
||||
const [journal, setJournal] = useState<Journal | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [generating, setGenerating] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (date) loadJournal();
|
||||
}, [date]);
|
||||
|
||||
const loadJournal = async () => {
|
||||
if (!date) return;
|
||||
setLoading(true);
|
||||
const res = await api.getJournal(date);
|
||||
if (res.data) {
|
||||
setJournal(res.data);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const handleGenerate = async () => {
|
||||
if (!date) return;
|
||||
setGenerating(true);
|
||||
const res = await api.generateJournal(date);
|
||||
if (res.data) {
|
||||
setJournal(res.data);
|
||||
}
|
||||
setGenerating(false);
|
||||
};
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
const d = new Date(dateStr + 'T12:00:00');
|
||||
return d.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' });
|
||||
};
|
||||
|
||||
if (!date) return null;
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto p-4">
|
||||
<div className="mb-6">
|
||||
<a href={`/day/${date}`} className="text-slate-400 hover:text-white text-sm mb-1 inline-block">← Back to day</a>
|
||||
<h1 className="text-2xl font-bold">Journal</h1>
|
||||
<p className="text-slate-400">{formatDate(date)}</p>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="text-center py-12 text-slate-400">Loading...</div>
|
||||
) : !journal ? (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-slate-400 mb-4">No journal generated yet</p>
|
||||
<button
|
||||
onClick={handleGenerate}
|
||||
disabled={generating}
|
||||
className="px-6 py-3 bg-purple-600 hover:bg-purple-700 rounded-lg font-medium transition disabled:opacity-50"
|
||||
>
|
||||
{generating ? 'Generating...' : 'Generate Journal'}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<div className="text-sm text-slate-400 mb-4">
|
||||
Generated {new Date(journal.generatedAt).toLocaleString()} • {journal.entryCount} entries
|
||||
</div>
|
||||
<div className="prose prose-invert prose-slate max-w-none">
|
||||
<div className="bg-slate-900 rounded-xl p-6 border border-slate-800 whitespace-pre-wrap leading-relaxed">
|
||||
{journal.content}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 flex gap-4">
|
||||
<button
|
||||
onClick={handleGenerate}
|
||||
disabled={generating}
|
||||
className="px-4 py-2 bg-slate-800 hover:bg-slate-700 rounded-lg text-sm transition disabled:opacity-50"
|
||||
>
|
||||
Regenerate
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user