Skip to content

phrazzld/vanity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vanity

CI TypeScript Next.js License Conventional Commits

A personal website built with Next.js, featuring a collection of readings, travel map, and quotes with a minimalist design aesthetic. Content is managed through markdown files and a custom CLI tool, emphasizing simplicity, type safety, and accessibility.

Table of Contents

Features

  • Readings Collection: Showcase books and readings with cover images, organized by year with audiobook indicators and simplified reading/finished status
  • Travel Map: Interactive map using Leaflet to display travel locations with custom markers and popups
  • Quote Display: Animated typewriter effect for displaying quotes with randomization
  • Content Management: Custom CLI tools for adding and managing readings and quotes via markdown files
  • Responsive Design: Optimized for all device sizes using Tailwind's responsive utilities
  • Dark Mode: Fully implemented dark mode support with theme persistence
  • Accessibility: WCAG 2.1 AA compliant with keyboard navigation, semantic HTML, and ARIA attributes
  • State Management: Zustand for UI state, native fetch for data loading
  • Type Safety: Strict TypeScript throughout with comprehensive type definitions

Tech Stack

Frontend

  • Framework: Next.js 15 with App Router
  • Language: TypeScript 5.4
  • Component Library: Custom React 19 components
  • Styling: Tailwind CSS with custom design tokens
  • State Management: Zustand v5 (UI state) + native fetch API
  • Maps: Leaflet/React-Leaflet v5

Content & Data

  • Content Storage: Markdown files with YAML frontmatter
  • API Routes: Next.js API Routes serving static content
  • CLI Tools: Custom TypeScript CLI for content management
  • Logging: Winston for structured JSON logging

Testing & Quality

  • Testing: Jest with React Testing Library
  • Accessibility Testing: jest-axe + eslint-plugin-jsx-a11y
  • Component Development: Storybook v8 with A11y addon
  • Linting: ESLint v9 with Next.js and TypeScript configs
  • Formatting: Prettier
  • Git Hooks: Husky + lint-staged

Getting Started

Prerequisites

  • Node.js 20+ and npm 10.9.2+
  • Git
  • Text editor (for content creation)

Installation

  1. Clone the repository

    git clone https://github.com/phrazzld/vanity.git
    cd vanity
  2. Install dependencies

    npm install
  3. Start the development server

    npm run dev

    The application will be available at http://localhost:3000.

Content Management

Content is managed through markdown files and a custom CLI tool. All content is stored in the /content/ directory.

Adding Quotes

# Add a new quote (opens your $EDITOR for quote and author)
npm run vanity -- quote add

# List recent quotes
npm run vanity -- quote list
npm run vanity -- quote list -n 20  # Show 20 quotes

Quotes are saved as /content/quotes/[ID].md with YAML frontmatter:

---
author: 'Author Name'
id: 42
---

The quote text goes here.

Adding Readings

# Add a new reading (interactive prompts)
npm run vanity -- reading add

# Update a reading (mark finished, add thoughts, delete)
npm run vanity -- reading update

# List recent readings
npm run vanity -- reading list
npm run vanity -- reading list -n 5  # Show 5 readings

Readings support:

  • Two-state system: Currently reading or finished (simplified from previous three-state system)
  • Audiobook support: Mark readings as audiobooks with 🎧 indicators in the UI
  • Cover images: URLs or local files (auto-optimized to WebP at 400x600px)
  • Status management: Easy updates via CLI to mark books as finished
  • Optional thoughts: Add personal notes via $EDITOR
  • File deletion: Remove readings entirely through update command
  • Saved as: /content/readings/[slug].md with YAML frontmatter

CLI Configuration

  • Set EDITOR environment variable for preferred editor (default: vi)
  • Example: export EDITOR=nvim

Content Structure

content/
├── quotes/
│   ├── 0001.md
│   ├── 0002.md
│   └── ...
└── readings/
    ├── book-title.md
    └── ...

public/images/readings/
└── book-title.webp  # Optimized cover images

Reading File Format

Readings are stored as markdown files with YAML frontmatter:

---
title: 'The Pragmatic Programmer'
author: 'David Thomas and Andrew Hunt'
finished: 2023-06-15T00:00:00.000Z # null for currently reading
audiobook: true # Optional, defaults to false
coverImage: '/images/readings/pragmatic-programmer.webp'
---

Optional thoughts and notes about the book go here.

Reading Status:

  • Currently Reading: finished: null
  • Finished: finished: 2023-06-15T00:00:00.000Z (ISO date string)
  • Audiobook: audiobook: true (shows 🎧 indicator in UI)

Troubleshooting

  • Build Errors: Check for TypeScript errors with npm run typecheck.
  • Missing Content: Ensure content directories exist: /content/quotes/ and /content/readings/.
  • Image Issues: Ensure cover image URLs in markdown content are valid HTTPS URLs from approved CDN domains.

Development Scripts

Core Development

  • npm run dev - Start development server with Turbopack
  • npm run dev:log - Start development server with logging to logs/dev.log
  • npm run logs - View development logs
  • npm run logs:watch - Watch development logs in real-time
  • npm run build - Build for production (includes Prisma generation)
  • npm run start - Start production server

Testing

  • npm run test - Run all tests
  • npm run test:watch - Run tests in watch mode
  • npm run test:coverage - Run tests with coverage report
  • npm run test:snapshot - Run snapshot tests only
  • npm run test:snapshot:update - Update snapshot tests

Code Quality

  • npm run lint - Run ESLint on specified files
  • npm run lint:fix - Run ESLint and automatically fix issues
  • npm run format - Format all files with Prettier
  • npm run format:check - Check formatting without making changes
  • npm run typecheck - Run TypeScript type checking
  • npm run security:audit - Run npm audit for high and critical vulnerabilities
  • npm run security:scan - Run security scan with allowlist filtering

Content Management

  • npm run vanity -- quote add - Add new quote interactively
  • npm run vanity -- quote list - List recent quotes (with optional count: -n 20)
  • npm run vanity -- reading add - Add new reading interactively (includes audiobook prompt)
  • npm run vanity -- reading update - Update reading status, add thoughts, or delete reading
  • npm run vanity -- reading list - List recent readings (with optional count: -n 5)
  • npm run reading-summary - Generate reading summary report

Storybook

  • npm run storybook - Start Storybook dev server
  • npm run build-storybook - Build Storybook
  • npm run test-storybook - Run Storybook tests

Release

  • npm run release - Generate new version based on conventional commits
  • npm run release:patch - Generate a new patch version (0.0.x)
  • npm run release:minor - Generate a new minor version (0.x.0)
  • npm run release:major - Generate a new major version (x.0.0)
  • npm run release:dry-run - Preview what the next version would look like

Project Structure

/
├── cli/                     # Custom CLI tools for content management
├── content/                 # Markdown content files
│   ├── quotes/              # Quote markdown files (auto-numbered)
│   └── readings/            # Reading markdown files (slug-based)
├── public/                  # Static assets
│   ├── images/              # Project and reading cover images
│   └── ...                  # Other static files
├── scripts/                 # Utility scripts and build tools
├── src/
│   ├── app/                 # Next.js App Router
│   │   ├── api/             # API routes (serve static content)
│   │   ├── components/      # React components
│   │   │   ├── keyboard/    # Keyboard navigation components
│   │   │   ├── quotes/      # Quote-related components
│   │   │   └── readings/    # Reading-related components
│   │   ├── contexts/        # React contexts
│   │   ├── hooks/           # Custom React hooks
│   │   └── utils/           # Utility functions
│   ├── lib/                 # Core library code
│   │   ├── api/             # API client functions
│   │   └── data.ts          # Markdown file parsing
│   ├── store/               # Zustand store definitions
│   └── types/               # TypeScript type definitions
├── docs/                    # Documentation files
├── .env.example             # No environment variables needed
├── next.config.ts           # Next.js configuration
├── tailwind.config.ts       # Tailwind CSS configuration
└── tsconfig.json            # TypeScript configuration

Key Files

Development Philosophy

This project follows a set of core principles to ensure maintainable, secure, and high-quality code:

Core Principles

  1. Simplicity First: Resist unnecessary complexity and over-engineering
  2. Modularity is Mandatory: Small, focused components with clear responsibilities
  3. Testability by Design: Code structured for comprehensive testing
  4. Explicit Intent: Clear, readable code with explicit dependencies
  5. Secure by Default: Security integrated into the development process
  6. Automate Everything: Extensive automation for consistency and efficiency

For detailed information, see DEVELOPMENT_PHILOSOPHY.md.

Code Style

  • Strict TypeScript with explicit types and minimal use of any
  • Feature-focused organization rather than technical layers
  • Functional components with explicit return types
  • Detailed JSDoc comments for components and functions
  • Consistent naming conventions (PascalCase for components, camelCase for utilities)

Accessibility

This project is committed to WCAG 2.1 AA compliance, ensuring the application is usable by people with various disabilities:

Key Accessibility Features

  • Semantic HTML structure with appropriate ARIA attributes
  • Keyboard navigation support throughout the application (Tab, Shift+Tab, Enter, Space)
  • Color contrast ratios that meet WCAG standards in both light and dark themes
  • Focus management for modals and interactive elements
  • Screen reader compatibility with descriptive alt text and labels
  • Accessible hover interactions with keyboard focus equivalence (audiobook indicators)

Keyboard Navigation

The project includes comprehensive keyboard navigation utilities:

  • Focus trapping for modals and dialogs
  • Arrow key navigation within components
  • Skip links to bypass navigation elements
  • Focus management and restoration

For more details, see KEYBOARD_NAVIGATION.md and ACCESSIBILITY.md.

State Management

The project uses a hybrid approach to state management:

  • Server State: Native fetch API for loading static markdown data
  • UI State: Zustand for simple, lightweight global state management
  • Local State: React's useState and useReducer for component-specific state

This approach separates concerns and provides optimal solutions for different types of state. For details, see STATE_MANAGEMENT.md.

Testing Strategy

The project follows a comprehensive testing approach:

  • Unit Tests: For utility functions and isolated logic
  • Component Tests: Using React Testing Library with user-centric approach
  • Integration Tests: For API routes and data flow
  • Accessibility Tests: Using jest-axe for automated accessibility checks
  • Snapshot Tests: For UI regression testing

Guidelines:

  • Test behavior, not implementation
  • Mock external dependencies only (not internal collaborators)
  • Focus on user interactions rather than implementation details

Git Workflow

Branch Naming Conventions

  • Main branches: main or master
  • Feature branches: feature/feature-name
  • Bug fix branches: fix/bug-description
  • Documentation branches: docs/what-was-documented
  • Refactoring branches: refactor/what-was-refactored
  • Release branches: release/vX.Y.Z (semantic versioning)
  • Development branches: dev or develop
  • Planning branches: plan/plan-description

Git Hooks

  • Pre-commit Hooks: Lint, format, typecheck, and detect sensitive data
  • Post-commit Hooks: Generate documentation
  • Pre-push Hooks: Run tests and enforce branch naming conventions

Versioning

This project uses semantic versioning based on Conventional Commits:

  • Patch Version (0.0.x): Automatically incremented for fix: commits
  • Minor Version (0.x.0): Automatically incremented for feat: commits
  • Major Version (x.0.0): Automatically incremented for commits with BREAKING CHANGE: or feat!:

The versioning system is managed by standard-version, which:

  1. Increments the version in package.json based on commit types
  2. Generates/updates the CHANGELOG.md file
  3. Creates a git tag for the new version

Continuous Integration

This project uses GitHub Actions for continuous integration:

  • Lint: Ensures code adheres to project standards
  • Type Check: Verifies TypeScript type correctness
  • Test: Runs the full test suite
  • Build: Verifies the project builds successfully
  • Storybook: Builds Storybook to ensure component documentation is valid
  • Security Scan: Checks for high and critical security vulnerabilities in dependencies with allowlist support

CI runs on each push to main and on pull requests. Check the .github/workflows directory for details.

Documentation

Project Documentation

Automatically Generated Documentation

The project automatically generates technical overviews of code directories.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

whadup

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •