Owner View
๐จ
Ceramic: 12 slots open this week โ critical
At 0%. Every open slot is lost revenue.
โ Today's Focus for Kaitlin
โMobile this week: 24 slots open โ text reactivation leads with specific times
โMobile next week: 36 slots unbooked โ start filling now
โCeramic this week: 12 slots open โ call warm pipeline leads
โCeramic next week: 12 slots unbooked
๐ Mobile Detailing
This Week
33
%
CRITICAL
12 bkd ยท 24 open
Next Week
0
%
CRITICAL
0 bkd ยท 36 open
๐ Ceramic Coating
This Week
0
%
CRITICAL
0 bkd ยท 12 open
Next Week
0
%
CRITICAL
0 bkd ยท 12 open
Leads Today
0
inbound today
Converted
0
Did Not Convert
0
Upsell Win Rate
0%
0/6
๐ด In Our Control
None logged today
๐ก Out of Our Control
None logged today
Capacity โ This Week & Next Week
๐ Mobile Detailing
This Week
33
%
CRITICAL
12 booked ยท 24 open ยท 36 total
12
/36
Next Week
0
%
CRITICAL
0 booked ยท 36 open ยท 36 total
0
/36
๐ Ceramic Coating
This Week
0
%
CRITICAL
0 booked ยท 12 open ยท 12 total
0
/12
Next Week
0
%
CRITICAL
0 booked ยท 12 open ยท 12 total
0
/12
Per Van โ This Week
Van 10/30%
Van 20/30%
Lead Tracking
0
Leads Today
0
Converted
0
Did Not Convert
๐ด In Our Control โ Sales Training Opportunity
None logged today
Total0
๐ก Out of Our Control
None logged today
Total0
Week to Date
Total Leads
0
Converted
0
Conversion Rate
โ
Follow-Up Queue
0
Upsell Tracking
0%
WIN RATE
๐ Mobile Upsells โ Today
Offered
6
Closed
0
โ
WIN RATE
๐ Ceramic Upsells โ Today
Offered
0
Closed
0
๐ Mobile โ By Service
ServiceOffCls%
Air purification / odor removal00โ
Steam clean / shampoo / stain removal600%
Pet hair removal00โ
Leather conditioner00โ
Headlight restoration00โ
Polishing / scratch removal00โ
Ceramic sealant00โ
๐ Ceramic โ By Service
ServiceOffCls%
Air purification / odor removal00โ
Steam clean / shampoo / stain removal00โ
Pet hair removal00โ
Leather conditioner00โ
Headlight restoration00โ
Polishing / scratch removal00โ
Ceramic sealant00โ
Historical Data โ Week Over Week
Capacity Trend โ Last 8 Weeks
Upsell Win Rate โ Last 8 Weeks
Weekly Log
No history yet โ data saves to Google Sheets when you hit Save EOD Report.
Connect Google Sheets in the โ Setup tab to enable history.
Connect Google Sheets in the โ Setup tab to enable history.
Kaitlin's End-of-Day Report
Fill this out before you close for the day
Auto-saves locally as you type. Hits Google Sheets when you click Save โ that's what builds your history.
๐ Fleet Settings โ only change when vans change
Mobile cap/week: 36 slots
Ceramic cap/week: 12 slots
๐ฏ Capacity
This Week
Next Week
Per Van (optional)
๐ Leads โ Today
๐ด In Our Control
๐ก Out of Our Control
โฌ Upsells โ Today
๐ On Mobile Detail Jobs
| Service | Offered | Closed |
|---|---|---|
| Air purification / odor removal | ||
| Steam clean / shampoo / stain removal | ||
| Pet hair removal | ||
| Leather conditioner | ||
| Headlight restoration | ||
| Polishing / scratch removal | ||
| Ceramic sealant |
๐ On Ceramic Coating Jobs
| Service | Offered | Closed |
|---|---|---|
| Air purification / odor removal | ||
| Steam clean / shampoo / stain removal | ||
| Pet hair removal | ||
| Leather conditioner | ||
| Headlight restoration | ||
| Polishing / scratch removal | ||
| Ceramic sealant |
๐ฌ Kaitlin's Note to Dalton
Last saved: โ
โ Google Sheets Setup
Connect this dashboard to Google Sheets
Do this once โ takes about 10 minutes. After setup, every time Kaitlin hits Save, the data writes to your Sheet automatically and builds your history.
1
Create a new Google Sheet
Go to sheets.google.com, click the + to create a new blank spreadsheet. Name it "AMD Dashboard Data".
2
Open the Script Editor
In your Sheet, click Extensions โ Apps Script. Delete any existing code in the editor.
3
Paste the AMD script
Copy the entire code block below and paste it into the Script Editor, then click Save (the floppy disk icon).
// AMD Dashboard โ Google Apps Script
// Paste into Extensions > Apps Script, then Deploy > New Deployment > Web App
// Execute as: Me | Who has access: Anyone
const SHEET_NAME='Weekly Log';
function doPost(e){
try{
const data=JSON.parse(e.postData.contents);
const ss=SpreadsheetApp.getActiveSpreadsheet();
let sheet=ss.getSheetByName(SHEET_NAME);
if(!sheet){
sheet=ss.insertSheet(SHEET_NAME);
sheet.getRange(1,1,1,35).setValues([['Week Of','Saved At','Mobile Booked TW','Mobile Open TW','Mobile Cap% TW','Mobile Booked NW','Mobile Open NW','Mobile Cap% NW','Ceramic Booked TW','Ceramic Open TW','Ceramic Cap% TW','Ceramic Booked NW','Ceramic Open NW','Ceramic Cap% NW','Mobile Total Slots','Ceramic Total Slots','Leads Today','Converted','Did Not Convert','Conv Rate%','Week Leads','Week Converted','Week Conv Rate%','Follow-Up Queue','In-Control Objections','Out-of-Control Objections','Mob Ups Offered','Mob Ups Closed','Mob Win Rate%','Cer Ups Offered','Cer Ups Closed','Cer Win Rate%','Total Win Rate%',"Kaitlin's Note",'Priority']]);
sheet.getRange(1,1,1,35).setFontWeight('bold');
sheet.setFrozenRows(1);
}
const weekOf=data.weekOf;
const allData=sheet.getDataRange().getValues();
let rowIdx=-1;
for(let i=1;i<allData.length;i++){if(allData[i][0]===weekOf){rowIdx=i+1;break;}}
const row=[weekOf,new Date().toLocaleString(),data.mw||0,data.mo||0,data.mPct||0,data.nmw||0,data.nmo||0,data.nmPct||0,data.cw||0,data.co||0,data.cPct||0,data.ncw||0,data.nco||0,data.ncPct||0,data.MC||0,data.CC||0,data.lt||0,data.lb||0,data.ln||0,data.convRate||0,data.wl||0,data.wb||0,data.wConvRate||0,data.fu||0,(data.ic||[]).join(', '),(data.oc||[]).join(', '),data.mOff||0,data.mCls||0,data.mWR||0,data.cOff||0,data.cCls||0,data.cWR||0,data.totalWR||0,data.note||'',data.pri||''];
if(rowIdx>0){sheet.getRange(rowIdx,1,1,row.length).setValues([row]);}
else{sheet.appendRow(row);}
sheet.autoResizeColumns(1,row.length);
return ContentService.createTextOutput(JSON.stringify({success:true,weekOf})).setMimeType(ContentService.MimeType.JSON);
}catch(err){
return ContentService.createTextOutput(JSON.stringify({success:false,error:err.toString()})).setMimeType(ContentService.MimeType.JSON);
}
}
function doGet(e){
try{
const ss=SpreadsheetApp.getActiveSpreadsheet();
const sheet=ss.getSheetByName(SHEET_NAME);
if(!sheet)return ContentService.createTextOutput(JSON.stringify({rows:[]})).setMimeType(ContentService.MimeType.JSON);
const data=sheet.getDataRange().getValues();
const headers=data[0];
const rows=data.slice(1).map(row=>{const obj={};headers.forEach((h,i)=>obj[h]=row[i]);return obj;}).filter(r=>r['Week Of']);
return ContentService.createTextOutput(JSON.stringify({rows})).setMimeType(ContentService.MimeType.JSON);
}catch(err){
return ContentService.createTextOutput(JSON.stringify({error:err.toString(),rows:[]})).setMimeType(ContentService.MimeType.JSON);
}
}
4
Deploy as a Web App
In the Script Editor, click Deploy โ New Deployment.
โข Type: Web app
โข Execute as: Me
โข Who has access: Anyone
Click Deploy, authorize the permissions, then copy the Web App URL.
โข Type: Web app
โข Execute as: Me
โข Who has access: Anyone
Click Deploy, authorize the permissions, then copy the Web App URL.
5
Paste your Web App URL here
Paste the URL from step 4 below. It should look like:
https://script.google.com/macros/s/ABC123.../exec