LiftyFifty
Your personal workout logger.
Sign in to save your progress.
Your data is stored in the shared Google Sheet. Only your own tab is written to.
šŸ”„
Sync Now
🚪
Sign Out
Workout
Today
Daily Check-in
Select Date
Date
Body Metrics
Body Weight
in kilograms
Waist
in centimeters
Wellbeing
Energy Level
1 = drained, 10 = great
7
Back Pain
0 = none, 10 = severe
0
Dashboard
Latest Weight
—kg
Latest Waist
—cm
Avg Energy
—/10
Back Pain
—/10
Weight Trend
Max Strength
Max Strength
Settings
ā—Œ Checking connection...
Google Sign-In (SSO)
Enable per-user sign-in
Each user who signs in gets their own sheet tabs created automatically:
Name — Workout Tracker
Name — Progress Tracker
Name — MAX Strength

Setup:
1. Go to console.cloud.google.com
2. APIs & Services → Credentials → Create OAuth 2.0 Client ID
3. Application type: Web application
4. Authorised JS origins: add your site URL (or http://localhost for local)
5. Copy the Client ID and paste below
Google Sheets
Apps Script Code
Replace your existing Apps Script with this updated version that auto-creates per-user sheet tabs when someone signs in.
const SHEET_ID = '1gcIkjeOaFhtzEkAD2haHYzaUy3me8SC_i5Fl1HrwDEQ'; function doPost(e) { try { var ss = SpreadsheetApp.openById(SHEET_ID); var data = JSON.parse(e.postData.contents); // Create per-user tabs if requested if (data.action === 'ensureUserSheets') { ensureUserSheets(ss, data.user, data.email); return ok(); } // Route to correct sheet tab // If user provided, write to "UserName — Sheet Name" // Fallback to shared sheet name var sheetName = data.user ? data.user + ' — ' + data.sheet : data.sheet; var sheet = ss.getSheetByName(sheetName); if (!sheet) { // Try bare sheet name as fallback sheet = ss.getSheetByName(data.sheet); } if (!sheet) { return err('Sheet not found: ' + sheetName); } if (data.action === 'appendRow') { sheet.appendRow(data.row); } else if (data.action === 'updateCell') { sheet.getRange(data.row, data.col).setValue(data.value); } return ok(); } catch(ex) { return err(ex.toString()); } } function ensureUserSheets(ss, userName, email) { var sheetTypes = [ { name: 'Workout Tracker', headers: ['Date','Day','Exercise','Set 1','Set 2','Set 3','Set 4','REPS'] }, { name: 'Progress Tracker', headers: ['Week','Date','Body Weight (kg)','Waist (cm)','Energy (1-10)','Back Pain (1-10)'] }, { name: 'MAX Strength', headers: ['Exercise','MAX Weight'] } ]; sheetTypes.forEach(function(t) { var tabName = userName + ' — ' + t.name; var existing = ss.getSheetByName(tabName); if (!existing) { var newSheet = ss.insertSheet(tabName); newSheet.appendRow(t.headers); newSheet.getRange(1, 1, 1, t.headers.length) .setFontWeight('bold') .setBackground('#1a1a2e') .setFontColor('#ffffff'); newSheet.setFrozenRows(1); // Add user info in a note on A1 newSheet.getRange('A1').setNote('User: ' + userName + '\nEmail: ' + email + '\nCreated: ' + new Date().toISOString()); } }); } function ok() { return ContentService.createTextOutput(JSON.stringify({ok:true})).setMimeType(ContentService.MimeType.JSON); } function err(m){ return ContentService.createTextOutput(JSON.stringify({ok:false,error:m})).setMimeType(ContentService.MimeType.JSON); }