diff --git a/apps/web/app/(dashboard)/daily-notes/page.tsx b/apps/web/app/(dashboard)/daily-notes/page.tsx
new file mode 100644
index 0000000..b7e7b06
--- /dev/null
+++ b/apps/web/app/(dashboard)/daily-notes/page.tsx
@@ -0,0 +1,205 @@
+'use client';
+
+import { useState, useEffect, useCallback, Suspense } from 'react';
+import { BookOpen, Plus, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';
+import dynamic from 'next/dynamic';
+import { format, addDays, subDays } from 'date-fns';
+import { toast } from 'sonner';
+import { Button } from '@/components/ui/button';
+import { Card } from '@/components/ui/card';
+
+const NoteEditor = dynamic(
+ () => import('@/components/notes/note-editor').then((m) => m.NoteEditor),
+ {
+ ssr: false,
+ loading: () => (
+
+ ),
+ }
+);
+
+interface Note {
+ id: string;
+ title: string;
+ content: string | null;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export default function DailyNotesPage() {
+ const [currentDate, setCurrentDate] = useState(new Date());
+ const [note, setNote] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [creating, setCreating] = useState(false);
+ const [saveStatus, setSaveStatus] = useState<'Saved' | 'Saving' | 'Failed'>('Saved');
+
+ const dateStr = format(currentDate, 'yyyy-MM-dd');
+ const displayDate = format(currentDate, 'EEEE, MMMM d, yyyy');
+
+ const fetchDailyNote = useCallback(async () => {
+ setLoading(true);
+ setNote(null);
+ try {
+ const res = await fetch(`/api/notes/daily?date=${dateStr}`);
+ if (!res.ok) throw new Error('Failed to fetch daily note');
+ const data = await res.json();
+ if (data.note) {
+ setNote(data.note);
+ }
+ } catch (err) {
+ console.error('Failed to fetch daily note:', err);
+ } finally {
+ setLoading(false);
+ }
+ }, [dateStr]);
+
+ useEffect(() => {
+ fetchDailyNote();
+ }, [fetchDailyNote]);
+
+ async function handleCreateDailyNote() {
+ setCreating(true);
+ try {
+ const res = await fetch('/api/notes/daily', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ date: dateStr }),
+ });
+ if (!res.ok) {
+ const text = await res.text();
+ console.error('Failed to create daily note', text);
+ toast.error('Failed to create daily note');
+ return;
+ }
+ const createdNote = await res.json();
+ setNote(createdNote);
+ toast.success('Daily note created');
+ } catch (err) {
+ console.error('Failed to create daily note:', err);
+ toast.error('Failed to create daily note');
+ } finally {
+ setCreating(false);
+ }
+ }
+
+ function navigate(delta: number) {
+ const next = delta > 0 ? addDays(currentDate, 1) : subDays(currentDate, 1);
+ setCurrentDate(next);
+ }
+
+ function goToToday() {
+ setCurrentDate(new Date());
+ }
+
+ async function handleSave(content: string) {
+ if (!note) return;
+ setSaveStatus('Saving');
+ try {
+ const res = await fetch(`/api/notes/${note.id}`, {
+ method: 'PATCH',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ content }),
+ });
+ if (!res.ok) throw new Error('Failed to save');
+ setSaveStatus('Saved');
+ } catch (err) {
+ console.error('Failed to save note:', err);
+ setSaveStatus('Failed');
+ toast.error('Failed to save note');
+ }
+ }
+
+ const isToday = dateStr === format(new Date(), 'yyyy-MM-dd');
+
+ return (
+
+
+
+
Daily Notes
+
+ {displayDate}
+
+
+
+
+ {!isToday && (
+
+ )}
+
+
+
+
+
+ {loading ? (
+
+
+
+ ) : note ? (
+
+
+
+
{note.title}
+
+ {saveStatus}
+
+
+
+
+
+
+ Loading editor...
+
+
+ }
+ >
+
{
+ setNote({ ...note, content });
+ handleSave(content);
+ }}
+ />
+
+
+
+ ) : (
+
+
+
+
No daily note yet
+
+ {isToday
+ ? 'Create your daily note to track what you accomplished today.'
+ : 'No daily note exists for this date.'}
+
+
+
+
+ )}
+
+
+ );
+}
diff --git a/apps/web/components/sidebar.tsx b/apps/web/components/sidebar.tsx
index 85079ed..1c23967 100644
--- a/apps/web/components/sidebar.tsx
+++ b/apps/web/components/sidebar.tsx
@@ -10,6 +10,7 @@ import {
Flame,
FolderKanban,
NotebookPen,
+ BookOpen,
Share2,
CalendarDays,
Search,
@@ -41,6 +42,7 @@ const navItems = [
{ href: '/habits', label: 'Habits', icon: Flame },
{ href: '/projects', label: 'Projects', icon: FolderKanban },
{ href: '/notes', label: 'Notes', icon: NotebookPen },
+ { href: '/daily-notes', label: 'Daily Note', icon: BookOpen },
{ href: '/graph', label: 'Graph', icon: Share2 },
{ href: '/calendar', label: 'Calendar', icon: CalendarDays },
{ href: '/search', label: 'Search', icon: Search },