
Journal Application

Nikola Filipovski
Full-Stack Web Developer
Overview
Journal is a personal blog platform where the author can write, manage, and publish journal entries. The public side is designed to feel like a literary magazine, refined, readable, intentional. The admin side is a fully custom CMS built specifically for long-form writing.
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Next.js (App Router) |
| Language | TypeScript |
| Styling | Tailwind CSS + CSS custom properties |
| Database | PostgreSQL |
| ORM | Drizzle ORM |
| Authentication | Session-based auth |
| Media Storage | Cloudinary |
| Hosting | Vercel |
Design System
The visual identity is built around an editorial dark theme, the kind you'd find in a literary journal or independent publication.
- Typography: Playfair Display for headings, Source Serif 4 for body text, both chosen for their literary character
- Color palette:
#0f0f0fdeep black background#7eb8d4steel blue headings#c0504adark red links
- Design tokens defined as CSS custom properties and extended into Tailwind - no magic numbers scattered through the codebase
- Fully responsive, accessible - skip links, ARIA attributes, keyboard navigation throughout
Public Blog
The reader-facing side of the application:
- Homepage with a featured latest entry, recent posts, a monthly mood indicator, and a daily rotating quote pulled from an external API
- Blog listing - all published entries, newest first
- Individual post pages - full typography treatment with drop cap first letter, prev/next navigation between entries
- Search - full-text search across titles, excerpts, content and tags, with a live dropdown in the header (debounced, keyboard navigable)
- 404 and error pages - written in the same voice as the rest of the blog, with graceful fallbacks
Admin CMS
A completely custom content management system accessible only to the author:
- Post listing - table view of all posts including drafts, with edit and live preview links
- Post editor - the centerpiece of the admin panel; a full markdown editor with three view modes: Write, Split (side-by-side live preview), and Preview
- Rich toolbar - text formatting (bold, italic, headings, blockquote, links) and media insertion (image, video, audio)
- Media uploads - drag and drop or file picker for images, video, and audio stored on Cloudinary, with caption support
- Voice recording - record audio directly in the browser via the MediaRecorder API, with live timer and playback before inserting
- Draft/Published toggle, word count, reading time estimate, auto-generated URL slugs
- Mood tracker - the author logs a daily mood note from the admin panel; entries are viewable by month with a full monthly breakdown, and the dominant mood for the current month is surfaced on the public homepage
Authentication
Secure, authentication system:
- Email and password login with session management
- Sessions expire automatically and refresh on activity
- Password management available from the admin panel
- All admin routes fully protected, unauthenticated requests never reach any page or API endpoint
Database
PostgreSQL with Drizzle ORM, with a schema designed around clear relationships:
- Posts with full metadata, slug, excerpt, content, tags, reading time, published status, and author
- Mood entries linked to dates and months, with notes written by the author
- Auth tables for secure session and account management
- All database operations centralized in a typed query layer
- Drizzle Studio available locally for direct database inspection
Media
All images, videos, and audio files are stored on Cloudinary - uploads go through the admin editor, are validated by type and size, and served via Cloudinary's CDN with automatic optimization. The free tier covers the storage and bandwidth needs of a personal blog comfortably.
API Layer
A set of internal REST endpoints that back the admin CMS and public features:
- Post creation, update, and deletion
- File upload handler integrated with Cloudinary
- Search endpoint powering the live header dropdown
- All authentication flows handled server-side
Hosting
The application is hosted on Vercel on the free tier. PostgreSQL is hosted on a managed cloud provider connected to Vercel via environment variables. Deployments are automatic on every push to the main branch. The free tier comfortably handles the traffic of a personal blog with no cold start issues thanks to Next.js edge runtime.
Documentation
The project includes full user documentation covering:
- Writing guide - how to use the editor, markdown syntax, inserting media, saving drafts vs publishing
- Mood tracker guide - how to log daily moods, add notes, and read the monthly breakdown
- Maintenance guide - how to update dependencies, run database migrations, and monitor the application
- Deployment guide - environment variables, Vercel configuration, Cloudinary setup
- Extension guide - the codebase is structured to make adding new features straightforward; new pages, API routes, and database tables follow consistent patterns throughout
Other Details
- PWA manifest - theme color, icons, and display mode configured for a native-app feel when added to a phone home screen
- Daily quote - external API fetch with time-based revalidation, refreshes automatically without redeployment
- Open Graph and Twitter Card metadata on all public pages for clean social sharing
- Search engine directives configured per page - admin and error pages excluded from indexing
Visit the Journal app and see how a modern personal blog looks, featuring powerful search and a carefully crafted user experience: View the Journal App