Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

295 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Personal Budget App

Vue Ionic Capacitor TypeScript Supabase Pinia Vite Vitest pnpm

A cross-platform personal expense and budget tracking mobile application built with Vue 3, Ionic Framework 8, Capacitor 8, and Supabase.

Designed for mobile devices (Android & iOS) as well as the web, featuring clean hexagonal architecture, native gestures, customizable spending categories, and period-based reporting.


Table of Contents


Features

  • πŸ’³ Transaction Tracking: Log daily expenses with amount, title, date, and category. Quick overview of total expenses on the main dashboard.
  • πŸ“‚ Expense Categories: Group spending by pre-defined categories with intuitive iconography (Food, Housing, Transportation, Health, Shopping, Entertainment, Education, Pets, Utilities, etc.).
  • πŸ“Š Period Reports & Analytics: Filter expenses across time horizons (Today, Week, Month, Year, Custom Range) with per-category totals and visual spending distributions.
  • πŸ“± Native Mobile Gestures:
    • Pull-to-refresh on transaction feeds.
    • Swipe/slide gestures on list items to edit or delete transactions.
    • Native haptics and keyboard handling via Capacitor plugins.
  • πŸ”” Programmatic Toast Feedback: Clean toast notifications for user actions via the reusable useToast composable.
  • 🎨 Design System v2: Modern visual design using semantic CSS variables and design tokens (--ds-*).

Architecture & Design

The application follows modular and decoupled design principles:

Domain-Storage Seam (Hexagonal Architecture)

Pinia setup stores (transactionStore, categoryStore, reportStore) interact with persistent storage solely through an abstract port interface: BudgetStorage (src/core/storage/types.ts).

  • Production Adapter (SupabaseStorage): Uses @supabase/supabase-js to communicate with Supabase PostgREST endpoints. Encapsulates lazy environment variable validation, camelCase ↔ snake_case mapping, and error normalization.
  • Testing / Mock Adapter (InMemoryStorage): Fast, in-memory implementation seeded with test fixtures. Enables 100% deterministic unit testing without network mocks or Supabase credentials.

For details, refer to ADR 0001: Domain Storage Seam.

Feature Modules

Code is organized by vertical feature modules under src/modules/<feature>/:

  • transactions: Dashboard view, transaction lists, add transaction form, update modal, slide list items, and transaction store.
  • categories: Category selection grid and category store.
  • reports: Spending breakdown by category, period filter bar, report headers, and report store.

Shared utilities, components (BaseHeader, BaseRefresher), composables (useToast), and storage ports reside in src/core/.


Tech Stack

Layer Technologies
Frontend Framework Vue 3 (Composition API, <script setup>)
Mobile UI & Components Ionic Framework 8 (@ionic/vue, @ionic/vue-router, Ionicons 8)
Mobile Runtime Capacitor 8 (Android & iOS runtime, @capacitor/app, @capacitor/haptics, @capacitor/keyboard, @capacitor/status-bar)
State Management Pinia 4
Backend & Database Supabase (PostgreSQL, PostgREST API)
Date & Time Day.js
Build Tool Vite 8 with tree-shaking & vendor chunk splitting
Testing Vitest 5, @vue/test-utils 2, jsdom
Code Quality TypeScript 5.9, ESLint 9 (Flat Config), Prettier (@ionic/prettier-config), Husky, lint-staged
Package Manager pnpm 11 (Node.js 24)

Project Structure

