Personal finance made simple. Track income, expenses, wallets, budgets and savings goals in one clean, secure app.
ActivityPlus is a lightweight, framework-free web app for managing personal money. It supports multiple currencies, multiple wallets, monthly budgets and savings goals, and gives you clear analytics and a downloadable PDF report. Data is stored per user in Supabase and protected with authentication.
| Area | What you get |
|---|---|
| Dashboard | Balance, income, expenses and savings at a glance, with recent activity |
| Transactions | Income, Expense, Transfer and Exchange (convert between currencies with a rate); search and filter |
| Wallets | Personal and Business wallets, each with a full name and live balance |
| Budgets | Per-category budgets with spending progress |
| Savings Goals | Create goals, deposit and withdraw. Stored in their own database tables (activityplus_goals, activityplus_savings_tx) |
| Analytics | Spending by category and income vs. expense summaries |
| Multi-currency | US Dollar (USD), SL Shilling (SLSH), ET Birr (ETB) |
| Reports & Backup | PDF report, CSV export, JSON backup and restore |
| Security | Email/password login, plus PIN and password confirmation before deleting or resetting data |
| Experience | Responsive layout (desktop, tablet, mobile), dark mode, a thin loading bar (the screen is never blocked) |
- Frontend: HTML, CSS and vanilla JavaScript (no framework, no build step)
- Backend: Supabase (PostgreSQL + Auth)
- PDF: jsPDF and jsPDF-AutoTable
- Icons & font: Phosphor Icons, Plus Jakarta Sans
- Hosting: Vercel (any static host works)
ActivityPlus-main/
├── index.html # App markup (login, dashboard, modals)
├── style.css # Design system, responsive layout, dark mode
├── script.js # App logic, Supabase auth + data, PDF report
├── assets/ # Logo, favicons, app icons
├── database/ # savings.sql (savings tables, already applied)
└── README.md
No build step is needed. Serve the folder with any static server:
# Python
python3 -m http.server 8080
# or Node
npx serve .Then open http://localhost:8080.
-
Create a project at supabase.com.
-
In
script.js, set your own values:const SUPABASE_URL = "https://YOUR-PROJECT.supabase.co"; const SUPABASE_KEY = "YOUR-PUBLISHABLE-KEY";
-
Create the data table and enable Row Level Security so each user can only access their own data:
create table if not exists public.activityplus_data ( user_id uuid primary key references auth.users (id) on delete cascade, data jsonb not null default '{}'::jsonb, updated_at timestamptz not null default now() ); alter table public.activityplus_data enable row level security; create policy "Users manage their own data" on public.activityplus_data for all using (auth.uid() = user_id) with check (auth.uid() = user_id);
-
In Authentication, create your user (email + password).
No SQL change is needed for wallet categories or exchanges. They are stored inside the existing
dataJSON column. Older wallets without a category are treated as Personal automatically and are upgraded the next time data is saved.
Only use the publishable (anon) key in the frontend. Never put a service-role key in client code.
- Push the project to GitHub.
- Import the repository in Vercel.
- Framework preset: Other. No build command, output directory is the project root.
- Deploy.
- Row Level Security must be enabled so users can only read and write their own row.
- Destructive actions (delete, reset) require the local PIN and the account password.
- The PIN is a convenience guard stored in the browser; real data protection comes from Supabase Auth and RLS.
- Recurring transactions
- Category management
- Charts export
- Installable PWA (offline support)
All rights reserved. Contact the author before reusing or redistributing.