Skip to content

codejunkie99/cove

Repository files navigation

Cove

A Notion-inspired personal productivity dashboard. Tasks, journal, habits, bookmarks, pages, and a quick note — all in one calm, keyboard-driven workspace. No backend, no accounts; everything lives in localStorage.

Built with React 18, Vite, Tailwind, TypeScript, and a single D3 chart.

Status: solo project · v0.1 · live at codejunkie99.github.io/cove


UI

The default view is a dashboard: a hero greeting + clock, sticky section pills, and a 2-column card grid (Today's Focus, Quick Note, Habits, Bookmarks, Journal Streak, Words This Week). Sidebar holds six views; titlebar holds ⌘K and the dark-mode toggle.

Cove UI mockup

UX

Every flow goes through one of two entry points: the sidebar (persistent nav) or the ⌘K command palette (search + create + jump). Each view has its own write path; every write hits a small useLocalStorage hook with cross-tab StorageEvent sync, so two tabs stay in lockstep without a backend.

Cove user flow


Features

  • Today dashboard — greeting, time, sticky section pills, six cards.
  • Tasks — checkbox toggle on full row, tag chips, inline add, hover-to-delete, progress bar, kanban view with status + priority + emoji + due date.
  • Pages — block editor (paragraph, h1–h3, bullet, numbered, todo, quote, code, callout, divider).
  • Journal — write today's entry, explicit ⌘S save with unsaved indicator, word count, past-entries list, calendar heatmap streak.
  • Habits — 4 habits × 7 days, click cells to toggle, today shown with a dashed orange border.
  • Bookmarks — title + URL + colored avatar, quick-add with auto https://, list and grid views.
  • Quick note — textarea with #idea / #work / #personal chips and a live char count.
  • Command palette (⌘K) — search content across tasks, pages, journal, bookmarks; create tasks/pages; jump views; toggle theme.
  • Dark mode — CSS custom properties on :root and .dark, smooth transition, persisted.
  • Responsive — sidebar collapses to an overlay on mobile; padding scales with breakpoints.
  • Accessibility<button> over <div>, ARIA roles, focus management, sr-only labels, keyboard handlers everywhere.

Stack

Layer Choice
Framework React 18
Bundler Vite 5
Styling Tailwind 3 + CSS custom properties
Language TypeScript 5
Charting D3 (bar chart only)
Persistence window.localStorage
Tests Vitest
Hosting GitHub Pages (gh-pages branch)

No state library, no router, no backend. State lives in App.tsx and threads down as props.

Project structure

cove/
├── docs/
│   ├── ui.svg              # Dashboard mockup (this README)
│   └── ux.svg              # User-flow / IA diagram (this README)
├── index.html              # Vite entry, Inter + DM Mono
├── vite.config.ts          # base: '/cove/' for GitHub Pages
├── tailwind.config.js      # darkMode: 'class', stone + orange tokens
└── src/
    ├── main.tsx
    ├── App.tsx             # state hub: types, defaults, useLocalStorage
    ├── index.css           # CSS vars for theming + dark overrides
    ├── hooks/
    │   └── useLocalStorage.ts   # cross-tab sync + array validation
    ├── utils/                   # workStats, journalEntries
    └── components/
        ├── Titlebar.tsx
        ├── Sidebar.tsx
        ├── MainContent.tsx      # view router
        ├── CommandPalette.tsx
        ├── BlockEditor.tsx
        ├── JournalEntryEditor.tsx
        ├── KanbanBoard.tsx
        ├── WorkMode.tsx
        └── cards/
            ├── TodayFocusCard.tsx
            ├── QuickNoteCard.tsx
            ├── HabitTrackerCard.tsx
            ├── BookmarksCard.tsx
            ├── JournalStreakCard.tsx
            └── WordsThisWeekCard.tsx

Data shapes

type View = 'today' | 'work' | 'pages' | 'journal'
          | 'tasks' | 'bookmarks' | 'archive'

interface Task {
  id: string; text: string; done: boolean; tag: string
  status?: 'todo' | 'in-progress' | 'in-review' | 'done'
  priority?: 'high' | 'medium' | 'low'
  emoji?: string; dueDate?: string
}

interface Habit    { name: string; color: 'orange' | 'blue'; days: boolean[] }
interface Bookmark { id: string; title: string; url: string; initial: string; color: string; bg: string; createdAt?: number }
interface Page     { id: string; title: string; content: string; blocks?: Block[] }
type JournalEntries = Record<string, JournalEntry>   // key: YYYY-MM-DD

localStorage keys

Key Shape
cove-tasks Task[]
cove-pages Page[]
cove-journal JournalEntries
cove-habits Habit[]
cove-bookmarks Bookmark[]
cove-note string
cove-dark boolean

Design system

Token Value
Accent #fb5607 (orange) — all interactive state
Secondary #3b82f6 (blue) — habit dots + heatmap
Background #ffffff light / #1a1a1a dark
Border #e7e5e4 light / #333333 dark
Text — primary #1c1c1c light / #e5e5e5 dark
Sans Inter, negative tracking on headings
Mono DM Mono, positive tracking on labels/timestamps
Radii 12px cards, 5px checkboxes, 4px chips
Card padding 22px 22px 20px
Card shadow 1px stone border + a barely-there drop shadow

Voice and tone: warm, direct, quietly personal. "Good morning." not "Hey there! Ready to crush it?"

Run locally

npm install
npm run dev        # http://localhost:5173
npm test           # vitest
npm run build      # tsc && vite build → dist/
npm run preview    # serve dist locally
npm run deploy     # gh-pages -d dist  (re-publishes to GitHub Pages)

Keyboard

Key Action
⌘K / Ctrl K Open command palette
⌘S / Ctrl S Save current journal entry
Esc Close palette / overlay sidebar
↑ ↓ ↩ Navigate + commit palette result

Credits

Originally seeded from the NotionOS static template by Terabint, then rebuilt from scratch into a real app. Design system generated with Moonchild and refined by hand.

License

MIT.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors