Urban Texture
Hair Studio — Staff Portal
Urban Texture
Welcome,  Not you?
0% overall complete
My logins

My accounts

Your login credentials for each system. Tap "Show" to reveal your password.

Overview

Manager dashboard

Live progress for all staff members by training section.

This view is only visible to management.
Loading...
Acknowledgment & signature

Please draw your signature below to confirm you have read and understood this document.

Sign here
Question 1 of 4 Score: 0
'; return h; } function viewPriceList() { var w = window.open('', '_blank'); if (!w) { showToast('Please allow pop-ups to view the price list in a new tab.'); return; } w.document.open(); w.document.write(buildPriceListHTML()); w.document.close(); } function renderInlineContent(docId) { var TRAINING = TRAININGS[docId]; if (!TRAINING) return; document.querySelector('.pdf-frame-wrap').style.display = 'none'; var existing = document.getElementById('inline-content-wrap'); if (existing) existing.remove(); var existingToolbar = document.getElementById('training-toolbar'); if (existingToolbar) existingToolbar.remove(); if (TRAINING.hasPriceList) { var toolbar = document.createElement('div'); toolbar.id = 'training-toolbar'; toolbar.style.cssText = 'display:flex;justify-content:flex-end;margin-bottom:12px;'; toolbar.innerHTML = ''; document.querySelector('.doc-viewer-body').insertBefore(toolbar, document.querySelector('.signature-section')); } var wrap = document.createElement('div'); wrap.id = 'inline-content-wrap'; document.querySelector('.doc-viewer-body').insertBefore(wrap, document.querySelector('.signature-section')); var state = { slide: 0, checkPassed: false, mode: 'training', scenarioIdx: 0, stepIdx: 0, scenarioDone: false }; function render() { if (state.mode === 'training') renderSlide(); else renderSimulator(); } function renderSlide() { var s = TRAINING.slides[state.slide]; var total = TRAINING.slides.length; var pct = Math.round((state.slide / total) * 100); var h = ''; h += '
'; // Progress h += '
'; h += '
'+s.eyebrow+'
'; h += '
'+state.slide+' of '+total+' complete
'; h += '
'; // Title h += '
'+s.title+'
'; if (s.body) h += '
'+s.body+'
'; // Inspo reference photos (small accent images, not full-bleed) if (s.images && s.images.length) { h += '
'; s.images.forEach(function(key){ var src2 = SERVICES_IMAGES[key]; if (!src2) return; h += '
Inspiration photo
'; }); h += '
'; } // Intro bullets if (s.type === 'intro' && s.bullets) { h += '
'; s.bullets.forEach(function(b){ h += '
'+b+'
'; }); h += '
'; } // Script box if (s.script) { h += '
'+s.script+'
'; } // Note if (s.note) h += '
'+s.note+'
'; // Example price table if (s.table) h += s.table; // Bullets list if (s.bullets && s.type !== 'intro') { s.bullets.forEach(function(b){ h += '
'+b+'
'; }); h += '
'; } // Do/Don't pairs (voice & policy reuse) if (s.pairs && s.type === 'content' && !s.steps) { h += '
'; s.pairs.forEach(function(p){ h += '
'+p.good+'
'; h += '
'+p.bad+'
'; }); h += '
'; } // Policy table (pairs where good=service, bad=fee) if (s.pairs && s.type === 'content' && s.id === 'policy') { h = h; // already handled above but we'll override in the policy section } // Mistakes if (s.mistakes) { s.mistakes.forEach(function(m){ h += '
'; h += '
Don\'t say'+m.wrong+'
'; h += '
Do say'+m.right+'
'; h += '
'; }); h += '
'; } // Steps if (s.steps) { s.steps.forEach(function(st,i){ h += '
'; h += '
'+st.n+'
'; h += '
'+st.label+'
'+st.detail+'
'; }); } h += '
'; // Knowledge check if (s.check) { h += '
'; h += '
Knowledge check
'; h += '
'+s.check.q+'
'; h += '
'; var letters = ['A','B','C','D']; s.check.options.forEach(function(opt,i){ var isCorrectOpt = i === s.check.correct; if (state.checkPassed) { var boxStyle = isCorrectOpt ? 'background:var(--success-light);border:1px solid var(--success);color:var(--success);' : 'background:var(--cream);border:1px solid var(--border);color:var(--muted);opacity:0.55;'; h += '
'; h += ''+letters[i]+''; h += ''+opt+'
'; } else { h += ''; } }); h += '
'; if (state.checkPassed) { h += '
✓ '+s.check.feedback+'
'; } else { h += ''; } h += '
'; } // Nav h += '
'; if (state.slide > 0) h += ''; else h += '
'; var isLast = state.slide === total - 1; var canNext = !s.check || state.checkPassed; if (isLast && canNext) { h += ''; } else if (canNext) { h += ''; } else { h += ''; } h += '
'; wrap.innerHTML = h; wrap.handleCheck = function(idx) { var s2 = TRAINING.slides[state.slide]; var btns = wrap.querySelectorAll('#check-opts button'); btns.forEach(function(b){ b.disabled = true; b.onmouseover = null; b.onmouseout = null; }); var isCorrect = idx === s2.check.correct; btns[idx].style.background = isCorrect ? 'var(--success-light)' : 'var(--error-light)'; btns[idx].style.borderColor = isCorrect ? 'var(--success)' : 'var(--error)'; btns[idx].style.color = isCorrect ? 'var(--success)' : 'var(--error)'; if (!isCorrect) { btns[s2.check.correct].style.background = 'var(--success-light)'; btns[s2.check.correct].style.borderColor = 'var(--success)'; btns[s2.check.correct].style.color = 'var(--success)'; } var fb = wrap.querySelector('#check-feedback'); fb.style.display = 'block'; fb.style.background = isCorrect ? 'var(--success-light)' : 'var(--error-light)'; fb.style.color = isCorrect ? 'var(--success)' : 'var(--error)'; fb.style.padding = '12px 16px'; fb.style.borderRadius = '2px'; fb.style.fontSize = '13px'; fb.style.marginTop = '12px'; fb.innerHTML = (isCorrect ? '✓ ' : '✗ Not quite — ') + s2.check.feedback + (isCorrect ? '' : ' Try again below.'); if (isCorrect) { state.checkPassed = true; } setTimeout(function(){ render(); if (isCorrect) wrap.scrollIntoView({behavior:'smooth',block:'start'}); }, isCorrect ? 900 : 1800); }; window.handleCheck = function(i){ wrap.handleCheck(i); }; window.nextSlide = function(){ state.slide++; state.checkPassed=false; render(); wrap.scrollIntoView({behavior:'smooth',block:'start'}); }; window.prevSlide = function(){ state.slide--; state.checkPassed=false; render(); wrap.scrollIntoView({behavior:'smooth',block:'start'}); }; window.startSimulator = function(){ state.mode='simulator'; state.scenarioIdx=0; state.stepIdx=0; render(); wrap.scrollIntoView({behavior:'smooth',block:'start'}); }; } function renderSimulator() { var scenarios = TRAINING.scenarios; var sc = scenarios[state.scenarioIdx]; var step = sc.steps[state.stepIdx]; var totalScenarios = scenarios.length; var h = ''; // Scenario selector h += '
'; h += '
Call simulations
'; h += '
'; scenarios.forEach(function(sc2,i){ var done = i < state.scenarioIdx; var active = i === state.scenarioIdx; h += ''; }); h += '
'; if (state.scenarioDone) { // Completed scenario h += '
'; h += '
'; h += '
Call handled perfectly.
'; h += '
'+sc.avatarName+' is a happy guest.
'; if (state.scenarioIdx < totalScenarios - 1) { h += ''; } else { h += '
All scenarios complete — module ready to sign off.
'; h += ''; } h += '
'; } else { // Active call simulation h += '
'; // Call header h += '
'; h += '
'+sc.avatar+'
'; h += '
'+sc.avatarName+'
'+sc.subtitle+'
'; h += '
Call in progress
'; h += '
'; // Progress dots h += '
'; sc.steps.forEach(function(st,i){ var done2 = i < state.stepIdx; var active2 = i === state.stepIdx; h += '
'; }); h += 'Step '+(state.stepIdx+1)+' of '+sc.steps.length+''; h += '
'; // Guest speech bubble h += '
'; h += '
'; h += '
'+sc.avatar+'
'; h += '
'+step.guest+'
'; // Prompt h += '
Your response
'; h += '
'+step.prompt+'
'; var letters2 = ['A','B','C','D']; h += '
'; step.options.forEach(function(opt,i){ h += ''; }); h += '
'; h += ''; h += '
'; } // Back to training h += '
'; wrap.innerHTML = h; window.selectScenario = function(i){ state.scenarioIdx=i; state.stepIdx=0; state.scenarioDone=false; render(); wrap.scrollIntoView({behavior:'smooth',block:'start'}); }; window.nextScenario = function(){ state.scenarioIdx++; state.stepIdx=0; state.scenarioDone=false; render(); wrap.scrollIntoView({behavior:'smooth',block:'start'}); }; window.backToTraining = function(){ state.mode='training'; render(); wrap.scrollIntoView({behavior:'smooth',block:'start'}); }; window.scrollToSig = function(){ document.querySelector('.signature-section').scrollIntoView({behavior:'smooth'}); }; window.handleSimChoice = function(idx) { var sc2 = TRAINING.scenarios[state.scenarioIdx]; var step2 = sc2.steps[state.stepIdx]; var choice = step2.options[idx]; var btns = wrap.querySelectorAll('#sim-opts button'); btns.forEach(function(b){ b.disabled=true; b.onmouseover=null; b.onmouseout=null; }); btns[idx].style.background = choice.outcome==='good' ? 'var(--success-light)' : 'var(--error-light)'; btns[idx].style.borderColor = choice.outcome==='good' ? 'var(--success)' : 'var(--error)'; btns[idx].style.color = choice.outcome==='good' ? 'var(--success)' : 'var(--error)'; var fb = wrap.querySelector('#sim-feedback'); fb.style.display = 'block'; fb.style.padding = '16px 20px'; fb.style.borderRadius = '2px'; fb.style.fontSize = '14px'; fb.style.lineHeight = '1.6'; if (choice.outcome === 'good') { fb.style.background = 'var(--success-light)'; fb.style.color = 'var(--success)'; fb.innerHTML = '✓ Correct. ' + choice.reason; setTimeout(function(){ if (state.stepIdx < sc2.steps.length - 1) { state.stepIdx++; render(); } else { state.scenarioDone = true; render(); } wrap.scrollIntoView({behavior:'smooth',block:'start'}); }, 1200); } else { fb.style.background = 'var(--error-light)'; fb.style.color = 'var(--error)'; fb.innerHTML = '✗ ' + sc2.avatarName + ' is unhappy and hangs up. ' + choice.reason + '

'; window.restartScenario = function(){ state.stepIdx=0; state.scenarioDone=false; render(); wrap.scrollIntoView({behavior:'smooth',block:'start'}); }; } }; } render(); } // ── ACCOUNTS ── async function renderAccounts() { var grid=document.getElementById('accounts-grid'); grid.innerHTML='
Loading your accounts...
'; var records=await loadCredentials(); if(!records.length){grid.innerHTML='
Your account credentials have not been set up yet. Please check with management.
';return;} grid.innerHTML=''; records.forEach(function(r){ var f=r.fields; var card=document.createElement('div'); card.className='account-card'; card.innerHTML='
'+(f['System']||'?')[0].toUpperCase()+'
'+(f['System']||'')+'
Username
Password
'; grid.appendChild(card); }); document.querySelectorAll('.show-pw-btn').forEach(function(btn){ btn.addEventListener('click',function(){ var el=document.getElementById('pw-'+btn.getAttribute('data-id')); if(btn.textContent==='Show'){el.textContent=btn.getAttribute('data-pw');btn.textContent='Hide';} else{el.textContent='••••••••';btn.textContent='Show';} }); }); } // ── PAYDAY ── function renderPaydayBanner() { var banner=document.getElementById('payday-banner'); var today=new Date(); today.setHours(0,0,0,0); var anchorCutoff=new Date(2026,5,6); var anchorPayday=new Date(2026,5,12); var twoWeeks=14*24*60*60*1000; var nextCutoff=new Date(anchorCutoff); while(nextCutoff  |  Payday: '+fmt(nextPayday)+''; } // ── MANAGER ── async function renderManagerDashboard() { var container=document.getElementById('manager-content'); container.innerHTML='
Loading staff progress...
'; var records=await loadAllProgress(); var staffMap={}; records.forEach(function(r){ var f=r.fields; var name=f['Staff Name']; if(!name)return; if(!staffMap[name])staffMap[name]={}; if(f['Document']){ if(!staffMap[name][f['Document']])staffMap[name][f['Document']]={}; if(f['Status']==='Signed')staffMap[name][f['Document']].signed=true; if(f['Status']==='Quiz Passed'){staffMap[name][f['Document']].complete=true;staffMap[name][f['Document']].score=f['Quiz Score'];} } }); var staffNames=Object.keys(staffMap).sort(); if(!staffNames.length){container.innerHTML='
No progress data yet.
';return;} var html=''; SECTIONS.forEach(function(section){ var docs=SECTION_DOCS[section.id]||[]; html+='

'+section.icon+' '+section.name+'

'; html+='
'; docs.forEach(function(d){html+='';}); html+=''; staffNames.forEach(function(name){ var p=staffMap[name]; var complete=0; var cells=docs.map(function(doc){ var d=p&&p[doc.id]; if(d&&d.complete){complete++;return '';} if(d&&d.signed)return ''; return ''; }); html+=''+cells.join('')+''; }); html+='
Staff member'+d.name+'Section %
✓ '+(d.score||'')+'%Signed
'+name+''+Math.round((complete/Math.max(docs.length,1))*100)+'%
'; }); container.innerHTML=html; } // ── NAV ── function showScreen(name) { document.querySelectorAll('.screen').forEach(function(s){s.classList.remove('active');}); document.getElementById('screen-'+name).classList.add('active'); window.scrollTo(0,0); } function goBack() { speechSynth.cancel(); isSpeaking=false; showScreen('portal'); renderTraining(); } function switchTab(tab,btn) { document.querySelectorAll('.tab-btn').forEach(function(b){b.classList.remove('active');}); document.querySelectorAll('.tab-panel').forEach(function(p){p.classList.remove('active');}); btn.classList.add('active'); document.getElementById('tab-'+tab).classList.add('active'); if(tab==='accounts')renderAccounts(); if(tab==='manager')renderManagerDashboard(); }