domma-cms 0.6.8 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/css/admin.css +1 -1
- package/admin/js/api.js +1 -1
- package/admin/js/app.js +4 -4
- package/admin/js/config/sidebar-config.js +1 -1
- package/admin/js/lib/markdown-toolbar.js +9 -9
- package/admin/js/lib/themes.js +1 -0
- package/admin/js/templates/page-editor.html +41 -21
- package/admin/js/templates/settings.html +2 -108
- package/admin/js/views/collection-editor.js +3 -3
- package/admin/js/views/login.js +7 -7
- package/admin/js/views/page-editor.js +34 -22
- package/admin/js/views/settings.js +2 -2
- package/package.json +1 -1
- package/plugins/analytics/stats.json +3 -3
- package/public/css/site.css +1 -1
- package/server/routes/api/pages.js +2 -2
- package/server/routes/api/versions.js +77 -0
- package/server/server.js +2 -0
- package/server/services/content.js +20 -2
- package/server/services/markdown.js +102 -4
- package/server/services/versions.js +253 -0
|
@@ -64,119 +64,13 @@
|
|
|
64
64
|
<div class="row">
|
|
65
65
|
<div class="col-6">
|
|
66
66
|
<label class="form-label">Public Site Theme</label>
|
|
67
|
-
|
|
68
|
-
<optgroup label="Charcoal">
|
|
69
|
-
<option value="charcoal-dark">Charcoal Dark</option>
|
|
70
|
-
<option value="charcoal-light">Charcoal Light</option>
|
|
71
|
-
</optgroup>
|
|
72
|
-
<optgroup label="Ocean">
|
|
73
|
-
<option value="ocean-dark">Ocean Dark</option>
|
|
74
|
-
<option value="ocean-light">Ocean Light</option>
|
|
75
|
-
</optgroup>
|
|
76
|
-
<optgroup label="Forest">
|
|
77
|
-
<option value="forest-dark">Forest Dark</option>
|
|
78
|
-
<option value="forest-light">Forest Light</option>
|
|
79
|
-
</optgroup>
|
|
80
|
-
<optgroup label="Sunset">
|
|
81
|
-
<option value="sunset-dark">Sunset Dark</option>
|
|
82
|
-
<option value="sunset-light">Sunset Light</option>
|
|
83
|
-
</optgroup>
|
|
84
|
-
<optgroup label="Royal">
|
|
85
|
-
<option value="royal-dark">Royal Dark</option>
|
|
86
|
-
<option value="royal-light">Royal Light</option>
|
|
87
|
-
</optgroup>
|
|
88
|
-
<optgroup label="Lemon">
|
|
89
|
-
<option value="lemon-dark">Lemon Dark</option>
|
|
90
|
-
<option value="lemon-light">Lemon Light</option>
|
|
91
|
-
</optgroup>
|
|
92
|
-
<optgroup label="Silver">
|
|
93
|
-
<option value="silver-dark">Silver Dark</option>
|
|
94
|
-
<option value="silver-light">Silver Light</option>
|
|
95
|
-
</optgroup>
|
|
96
|
-
<optgroup label="Unicorn">
|
|
97
|
-
<option value="unicorn-dark">Unicorn Dark</option>
|
|
98
|
-
<option value="unicorn-light">Unicorn Light</option>
|
|
99
|
-
</optgroup>
|
|
100
|
-
<optgroup label="Dreamy">
|
|
101
|
-
<option value="dreamy-dark">Dreamy Dark</option>
|
|
102
|
-
<option value="dreamy-light">Dreamy Light</option>
|
|
103
|
-
</optgroup>
|
|
104
|
-
<optgroup label="Grayve">
|
|
105
|
-
<option value="grayve-dark">Grayve Dark</option>
|
|
106
|
-
<option value="grayve-light">Grayve Light</option>
|
|
107
|
-
</optgroup>
|
|
108
|
-
<optgroup label="Mint">
|
|
109
|
-
<option value="mint-dark">Mint Dark</option>
|
|
110
|
-
<option value="mint-light">Mint Light</option>
|
|
111
|
-
</optgroup>
|
|
112
|
-
<optgroup label="Christmas">
|
|
113
|
-
<option value="christmas-dark">Christmas Dark</option>
|
|
114
|
-
<option value="christmas-light">Christmas Light</option>
|
|
115
|
-
</optgroup>
|
|
116
|
-
<optgroup label="Wedding">
|
|
117
|
-
<option value="wedding-dark">Wedding Dark</option>
|
|
118
|
-
<option value="wedding-light">Wedding Light</option>
|
|
119
|
-
</optgroup>
|
|
120
|
-
</select>
|
|
67
|
+
<select id="field-theme" class="form-select"></select>
|
|
121
68
|
<p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the public-facing
|
|
122
69
|
website.</p>
|
|
123
70
|
</div>
|
|
124
71
|
<div class="col-6">
|
|
125
72
|
<label class="form-label">Admin Theme</label>
|
|
126
|
-
|
|
127
|
-
<optgroup label="Charcoal">
|
|
128
|
-
<option value="charcoal-dark">Charcoal Dark</option>
|
|
129
|
-
<option value="charcoal-light">Charcoal Light</option>
|
|
130
|
-
</optgroup>
|
|
131
|
-
<optgroup label="Ocean">
|
|
132
|
-
<option value="ocean-dark">Ocean Dark</option>
|
|
133
|
-
<option value="ocean-light">Ocean Light</option>
|
|
134
|
-
</optgroup>
|
|
135
|
-
<optgroup label="Forest">
|
|
136
|
-
<option value="forest-dark">Forest Dark</option>
|
|
137
|
-
<option value="forest-light">Forest Light</option>
|
|
138
|
-
</optgroup>
|
|
139
|
-
<optgroup label="Sunset">
|
|
140
|
-
<option value="sunset-dark">Sunset Dark</option>
|
|
141
|
-
<option value="sunset-light">Sunset Light</option>
|
|
142
|
-
</optgroup>
|
|
143
|
-
<optgroup label="Royal">
|
|
144
|
-
<option value="royal-dark">Royal Dark</option>
|
|
145
|
-
<option value="royal-light">Royal Light</option>
|
|
146
|
-
</optgroup>
|
|
147
|
-
<optgroup label="Lemon">
|
|
148
|
-
<option value="lemon-dark">Lemon Dark</option>
|
|
149
|
-
<option value="lemon-light">Lemon Light</option>
|
|
150
|
-
</optgroup>
|
|
151
|
-
<optgroup label="Silver">
|
|
152
|
-
<option value="silver-dark">Silver Dark</option>
|
|
153
|
-
<option value="silver-light">Silver Light</option>
|
|
154
|
-
</optgroup>
|
|
155
|
-
<optgroup label="Unicorn">
|
|
156
|
-
<option value="unicorn-dark">Unicorn Dark</option>
|
|
157
|
-
<option value="unicorn-light">Unicorn Light</option>
|
|
158
|
-
</optgroup>
|
|
159
|
-
<optgroup label="Dreamy">
|
|
160
|
-
<option value="dreamy-dark">Dreamy Dark</option>
|
|
161
|
-
<option value="dreamy-light">Dreamy Light</option>
|
|
162
|
-
</optgroup>
|
|
163
|
-
<optgroup label="Grayve">
|
|
164
|
-
<option value="grayve-dark">Grayve Dark</option>
|
|
165
|
-
<option value="grayve-light">Grayve Light</option>
|
|
166
|
-
</optgroup>
|
|
167
|
-
<optgroup label="Mint">
|
|
168
|
-
<option value="mint-dark">Mint Dark</option>
|
|
169
|
-
<option value="mint-light">Mint Light</option>
|
|
170
|
-
</optgroup>
|
|
171
|
-
<optgroup label="Christmas">
|
|
172
|
-
<option value="christmas-dark">Christmas Dark</option>
|
|
173
|
-
<option value="christmas-light">Christmas Light</option>
|
|
174
|
-
</optgroup>
|
|
175
|
-
<optgroup label="Wedding">
|
|
176
|
-
<option value="wedding-dark">Wedding Dark</option>
|
|
177
|
-
<option value="wedding-light">Wedding Light</option>
|
|
178
|
-
</optgroup>
|
|
179
|
-
</select>
|
|
73
|
+
<select id="field-admin-theme" class="form-select"></select>
|
|
180
74
|
<p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the admin panel.</p>
|
|
181
75
|
</div>
|
|
182
76
|
</div>
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{api as
|
|
2
|
-
`).filter(
|
|
3
|
-
`),
|
|
1
|
+
import{api as z}from"../api.js";const Z=[{value:"string",label:"Text (single line)"},{value:"email",label:"Email"},{value:"tel",label:"Phone"},{value:"number",label:"Number"},{value:"textarea",label:"Textarea (multi-line)"},{value:"select",label:"Dropdown (select)"},{value:"radio",label:"Radio buttons"},{value:"checkbox",label:"Single checkbox"},{value:"checkbox-group",label:"Checkbox group"},{value:"date",label:"Date"},{value:"time",label:"Time"},{value:"url",label:"URL"},{value:"hidden",label:"Hidden field"}],Q=new Set(["select","radio","checkbox-group"]),ne=["public","subscriber","editor","manager","admin"],$=["create","read","update","delete"];let u=[],w=null,T=!0,q=null;function ee(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}function te(e){return Z.find(t=>t.value===e)?.label||e}function ae(e){const t={...u[e]},n=document.getElementById(`fb-label-${e}`),a=document.getElementById(`fb-name-${e}`),i=document.getElementById(`fb-type-${e}`),p=document.getElementById(`fb-required-${e}`),r=document.getElementById(`fb-placeholder-${e}`),l=document.getElementById(`fb-helper-${e}`);if(n&&(t.label=n.value.trim()||t.label),a&&(t.name=a.value.trim()||t.name),i&&(t.type=i.value||t.type),p&&(t.required=p.checked),r&&(t.placeholder=r.value.trim()),l&&(t.helper=l.value.trim()),Q.has(t.type)){const c=document.getElementById(`fb-options-${e}`);c&&(t.options=c.value.split(`
|
|
2
|
+
`).filter(f=>f.trim()).map(f=>{const[g,...m]=f.split(":");return{value:g.trim(),label:m.join(":").trim()||g.trim()}}))}const o=document.getElementById(`fb-span-${e}`);if(document.getElementById(`fb-fullwidth-${e}`)?.checked)t.fullWidth=!0,delete t.span;else{delete t.fullWidth;const c=parseInt(o?.value,10);c>1?t.span=c:delete t.span}return t}function X(){return u.map((e,t)=>ae(t))}function oe(e,t){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:1px solid var(--border-color,#333);border-radius:8px;margin-bottom:.75rem;overflow:hidden;";const a=document.createElement("div");a.className="fb-field-header",a.style.cssText="display:flex;align-items:center;gap:.5rem;padding:.6rem .75rem;background:var(--card-header-bg,rgba(255,255,255,.03));cursor:pointer;user-select:none;";const i=document.createElement("span");i.textContent="\u283F",i.style.cssText="cursor:grab;opacity:.4;font-size:1.1rem;flex-shrink:0;",n.draggable=!0,i.addEventListener("mousedown",()=>{n.draggable=!0}),n.addEventListener("dragstart",s=>{q=t,s.dataTransfer.effectAllowed="move",n.style.opacity="0.4"}),n.addEventListener("dragend",()=>{n.style.opacity="",document.querySelectorAll(".fb-field-card").forEach(s=>s.classList.remove("fb-drag-over"))}),n.addEventListener("dragover",s=>{s.preventDefault(),s.dataTransfer.dropEffect="move",document.querySelectorAll(".fb-field-card").forEach(y=>y.classList.remove("fb-drag-over")),n.classList.add("fb-drag-over")}),n.addEventListener("dragleave",()=>{n.classList.remove("fb-drag-over")}),n.addEventListener("drop",s=>{if(s.preventDefault(),n.classList.remove("fb-drag-over"),q===null||q===t)return;u=X();const[y]=u.splice(q,1);u.splice(t,0,y),q=null,P(document.getElementById("fields-list"))});const p=document.createElement("span");p.className="fb-field-summary",p.style.cssText="flex:1;font-weight:500;font-size:.9rem;",p.textContent=e.label||"(Untitled field)";const r=document.createElement("span");r.style.cssText="font-size:.75rem;opacity:.5;",r.textContent=te(e.type);const l=document.createElement("span");l.className="fb-field-chevron",l.textContent="\u25BE",l.style.cssText="opacity:.5;transition:transform .2s;";const o=document.createElement("button");o.type="button",o.textContent="\xD7",o.className="btn btn-sm",o.style.cssText="padding:.15rem .45rem;line-height:1;font-size:1rem;opacity:.6;",o.title="Remove field",o.addEventListener("click",s=>{s.stopPropagation(),u.splice(t,1),P(document.getElementById("fields-list"))}),a.appendChild(i),a.appendChild(p),a.appendChild(r),a.appendChild(l),a.appendChild(o);const d=document.createElement("div");d.className="fb-field-body",d.style.cssText="padding:.75rem;display:none;";const c=document.createElement("div");c.style.cssText="display:grid;grid-template-columns:1fr 1fr 1fr;gap:.6rem;margin-bottom:.6rem;";const f=document.createElement("div"),g=document.createElement("label");g.className="form-label",g.textContent="Label";const m=document.createElement("input");m.id=`fb-label-${t}`,m.type="text",m.className="form-input",m.value=e.label||"",m.addEventListener("input",()=>{p.textContent=m.value.trim()||"(Untitled field)";const s=document.getElementById(`fb-name-${t}`);s&&!s.dataset.manual&&(s.value=ee(m.value).replace(/-/g,"_"))}),f.appendChild(g),f.appendChild(m);const L=document.createElement("div"),h=document.createElement("label");h.className="form-label",h.textContent="Name (key)";const v=document.createElement("input");v.id=`fb-name-${t}`,v.type="text",v.className="form-input",v.value=e.name||"",v.addEventListener("input",()=>{v.dataset.manual="1"}),L.appendChild(h),L.appendChild(v);const O=document.createElement("div"),U=document.createElement("label");U.className="form-label",U.textContent="Type";const C=document.createElement("select");C.id=`fb-type-${t}`,C.className="form-input",Z.forEach(s=>{const y=document.createElement("option");y.value=s.value,y.textContent=s.label,s.value===e.type&&(y.selected=!0),C.appendChild(y)}),C.addEventListener("change",()=>{r.textContent=te(C.value);const s=d.querySelector(".fb-options-wrap");s&&(s.style.display=Q.has(C.value)?"":"none")}),O.appendChild(U),O.appendChild(C),c.appendChild(f),c.appendChild(L),c.appendChild(O);const N=document.createElement("div");N.style.cssText="display:grid;grid-template-columns:1fr 1fr auto;gap:.6rem;align-items:end;margin-bottom:.6rem;";const _=document.createElement("div"),M=document.createElement("label");M.className="form-label",M.textContent="Placeholder";const I=document.createElement("input");I.id=`fb-placeholder-${t}`,I.type="text",I.className="form-input",I.value=e.placeholder||"",_.appendChild(M),_.appendChild(I);const j=document.createElement("div"),V=document.createElement("label");V.className="form-label",V.textContent="Helper text";const S=document.createElement("input");S.id=`fb-helper-${t}`,S.type="text",S.className="form-input",S.value=e.helper||"",j.appendChild(V),j.appendChild(S);const H=document.createElement("div");H.style.cssText="padding-bottom:.35rem;";const A=document.createElement("label");A.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;white-space:nowrap;";const W=document.createElement("input");W.id=`fb-required-${t}`,W.type="checkbox",W.checked=!!e.required,A.appendChild(W),A.appendChild(document.createTextNode("Required")),H.appendChild(A),N.appendChild(_),N.appendChild(j),N.appendChild(H);const k=document.createElement("div");k.className="fb-options-wrap",k.style.display=Q.has(e.type)?"":"none";const Y=document.createElement("label");Y.className="form-label",Y.textContent="Options (one per line: value: Label)";const B=document.createElement("textarea");B.id=`fb-options-${t}`,B.className="form-input",B.rows=4,B.value=(e.options||[]).map(s=>typeof s=="string"?`${s}: ${s}`:`${s.value??""}: ${s.label??s.value??""}`).join(`
|
|
3
|
+
`),k.appendChild(Y),k.appendChild(B);const b=document.createElement("div");b.className="fb-grid-row",b.style.gridTemplateColumns="1fr auto",b.style.gap=".6rem",b.style.alignItems="end",b.style.marginBottom=".6rem",b.style.display=document.getElementById("collection-layout")?.value==="grid"?"grid":"none";const G=document.createElement("div"),J=document.createElement("label");J.className="form-label",J.textContent="Column Span";const x=document.createElement("input");x.id=`fb-span-${t}`,x.type="number",x.className="form-input",x.min="1",x.max="6",x.value=e.span>1?String(e.span):"1",G.appendChild(J),G.appendChild(x);const K=document.createElement("div");K.style.cssText="padding-bottom:.35rem;";const F=document.createElement("label");F.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;white-space:nowrap;";const D=document.createElement("input");return D.id=`fb-fullwidth-${t}`,D.type="checkbox",D.checked=!!e.fullWidth,F.appendChild(D),F.appendChild(document.createTextNode("Full Width")),K.appendChild(F),b.appendChild(G),b.appendChild(K),d.appendChild(c),d.appendChild(N),d.appendChild(k),d.appendChild(b),a.addEventListener("click",()=>{const s=d.style.display!=="none";d.style.display=s?"none":"",l.style.transform=s?"":"rotate(180deg)"}),n.appendChild(a),n.appendChild(d),n}function P(e){if(e){if(e.textContent="",u.length===0){const t=document.createElement("p");t.className="text-muted",t.id="fields-empty-msg",t.style.cssText="text-align:center;padding:2rem 0;",t.textContent='No fields yet. Click "Add Field" to get started.',e.appendChild(t);return}u.forEach((t,n)=>{e.appendChild(oe(t,n))})}}function se(e,t){t.textContent="",$.forEach(n=>{const a=e?.[n]||{enabled:!1,access:"admin"},i=document.createElement("div");i.style.cssText="display:grid;grid-template-columns:140px 1fr 160px;gap:.75rem;align-items:center;padding:.6rem 0;border-bottom:1px solid var(--border-color,#333);";const p=document.createElement("strong");p.textContent=n.charAt(0).toUpperCase()+n.slice(1),p.style.cssText="font-size:.9rem;";const r=document.createElement("label");r.style.cssText="display:flex;align-items:center;gap:.45rem;cursor:pointer;font-size:.875rem;";const l=document.createElement("input");l.type="checkbox",l.id=`api-${n}-enabled`,l.checked=!!a.enabled,r.appendChild(l),r.appendChild(document.createTextNode("Enable public access"));const o=document.createElement("select");o.id=`api-${n}-access`,o.className="form-input",ne.forEach(d=>{const c=document.createElement("option");c.value=d,c.textContent=d.charAt(0).toUpperCase()+d.slice(1),d===a.access&&(c.selected=!0),o.appendChild(c)}),i.appendChild(p),i.appendChild(r),i.appendChild(o),t.appendChild(i)})}function de(e,t){E.dropdown("#storage-adapter-trigger",{items:[{label:"File (default)",value:"file"},{label:"MongoDB",value:"mongodb"}],onSelect:({item:a})=>{e.find("#storage-adapter").val(a.value),e.find("#storage-adapter-label").text(a.label);const i=a.value==="mongodb";e.find("#storage-connection-group").toggle(i),e.find("#storage-migration-warning").toggle(i&&!T)}});const n=t.map(a=>({label:a,value:a}));E.dropdown("#storage-connection-trigger",{items:n.length?n:[{label:"default",value:"default"}],onSelect:({item:a})=>{e.find("#storage-connection").val(a.value),e.find("#storage-connection-label").text(a.label)}})}function le(){return(document.getElementById("storage-adapter")?.value||"file")==="mongodb"?{adapter:"mongodb",connection:document.getElementById("storage-connection")?.value||"default"}:{adapter:"file"}}function ce(){const e={};return $.forEach(t=>{const n=document.getElementById(`api-${t}-enabled`)?.checked??!1,a=document.getElementById(`api-${t}-access`)?.value||"admin";e[t]={enabled:n,access:a}}),e}export const collectionEditorView={templateUrl:"/admin/js/templates/collection-editor.html",async onMount(e){u=[],w=null,T=!0;const n=window.location.hash.match(/\/collections\/edit\/([^/?#]+)/);n&&(w=n[1],T=!1),E.tabs(e.find("#collection-tabs").get(0)),e.find("#collection-layout").get(0)?.addEventListener("change",function(){const l=this.value==="grid";e.find("#collection-columns-group").get(0).style.display=l?"":"none",document.querySelectorAll(".fb-grid-row").forEach(o=>{o.style.display=l?"grid":"none"})});const a=e.find("#fields-list").get(0),i=e.find("#api-access-rows").get(0),p=await z.collections.proStatus();p?.pro&&w!=="roles"&&(e.find("#storage-tab-btn").show(),de(e,p.connections));let r={create:{enabled:!1,access:"admin"},read:{enabled:!0,access:"public"},update:{enabled:!1,access:"admin"},delete:{enabled:!1,access:"admin"}};if(T){const l=e.find("#field-title").get(0),o=e.find("#field-slug").get(0);l&&o&&(l.addEventListener("input",()=>{o.dataset.manual||(o.value=ee(l.value))}),o.addEventListener("input",()=>{o.dataset.manual="1"}))}else try{const l=await z.collections.get(w);if(!l){E.toast("Collection not found.",{type:"error"}),R.navigate("/collections");return}const o=e.find("#editor-title-text").get(0);o&&(o.textContent=l.title),e.find("#field-title").val(l.title||""),e.find("#field-slug").val(l.slug||""),e.find("#field-slug").prop("readonly",!0),e.find("#slug-hint").get(0).textContent="Slug cannot be changed after creation.",e.find("#field-description").val(l.description||""),e.find("#collection-layout").val(l.layout||"stacked"),e.find("#collection-columns").val(l.columns||2),e.find("#collection-columns-group").get(0).style.display=l.layout==="grid"?"":"none",u=l.fields||[],r=l.api||r,l.storage&&(e.find("#storage-adapter").val(l.storage.adapter||"file"),e.find("#storage-adapter-label").text(l.storage.adapter==="mongodb"?"MongoDB":"File (default)"),l.storage.adapter==="mongodb"&&(e.find("#storage-connection-group").show(),e.find("#storage-connection").val(l.storage.connection||"default"),e.find("#storage-connection-label").text(l.storage.connection||"default"))),w==="roles"&&e.find("#storage-tab-btn").hide()}catch{E.toast("Failed to load collection.",{type:"error"}),R.navigate("/collections");return}P(a),se(r,i),e.find("#add-field-btn").off("click").on("click",()=>{u=X(),u.push({id:`field-${Date.now()}`,name:"",label:"",type:"string",required:!1,placeholder:"",helper:"",options:[],validation:[],logic:null}),P(a);const l=a.querySelectorAll(".fb-field-card");if(l.length){const o=l[l.length-1],d=o.querySelector(".fb-field-body"),c=o.querySelector(".fb-field-chevron");d&&(d.style.display=""),c&&(c.style.transform="rotate(180deg)"),o.querySelector(`#fb-label-${u.length-1}`)?.focus()}}),e.find("#save-collection-btn").off("click").on("click",async()=>{const l=e.find("#field-title").val().trim(),o=e.find("#field-slug").val().trim(),d=e.find("#field-description").val().trim();if(!l){E.toast("Title is required.",{type:"warning"});return}const c=X(),f=ce(),g=e.find("#collection-layout").val()||"stacked",m=parseInt(e.find("#collection-columns").val(),10)||2,L=e.find("#save-collection-btn");L.prop("disabled",!0);try{if(T){const h=await z.collections.create({title:l,slug:o,description:d,layout:g,columns:m,fields:c,api:f,storage:le()});w=h.slug,T=!1,E.toast("Collection created.",{type:"success"}),R.navigate(`/collections/edit/${h.slug}`)}else await z.collections.update(w,{title:l,description:d,layout:g,columns:m,fields:c,api:f,storage:le()}),E.toast("Collection saved.",{type:"success"})}catch(h){E.toast(h.message||"Failed to save.",{type:"error"})}finally{L.prop("disabled",!1)}}),Domma.icons.scan()}};
|
package/admin/js/views/login.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import{api as
|
|
2
|
-
<div class="theme-swatch" data-theme="${
|
|
3
|
-
<div class="theme-swatch-preview" style="background:${
|
|
4
|
-
<div class="theme-swatch-accent" style="background:${
|
|
1
|
+
import{api as o,isAuthenticated as u,setAuthData as l}from"../api.js";import{THEMES as p}from"../lib/themes.js";const f={name:{type:"string",required:!0,minLength:2,label:"Full Name",formConfig:{placeholder:"Your name",autocomplete:"name"}},email:{type:"email",required:!0,label:"Email Address",formConfig:{placeholder:"admin@example.com",autocomplete:"email"}},password:{type:"password",required:!0,minLength:8,label:"Password",formConfig:{placeholder:"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",autocomplete:"new-password",tooltip:"Minimum 8 characters"}}},h={email:{type:"email",required:!0,label:"Email Address",formConfig:{placeholder:"you@example.com",autocomplete:"email"}},password:{type:"password",required:!0,label:"Password",formConfig:{placeholder:"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",autocomplete:"current-password"}}};export const loginView={templateUrl:"/admin/js/templates/login.html",async onMount(e){if(u()){R.navigate("/");return}const a=window.location.hash,t=a.match(/[?&]token=([a-f0-9]{64})/);if(a.startsWith("#/reset-password")&&t){r(e,"reset"),S(e,t[1]),Domma.icons.scan();return}if(a.startsWith("#/reset-password")){R.navigate("/login");return}let s=!1;try{s=(await o.auth.setupStatus()).needsSetup}catch{E.toast("Could not reach the server.",{type:"error"})}s?(r(e,"setup"),y(e)):(r(e,"login"),k(e)),Domma.icons.scan()}};const g={email:{type:"email",required:!0,label:"Email Address",formConfig:{placeholder:"you@example.com",autocomplete:"email"}}},b={password:{type:"password",required:!0,minLength:8,label:"New Password",formConfig:{placeholder:"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",autocomplete:"new-password",tooltip:"Minimum 8 characters"}},confirmPassword:{type:"password",required:!0,label:"Confirm Password",formConfig:{placeholder:"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",autocomplete:"new-password"}}},w=["setup","onboarding-site","onboarding-theme","onboarding-done","login","forgot","forgot-success","reset"];function r(e,a){w.forEach(t=>e.find(`#${t}-panel`).hide()),e.find(`#${a}-panel`).show(),Domma.icons.scan()}function d(e,a,t){e.find(`#${a}`).text(t).show()}function y(e){F.render("#setup-form-container",f,{},{layout:"stacked",submitText:"Create admin account",onSubmit:async a=>{try{const t=await o.auth.setup(a);l(t),r(e,"onboarding-site"),v(e)}catch(t){return E.toast(t.message||"Setup failed. Please try again.",{type:"error"}),!1}}})}function v(e){e.find("#ob-site-skip").on("click",a=>{a.preventDefault(),r(e,"onboarding-theme"),c(e),m(e)}),e.find("#ob-site-btn").on("click",async()=>{e.find("#ob-site-error").hide();const a=e.find("#ob-title").val().trim(),t=e.find("#ob-tagline").val().trim(),s=e.find("#ob-site-btn").prop("disabled",!0).text("Saving\u2026");try{const i=await o.settings.get();await o.settings.save({...i,title:a||i.title,tagline:t||i.tagline,seo:{...i.seo||{},defaultTitle:a||i.seo&&i.seo.defaultTitle}});const n=await o.navigation.get();await o.navigation.save({...n,brand:{...n.brand||{},text:a||n.brand.text}}),r(e,"onboarding-theme"),c(e),m(e)}catch(i){d(e,"ob-site-error",i.message||"Could not save site details.")}finally{s.prop("disabled",!1).text("Continue")}})}function c(e){const a=e.find("#theme-grid").empty();p.forEach(t=>{const s=$(`
|
|
2
|
+
<div class="theme-swatch" data-theme="${t.id}" title="${t.id}">
|
|
3
|
+
<div class="theme-swatch-preview" style="background:${t.bg}">
|
|
4
|
+
<div class="theme-swatch-accent" style="background:${t.primary}"></div>
|
|
5
5
|
</div>
|
|
6
6
|
<div class="theme-swatch-label">
|
|
7
|
-
<span>${
|
|
8
|
-
<span class="theme-swatch-mode">${
|
|
7
|
+
<span>${t.label}</span>
|
|
8
|
+
<span class="theme-swatch-mode">${t.dark?"Dark":"Light"}</span>
|
|
9
9
|
</div>
|
|
10
10
|
</div>
|
|
11
|
-
`);
|
|
11
|
+
`);s.on("click",()=>{e.find(".theme-swatch").removeClass("selected"),s.addClass("selected")}),a.append(s)}),e.find('[data-theme="charcoal-dark"]').addClass("selected")}function m(e){e.find("#ob-theme-skip").on("click",a=>{a.preventDefault(),r(e,"onboarding-done")}),e.find("#ob-theme-btn").on("click",async()=>{e.find("#ob-theme-error").hide();const a=e.find(".theme-swatch.selected").attr("data-theme")||"charcoal-dark",t=e.find("#ob-theme-btn").prop("disabled",!0).text("Applying\u2026");try{const s=await o.settings.get();await o.settings.save({...s,theme:a}),r(e,"onboarding-done")}catch(s){d(e,"ob-theme-error",s.message||"Could not save theme.")}finally{t.prop("disabled",!1).text("Apply theme")}})}function k(e){F.render("#login-form-container",h,{},{layout:"stacked",submitText:"Sign in",onSubmit:async a=>{try{const t=await o.auth.login(a);l(t),R.navigate("/")}catch(t){return E.toast(t.message||"Invalid credentials. Please try again.",{type:"error"}),!1}}}),e.find("#forgot-link").on("click",a=>{a.preventDefault(),r(e,"forgot"),C(e)})}function C(e){F.render("#forgot-form-container",g,{},{layout:"stacked",submitText:"Send reset link",onSubmit:async t=>{try{await o.auth.forgotPassword(t.email)}catch{}r(e,"forgot-success"),Domma.icons.scan()}});const a=t=>{t.preventDefault(),r(e,"login")};e.find("#forgot-back-link").on("click",a),e.find("#forgot-success-back-link").on("click",a)}function S(e,a){F.render("#reset-form-container",b,{},{layout:"stacked",submitText:"Set new password",onSubmit:async t=>{if(t.password!==t.confirmPassword)return E.toast("Passwords do not match.",{type:"error"}),!1;try{await o.auth.resetPassword(a,t.password),E.toast("Password updated. Please sign in.",{type:"success"}),window.location.hash="#/login"}catch(s){return E.toast(s.message||"Link expired or invalid.",{type:"error"}),!1}}})}
|