A personal fitness tracking app with a galactic reward system. Every completed workout week births a new star, every month adds a new planet to your growing galaxy.
Built with React, TypeScript, Tailwind CSS, and Supabase.
- Workout Planning β Create and edit workout plans with exercises, sets, and reps
- Exercise Library β Browse 27 default exercises across 7 categories with personal record tracking
- Templates β Save workout plans as reusable templates
- Galaxy Visualization β Watch your galaxy grow with every completed week and month
- Reports β Weekly/monthly charts, top exercises, PR graphs, and body weight tracking
- Goals β Set monthly workout targets with progress tracking
- Year-End Summary β Export your annual stats as PNG or JSON
- Quick Copy β Instantly copy past workouts to today's schedule
- Streak Tracking β Keep your training momentum alive
| Layer | Technology |
|---|---|
| Framework | React 18 + TypeScript |
| Styling | Tailwind CSS |
| Backend | Supabase (PostgreSQL) |
| Charts | Recharts |
| Icons | Lucide React |
| Export | html2canvas |
git clone https://github.com/your-username/pulsar.git
cd pulsarnpm installCreate a free project at supabase.com and run the following SQL in the SQL Editor:
create table exercises (
id uuid default gen_random_uuid() primary key,
name text not null,
category text not null,
is_default boolean default true,
created_at timestamptz default now()
);
create table workouts (
id uuid default gen_random_uuid() primary key,
title text not null,
type text not null,
date date not null,
week_number int not null,
year int not null,
duration_minutes int,
notes text,
completed boolean default false,
copied_from uuid references workouts(id),
created_at timestamptz default now()
);
create table workout_exercises (
id uuid default gen_random_uuid() primary key,
workout_id uuid references workouts(id) on delete cascade,
exercise_id uuid references exercises(id),
sets int,
reps int,
duration_seconds int,
notes text,
order_index int default 0
);
create table templates (
id uuid default gen_random_uuid() primary key,
name text not null,
type text not null,
exercises jsonb default '[]',
created_at timestamptz default now()
);
create table body_weight (
id uuid default gen_random_uuid() primary key,
weight_kg numeric not null,
date date not null,
created_at timestamptz default now()
);
create table goals (
id uuid default gen_random_uuid() primary key,
month int not null,
year int not null,
target_workout_count int not null,
created_at timestamptz default now()
);Then enable Row Level Security with open policies (single-user app):
do $$
declare
t text;
begin
foreach t in array array['workouts','workout_exercises','exercises','templates','body_weight','goals']
loop
execute format('alter table %I enable row level security', t);
execute format('create policy "%I_all" on %I for all using (true) with check (true)', t, t);
end loop;
end $$;Create a .env file in the project root:
REACT_APP_SUPABASE_URL=https://your-project-id.supabase.co
REACT_APP_SUPABASE_ANON_KEY=your-anon-keynpm startOpen https://pulsar-smoky.vercel.app in your browser.
src/
βββ components/
β βββ layout/
β β βββ BottomNav.tsx # Mobile bottom navigation
β β βββ Screen.tsx # Screen & Header wrappers
β βββ ui/
β β βββ index.tsx # UI primitives (Card, Button, Input...)
β β βββ StarBackground.tsx # Animated star field
β β βββ Toast.tsx # Toast notifications
β βββ workout/
β βββ ExerciseDetailModal.tsx # Exercise PR history
β βββ ExercisePickerModal.tsx # Exercise selector
β βββ ExerciseRow.tsx # Set/rep input row
β βββ TemplatePickerModal.tsx # Template selector
β βββ WorkoutCard.tsx # Workout list card
βββ lib/
β βββ AppContext.tsx # Global state (Context API)
β βββ supabase.ts # Supabase client
β βββ utils.ts # Helper functions
βββ pages/
β βββ GalaxyPage.tsx # Canvas galaxy visualization
β βββ HomePage.tsx # Dashboard & today's workouts
β βββ LibraryPage.tsx # Exercise library
β βββ ProfilePage.tsx # Goals, body weight & export
β βββ ReportsPage.tsx # Charts & statistics
β βββ WorkoutFormPage.tsx # Create/edit workout form
β βββ WorkoutPage.tsx # Workout list
βββ types/
β βββ index.ts # TypeScript interfaces
βββ App.tsx
βββ index.css # Design tokens & animations
The galaxy grows based on your training consistency:
- Star β Awarded at the end of each week where at least one workout was completed. Star size reflects workout count, brightness reflects streak length.
- Planet β Awarded at the end of each month. Planet size reflects total monthly workout count.
Click any star in the galaxy to see that week's workout details.
workouts ββ< workout_exercises >ββ exercises
templates (exercises stored as jsonb)
body_weight
goals
- PWA support (installable on mobile)
- Push notifications for workout reminders
- Multi-user support with Supabase Auth
- Dark/light theme toggle
- Apple Health / Google Fit integration