Workout
Daily Check-in
Select Date
Date
Body Metrics
Body Weight
in kilograms
Waist
in centimeters
Wellbeing
Energy Level
1 = drained, 10 = great
Back Pain
0 = none, 10 = severe
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:
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
5. Copy the Client ID and paste below
Each user who signs in gets their own sheet tabs created automatically:
Name ā Workout TrackerName ā Progress TrackerName ā MAX StrengthSetup:
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); }