β”œβ”€β”€ android/                   # Capacitor Android native project
β”œβ”€β”€ ios/                       # Capacitor iOS native project
β”œβ”€β”€ docs/                      # Project documentation, design specs, and ADRs
β”‚   β”œβ”€β”€ adr/                   # Architecture Decision Records
β”‚   β”œβ”€β”€ design/                # Design templates and screen specifications
β”‚   β”œβ”€β”€ design-system.md       # Design system v2 token and component guidelines
β”‚   └── features/              # Feature-specific architectural docs
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ assets/
β”‚   β”‚   β”œβ”€β”€ icons/             # Category PNG icons
β”‚   β”‚   └── theme/             # Design tokens (--ds-*) & Ionic variable mappings
β”‚   β”œβ”€β”€ core/                  # Shared core domain & infrastructure
β”‚   β”‚   β”œβ”€β”€ components/        # BaseHeader, BaseRefresher
β”‚   β”‚   β”œβ”€β”€ composables/       # useToast and programmatic controllers
β”‚   β”‚   β”œβ”€β”€ storage/           # BudgetStorage port, Supabase & InMemory adapters
β”‚   β”‚   └── utils/             # Amount formatting, date intervals, category icons
β”‚   β”œβ”€β”€ modules/               # Feature-based domain modules
β”‚   β”‚   β”œβ”€β”€ categories/        # Category components, types & store
β”‚   β”‚   β”œβ”€β”€ reports/           # Report views, period filters, types & store
β”‚   β”‚   └── transactions/      # Transaction views, forms, modals & store
β”‚   β”œβ”€β”€ views/                 # Root tab layout (TabsPage.vue)
β”‚   β”œβ”€β”€ App.vue                # Root application component
β”‚   β”œβ”€β”€ main.ts                # App entrypoint (Ionic & Pinia bootstrapping)
β”‚   └── router.ts              # Route declarations & lazy-loaded tabs
β”œβ”€β”€ supabase/                  # Supabase local config & schema snippets
β”œβ”€β”€ capacitor.config.ts        # Capacitor configuration
β”œβ”€β”€ vite.config.ts             # Vite build & chunking configuration
β”œβ”€β”€ AGENT.md                   # Agentic workflow & coding assistant guidelines
└── GLOSSARY.md                # Domain terminology and ubiquitous language

Prerequisites

  • Node.js: ^24.x (managed via .nvmrc)
  • pnpm: ^11.x
  • Android Studio (optional, for Android native testing/building)
  • Supabase Account / Project (for backend database storage)

Getting Started

1. Clone the repository

git clone https://github.com/AndreiDetenkov/vue3-ionic-budget-app.git
cd vue3-ionic-budget-app

2. Install dependencies

pnpm install

3. Configure environment variables

Copy the example environment file and provide your Supabase project credentials:

cp .env.dist .env

Edit .env:

VITE_SUPABASE_URL=https://your-supabase-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=your-supabase-anon-or-publishable-key

Note: In development or test environments without Supabase credentials, unit tests run seamlessly using InMemoryStorage.

4. Run the development server

pnpm dev

Open http://localhost:5173 in your browser. Use mobile device emulation in browser DevTools for the best experience.


Mobile Development (Capacitor)

The mobile workflow uses Capacitor to package the Vite web application into the native Android project.

Android

  1. Build web assets:
    pnpm build
  2. Sync web bundle with the Android project:
    pnpm sync
  3. Open project in Android Studio:
    pnpm open
  4. Run on an Android emulator or connected device with live reload:
    pnpm run:android

Available Scripts

Command Description
pnpm dev Starts the Vite development server with HMR
pnpm build Compiles production web bundle into dist/
pnpm preview Locally previews production build
pnpm test:unit Starts Vitest in watch mode
pnpm test:unit run Runs Vitest test suite once
pnpm typecheck Type-checks code with vue-tsc -b --noEmit
pnpm lint Runs ESLint with auto-fix on src/
pnpm format Formats source files using Prettier
pnpm sync Runs ionic capacitor sync android
pnpm open Opens Android Studio for the native Android project
pnpm run:android Runs on Android emulator with live reload
pnpm release Creates a release via changelogen (version bump, changelog, git tag)

Testing & Quality Assurance

Unit Tests

Unit tests are written using Vitest and @vue/test-utils, residing next to the source code (*.spec.ts):

# Run all unit tests once
pnpm test:unit run

# Run a specific test file
pnpm test:unit src/modules/transactions/store/transactionStore.spec.ts

# Filter tests by name
pnpm test:unit -t "calculates total"

Type Checking & Linting

# Typecheck
pnpm typecheck

# Lint with ESLint
pnpm lint

# Format with Prettier
pnpm format

Pre-commit hooks are configured via Husky and lint-staged to automatically lint, format, and typecheck staged files prior to each commit.


Database & Supabase Integration

The PostgreSQL database contains two primary tables:

  1. categories:
    • id (uuid, primary key)
    • title (text)
    • icon (text, nullable)
  2. transactions:
    • id (uuid, primary key)
    • name (text, transaction description/title)
    • value (numeric, expense amount)
    • category_id (uuid, foreign key referencing categories.id)
    • created_at (timestamptz)

TypeScript definitions for database tables are generated using the Supabase CLI in src/core/storage/database.types.ts:

npx supabase gen types typescript --project-id <your-project-id> > src/core/storage/database.types.ts

Documentation & ADRs

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages