127 lines
11 KiB
JavaScript
127 lines
11 KiB
JavaScript
(()=>{
|
||
'use strict';
|
||
if(window.CateriumAccountCenterV1780)return;
|
||
const VERSION='17.8.0-account-center-v1';
|
||
const $=(s,r=document)=>r.querySelector(s);
|
||
const qa=(s,r=document)=>[...r.querySelectorAll(s)];
|
||
const esc=v=>window.SunSafe?.escapeHTML?window.SunSafe.escapeHTML(String(v??'')):String(v??'');
|
||
const cloud=()=>window.SunCloudV2||null;
|
||
const client=()=>cloud()?.getClient?.()||null;
|
||
const workspace=()=>cloud()?.getWorkspace?.()||null;
|
||
const session=()=>cloud()?.getSession?.()||null;
|
||
const toast=(text,type='info',ms=4500)=>{try{return window.SunEnterprise?.toast?.(text,type,ms)}catch(_){console.log('[AccountCenter]',text)}};
|
||
const ROLE_LABELS={admin:'Владелец',manager:'Менеджер',kitchen:'Кухня',courier:'Курьер',viewer:'Просмотр'};
|
||
let snapshot=null;
|
||
let modal=null;
|
||
let lastUserId='';
|
||
|
||
function installStyle(){
|
||
if($('#caterium-account-center-style'))return;
|
||
const s=document.createElement('style');s.id='caterium-account-center-style';s.textContent=`
|
||
#cateriumAccountCenter{position:fixed;inset:0;z-index:21000;display:none;place-items:center;padding:22px;background:#102c3d99;backdrop-filter:blur(5px)}
|
||
#cateriumAccountCenter.on{display:grid}
|
||
#cateriumAccountCenter .cac-shell{width:min(980px,100%);max-height:min(860px,92vh);overflow:auto;background:#f6f2ea;border-radius:22px;box-shadow:0 28px 90px #0004;color:#2f2b25}
|
||
#cateriumAccountCenter .cac-head{display:flex;justify-content:space-between;gap:16px;align-items:flex-start;padding:28px 30px 20px;border-bottom:1px solid #d9d1c5}
|
||
#cateriumAccountCenter h2{margin:0;font:500 38px/1.04 Georgia,'Times New Roman',serif;letter-spacing:-.03em;color:#27231f}
|
||
#cateriumAccountCenter .cac-sub{margin-top:7px;color:#8a8379;font-size:14px}
|
||
#cateriumAccountCenter .cac-close{border:0;background:transparent;font-size:31px;color:#5c564d;padding:0 4px}
|
||
#cateriumAccountCenter .cac-body{padding:24px 30px 30px}
|
||
#cateriumAccountCenter .cac-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
|
||
#cateriumAccountCenter .cac-card{background:#fffaf2;border:1px solid #ddd4c7;border-radius:16px;padding:20px}
|
||
#cateriumAccountCenter .cac-card.wide{grid-column:1/-1}
|
||
#cateriumAccountCenter .cac-card h3{margin:0 0 14px;color:#302b25;font-size:17px}
|
||
#cateriumAccountCenter .cac-meta{display:grid;gap:8px;margin:0 0 16px}.cac-meta div{display:flex;justify-content:space-between;gap:20px;padding-bottom:8px;border-bottom:1px dashed #e3dbcf}.cac-meta span{color:#8c857b}.cac-meta b{color:#332f29;text-align:right}
|
||
#cateriumAccountCenter label{display:flex;flex-direction:column;gap:6px;margin:11px 0;color:#777066;font-size:12px;font-weight:700}
|
||
#cateriumAccountCenter input{min-height:48px;border:1px solid #cfc6ba;border-radius:11px;background:#fff;padding:0 13px;color:#2e2a25;font-size:15px;outline:none}
|
||
#cateriumAccountCenter input:focus{border-color:#d0a13c;box-shadow:0 0 0 4px rgba(208,161,60,.11)}
|
||
#cateriumAccountCenter .cac-actions{display:flex;gap:9px;flex-wrap:wrap;margin-top:14px}
|
||
#cateriumAccountCenter button.primary{border:0;border-radius:11px;background:linear-gradient(100deg,#d9aa42,#efca69);color:#171512;padding:12px 16px;font-weight:900}
|
||
#cateriumAccountCenter button.outline{border:1px solid #c9c1b6;border-radius:11px;background:#fffaf2;color:#37332d;padding:11px 15px;font-weight:800}
|
||
#cateriumAccountCenter .cac-note{font-size:12px;color:#8a8379;line-height:1.55;margin-top:9px}
|
||
#cateriumAccountCenter .cac-owner{display:flex;align-items:center;gap:10px;padding:11px 13px;background:#fbf2d9;border:1px solid #ead39a;border-radius:12px;margin-bottom:12px}.cac-owner b{color:#725317}.cac-owner span{color:#8a6e36;font-size:12px}
|
||
#cateriumAccountCenter .cac-company-actions{display:flex;gap:10px;flex-wrap:wrap}
|
||
#sunCurrentUserLabel{cursor:pointer}
|
||
#sunCurrentUserLabel:hover{text-decoration:underline;text-underline-offset:3px}
|
||
@media(max-width:720px){#cateriumAccountCenter{padding:0;place-items:stretch}#cateriumAccountCenter .cac-shell{width:100%;max-height:none;height:100dvh;border-radius:0}#cateriumAccountCenter .cac-grid{grid-template-columns:1fr}#cateriumAccountCenter .cac-card.wide{grid-column:auto}#cateriumAccountCenter .cac-head,#cateriumAccountCenter .cac-body{padding-left:18px;padding-right:18px}}
|
||
`;document.head.appendChild(s);
|
||
}
|
||
|
||
function ensureModal(){
|
||
if(modal)return modal;
|
||
modal=document.createElement('div');modal.id='cateriumAccountCenter';modal.innerHTML='<div class="cac-shell"><div class="cac-head"><div><h2>Мой аккаунт</h2><div class="cac-sub">Профиль и безопасность Caterium</div></div><button class="cac-close" type="button" aria-label="Закрыть">×</button></div><div class="cac-body" id="cateriumAccountCenterBody"></div></div>';
|
||
document.body.appendChild(modal);
|
||
modal.addEventListener('click',e=>{if(e.target===modal||e.target.closest('.cac-close'))close();});
|
||
return modal;
|
||
}
|
||
async function loadSnapshot(){
|
||
const c=client(),ws=workspace();if(!c||!ws?.id)return null;
|
||
const {data,error}=await c.rpc('caterium_account_snapshot',{p_workspace:ws.id});
|
||
if(error)throw error;snapshot=data||null;return snapshot;
|
||
}
|
||
function render(){
|
||
const body=$('#cateriumAccountCenterBody');if(!body)return;
|
||
const ss=session(),s=snapshot||{},owner=Boolean(s.is_owner);
|
||
const companyNo=s.company_number?`№${s.company_number}`:'—';
|
||
body.innerHTML=`<div class="cac-grid">
|
||
<section class="cac-card">
|
||
<h3>Профиль</h3>
|
||
${owner?'<div class="cac-owner"><div><b>Главный аккаунт компании</b><span>Только этот аккаунт управляет сотрудниками и их правами.</span></div></div>':''}
|
||
<div class="cac-meta"><div><span>Компания</span><b>${esc(s.company_name||'—')} · ${esc(companyNo)}</b></div><div><span>Статус</span><b>${esc(owner?'Владелец':ROLE_LABELS[s.role]||s.role||'Сотрудник')}</b></div></div>
|
||
<label>Имя<input id="cacName" value="${esc(s.display_name||ss?.user?.user_metadata?.name||'')}"></label>
|
||
<div class="cac-actions"><button class="primary" id="cacSaveName" type="button">Сохранить имя</button></div>
|
||
</section>
|
||
<section class="cac-card">
|
||
<h3>Email для входа</h3>
|
||
<label>Текущий email<input value="${esc(ss?.user?.email||s.email||'')}" disabled></label>
|
||
<label>Новый email<input id="cacEmail" type="email" autocomplete="email" placeholder="new@email.com"></label>
|
||
<div class="cac-actions"><button class="primary" id="cacSaveEmail" type="button">Изменить email</button></div>
|
||
<div class="cac-note">После смены Supabase отправит письмо подтверждения на новый адрес.</div>
|
||
</section>
|
||
<section class="cac-card">
|
||
<h3>Пароль</h3>
|
||
<label>Новый пароль<input id="cacPassword" type="password" autocomplete="new-password" minlength="8"></label>
|
||
<label>Повторите пароль<input id="cacPassword2" type="password" autocomplete="new-password" minlength="8"></label>
|
||
<div class="cac-actions"><button class="primary" id="cacSavePassword" type="button">Сменить пароль</button></div>
|
||
</section>
|
||
${owner?`<section class="cac-card"><h3>Компания и пользователи</h3><p class="cac-note">Создавайте сотрудников, назначайте роли и выдавайте доступ к нужным разделам Caterium.</p><div class="cac-company-actions"><button class="primary" id="cacOpenUsers" type="button">Пользователи и права</button></div></section>`:''}
|
||
<section class="cac-card wide"><h3>Сеанс</h3><div class="cac-actions"><button class="outline" id="cacLogout" type="button">Выйти из аккаунта</button></div></section>
|
||
</div>`;
|
||
$('#cacSaveName').onclick=saveName;$('#cacSaveEmail').onclick=saveEmail;$('#cacSavePassword').onclick=savePassword;$('#cacLogout').onclick=logout;
|
||
const users=$('#cacOpenUsers');if(users)users.onclick=()=>{close();window.SunAdminRBACV3?.openUsers?.();};
|
||
}
|
||
async function saveName(){
|
||
const name=String($('#cacName')?.value||'').trim();if(!name)return toast('Введите имя.','warn');
|
||
const c=client();if(!c)return;
|
||
const btn=$('#cacSaveName');btn.disabled=true;
|
||
try{const {data,error}=await c.rpc('caterium_update_my_name',{p_display_name:name});if(error)throw error;const r=await c.auth.updateUser({data:{name:data||name}});if(r.error)throw r.error;await cloud()?.reloadMemberships?.();await loadSnapshot();render();window.SunAdminRBACV3?.apply?.();toast('Имя изменено.','success');}
|
||
catch(e){toast(e?.message||String(e),'error',6500)}finally{btn.disabled=false}
|
||
}
|
||
async function saveEmail(){
|
||
const email=String($('#cacEmail')?.value||'').trim().toLowerCase();if(!email)return toast('Введите новый email.','warn');
|
||
const c=client();if(!c)return;const btn=$('#cacSaveEmail');btn.disabled=true;
|
||
try{const {error}=await c.auth.updateUser({email});if(error)throw error;$('#cacEmail').value='';toast('На новый email отправлено письмо подтверждения.','success',6500)}catch(e){toast(e?.message||String(e),'error',6500)}finally{btn.disabled=false}
|
||
}
|
||
async function savePassword(){
|
||
const p=String($('#cacPassword')?.value||''),p2=String($('#cacPassword2')?.value||'');
|
||
if(p.length<8)return toast('Пароль должен быть не короче 8 символов.','warn');if(p!==p2)return toast('Пароли не совпадают.','warn');
|
||
const c=client();if(!c)return;const btn=$('#cacSavePassword');btn.disabled=true;
|
||
try{const {error}=await c.auth.updateUser({password:p});if(error)throw error;$('#cacPassword').value='';$('#cacPassword2').value='';toast('Пароль изменён.','success')}
|
||
catch(e){toast(e?.message||String(e),'error',6500)}finally{btn.disabled=false}
|
||
}
|
||
async function logout(){try{await cloud()?.signOut?.()}catch(_){try{await client()?.auth.signOut()}catch(__){}location.reload()}}
|
||
async function open(){
|
||
ensureModal();modal.classList.add('on');const body=$('#cateriumAccountCenterBody');body.innerHTML='<p class="cac-note">Загружаю аккаунт…</p>';
|
||
try{await loadSnapshot();render()}catch(e){body.innerHTML=`<p class="cac-note">${esc(e?.message||e||'Не удалось загрузить аккаунт.')}</p>`}
|
||
}
|
||
function close(){modal?.classList.remove('on')}
|
||
function bindEntry(){
|
||
const label=$('#sunCurrentUserLabel');if(label&&!label.dataset.cateriumAccountBound){label.dataset.cateriumAccountBound='1';label.title='Открыть личный кабинет';label.addEventListener('click',open)}
|
||
const ss=session();const uid=ss?.user?.id||'';if(uid&&uid!==lastUserId){lastUserId=uid;snapshot=null;}
|
||
}
|
||
installStyle();ensureModal();bindEntry();
|
||
const obs=new MutationObserver(bindEntry);obs.observe(document.documentElement,{childList:true,subtree:true});
|
||
window.addEventListener('sun:cloud-permissions-changed',()=>setTimeout(bindEntry,0));
|
||
setInterval(()=>{if(!document.hidden)bindEntry()},3000);
|
||
window.CateriumAccountCenterV1780=Object.freeze({VERSION,open,close,reload:async()=>{await loadSnapshot();render();return snapshot}});
|
||
})();
|