PageSourceSearch

https://skinnovation.at/assets/templates-B6bKjAXX.js

js skinnovation.at collected 2026-10-04 01:47:42 UTC 17,505 bytes, 15 lines download raw bytes

1import{aB as M,ap as C,h as x,aD as y,q as e,bj as $,bl as q,bm as z,bn as I,el as U,aE as N,X as Q,aZ as K,cu as f,em as V,eq as G,E as W}from"./index-BiZh21pO.js";import{u as E}from"./useMutation-De6n0Lgb.js";import{P as X}from"./PageHeader-Bh-FqFPp.js";import{S as Z}from"./Section-BTk9_oDV.js";import{E as J}from"./EmptyState-cDUcTfgq.js";import{B as Y}from"./badge-IbQmR9HU.js";import{D as ee,a as se,b as re,c as S}from"./dropdown-menu-CMlUkvT7.js";import{A as te,a as ae,b as ne,c as ie,d as le,e as oe,f as de,g as ce}from"./alert-dialog-DqDSlEsh.js";import{c as me,e as ue,f as pe,g as xe,h as he}from"./broadcast-compose.functions-8ViyLPGg.js";import{r as O,D as d}from"./render-BCAuLVEc.js";import{L as P}from"./label-CZT4tCBm.js";import{S as ge}from"./slider-CyOczyZk.js";import{B as be}from"./BroadcastEditor-2rHsw_8P.js";import{M as R}from"./preview-sandbox-G00bgf9T.js";import{S as je}from"./save-Dtypd3sS.js";import{P as fe}from"./plus-DZ46z9WM.js";import{F as H}from"./file-text-VggaLVdD.js";import{E as ve}from"./ellipsis-vertical-Cl_B1Ogk.js";import{P as L}from"./pencil-Cgizu50M.js";import{C as we}from"./copy-BNKkeZpn.js";import{T as ye}from"./trash-2-D_SwAcYq.js";import{E as Ne}from"./eye-DEuWdYKX.js";import"./index-DVYrm6bS.js";import"./chevron-right-CZVp6Zj_.js";import"./marked.esm-C-1ewrWj.js";import"./index-BdQq_4o_.js";import"./gap-cursor-backspace-guard-rgMxUtpd.js";import"./index-CnWvyyiv.js";import"./index-C7yKKq-w.js";import"./index-D5JdNXTt.js";import"./index-Dfmf9ZHt.js";import"./index-b9N3u8EA.js";import"./popover-C-o7gjyP.js";import"./square-kdCpf-R1.js";import"./text-align-justify-Dg3WObNd.js";import"./image-CfDvBGtW.js";import"./user-plus-BrGUd7XB.js";import"./arrow-down-BqPAsec4.js";import"./link-2-DsrBtU04.js";import"./heading-1-CB0_yoEX.js";import"./heading-3-CQCBaqH4.js";import"./list-3l9ciOCT.js";import"./text-align-end-JluTvqm8.js";import"./text-align-start-C66Bgqap.js";import"./mouse-pointer-click-ClG_5ZUt.js";import"./italic-Dwc4t1eO.js";import"./link-mFPFqhwW.js";import"./type-Dnn-t6km.js";import"./rows-3-nzKsaUaF.js";import"./minus-CyFtsFBm.js";import"./newspaper-tH9Y1YfE.js";import"./table-WqaMngUy.js";function F(t){return t.toLowerCase().normalize("NFKD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40)}function A(t){return{name:t?.name??"",slug:t?.slug??"",description:t?.description??"",subject_template:t?.subject_template??"",brand_variant:t?.brand_variant??"standard",preview_starter_body:t?.preview_starter_body??t?.body_markdown??"",design:t?.design&&Object.keys(t.design).length>0?t.design:d}}function Ce({open:t,mode:i,template:o,isSystem:m,onClose:l}){const c=M(),u=C(me),g=C(ue),[s,p]=x.useState(()=>A(o)),[b,w]=x.useState(!1);x.useEffect(()=>{t&&(p(A(o)),w(i==="edit"))},[t,o,i]),x.useEffect(()=>{i==="create"&&!b&&p(r=>({...r,slug:F(r.name)}))},[s.name,b,i]);const _=x.useMemo(()=>{const r=s.preview_starter_body.trim()?s.preview_starter_body:`# Sample heading
2
3This is a sample body rendered with the **${s.name||"new"}** template.
4
5- Lists work
6- **Bold** and *italic* work
7- [Links](https://skinnovation.at) work
8`;return O({subject:s.subject_template||s.name||"Preview subject",preheader:"Template preview - inbox preview text",bodyMarkdown:r,design:s.design}).html},[s]),v=E({mutationFn:async()=>{if(i==="create")return u({data:{name:s.name,slug:s.slug,description:s.description||null,subject_template:s.subject_template,brand_variant:s.brand_variant,design:s.design,preview_starter_body:s.preview_starter_body||null}});if(!o)throw new Error("Missing template id");return g({data:{id:o.id,...m?{}:{name:s.name},description:s.description||null,subject_template:s.subject_template,brand_variant:s.brand_variant,design:s.design,preview_starter_body:s.preview_starter_body||null}})},onSuccess:()=>{y.success(i==="create"?"Template created":"Template saved"),c.invalidateQueries({queryKey:["broadcast","templates"]}),l()},onError:r=>y.error(r.message)}),n=r=>p(a=>({...a,design:r(a.design)}));return e.jsx($,{open:t,onOpenChange:r=>!r&&l(),children:e.jsxs(q,{side:"right",className:"w-full max-w-[min(1280px,100vw)] sm:max-w-[min(1280px,100vw)] p-0 flex flex-col",children:[e.jsx(z,{className:"border-b border-border/60 px-6 py-4 shrink-0",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(I,{className:"text-base",children:i==="create"?"New template":`Edit · ${o?.name}`}),e.jsx(U,{className:"text-xs",children:"Brand shell shared across broadcasts. Edits apply to future sends."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(N,{variant:"ghost",size:"sm",onClick:l,children:[e.jsx(Q,{className:"mr-1.5 h-4 w-4"})," Cancel"]}),e.jsxs(N,{size:"sm",onClick:()=>v.mutate(),disabled:v.isPending||!s.name||i==="create"&&!s.slug,children:[v.isPending?e.jsx(K,{className:"mr-1.5 h-4 w-4 animate-spin"}):e.jsx(je,{className:"mr-1.5 h-4 w-4"}),"Save"]})]})]})}),e.jsxs("div",{className:"grid flex-1 min-h-0 gap-0 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]",children:[e.jsxs("div",{className:"overflow-y-auto border-r border-border/60 px-6 py-5 space-y-6",children:[e.jsxs(j,{label:"Identity",children:[e.jsxs(h,{label:"Name",children:[e.jsx(f,{value:s.name,onChange:r=>p({...s,name:r.target.value}),placeholder:"e.g. Investor Update",disabled:m}),m&&e.jsx("p",{className:"mt-1 text-[11px] text-muted-foreground",children:"System template - name is locked. Design and starter body are editable."})]}),e.jsxs(h,{label:"Slug",children:[e.jsx(f,{value:s.slug,onChange:r=>{w(!0),p({...s,slug:F(r.target.value)})},disabled:i==="edit",placeholder:"investor-update"}),e.jsx("p",{className:"mt-1 text-[11px] text-muted-foreground",children:"Used internally. Cannot be changed after creation."})]}),e.jsx(h,{label:"Description",children:e.jsx(V,{value:s.description,onChange:r=>p({...s,description:r.target.value}),rows:2,placeholder:"Short note for the team."})}),e.jsx(h,{label:"Default subject (optional)",children:e.jsx(f,{value:s.subject_template,onChange:r=>p({...s,subject_template:r.target.value}),placeholder:"[SKInnovation] …"})})]}),e.jsx(j,{label:"Brand colors",children:e.jsx("div",{className:"grid grid-cols-2 gap-3",children:[["background","Page background"],["card","Card / container"],["text","Body text"],["muted","Muted text"],["border","Borders / dividers"],["primary","Primary accent"],["accent","Secondary accent"]].map(([r,a])=>e.jsx(T,{label:a,value:s.design.colors?.[r]??d.colors[r],onChange:k=>n(B=>({...B,colors:{...d.colors,...B.colors,[r]:k}}))},r))})}),e.jsxs(j,{label:"Header",children:[e.jsx(h,{label:"Eyebrow text",children:e.jsx(f,{value:s.design.header?.eyebrow??"",onChange:r=>n(a=>({...a,header:{...d.header,...a.header,eyebrow:r.target.value}}))})}),e.jsx(h,{label:"Tagline",children:e.jsx(f,{value:s.design.header?.tagline??"",onChange:r=>n(a=>({...a,header:{...d.header,...a.header,tagline:r.target.value}}))})}),e.jsx(h,{label:"Logo URL (optional - replaces eyebrow if set)",children:e.jsx(f,{value:s.design.header?.logoUrl??"",onChange:r=>n(a=>({...a,header:{...d.header,...a.header,logoUrl:r.target.value||null}})),placeholder:"https://…"})}),e.jsx(h,{label:"Align",children:e.jsx("div",{className:"flex rounded-md border border-border/60 p-0.5 w-fit",children:["left","center"].map(r=>e.jsx("button",{type:"button",onClick:()=>n(a=>({...a,header:{...d.header,...a.header,align:r}})),className:`rounded px-3 py-1 text-xs capitalize ${(s.design.header?.align??"left")===r?"bg-muted text-foreground":"text-muted-foreground"}`,children:r},r))})})]}),e.jsxs(j,{label:"Footer",children:[e.jsx(h,{label:"Address / legal line (supports {{year}})",children:e.jsx(f,{value:s.design.footer?.addressLine??"",onChange:r=>n(a=>({...a,footer:{...d.footer,...a.footer,addressLine:r.target.value}}))})}),e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-border/60 px-3 py-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium",children:"Show unsubscribe link"}),e.jsx("div",{className:"text-[11px] text-muted-foreground",children:"Recommended. Required for non-transactional sends."})]}),e.jsx(G,{checked:s.design.footer?.showUnsubscribe??!0,onCheckedChange:r=>n(a=>({...a,footer:{...d.footer,...a.footer,showUnsubscribe:r}}))})]})]}),e.jsxs(j,{label:"Button style",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(T,{label:"Backgroun
8d",value:s.design.button?.background??d.button.background,onChange:r=>n(a=>({...a,button:{...d.button,...a.button,background:r}}))}),e.jsx(T,{label:"Text",value:s.design.button?.text??d.button.text,onChange:r=>n(a=>({...a,button:{...d.button,...a.button,text:r}}))})]}),e.jsx(D,{label:`Corner radius - ${s.design.button?.radiusPx??6}px`,min:0,max:24,value:s.design.button?.radiusPx??6,onChange:r=>n(a=>({...a,button:{...d.button,...a.button,radiusPx:r}}))})]}),e.jsx(j,{label:"Typography",children:e.jsx("div",{className:"flex flex-wrap gap-2",children:[["system","System sans"],["inter","Inter"],["serif","Serif"]].map(([r,a])=>e.jsx("button",{type:"button",onClick:()=>n(k=>({...k,typography:{fontStack:r}})),className:`rounded-md border px-3 py-1.5 text-xs ${(s.design.typography?.fontStack??"system")===r?"border-primary bg-primary/10 text-foreground":"border-border/60 text-muted-foreground hover:bg-muted"}`,children:a},r))})}),e.jsxs(j,{label:"Container",children:[e.jsx(D,{label:`Width - ${s.design.container?.widthPx??600}px`,min:480,max:720,step:20,value:s.design.container?.widthPx??600,onChange:r=>n(a=>({...a,container:{...d.container,...a.container,widthPx:r}}))}),e.jsx(D,{label:`Corner radius - ${s.design.container?.radiusPx??8}px`,min:0,max:24,value:s.design.container?.radiusPx??8,onChange:r=>n(a=>({...a,container:{...d.container,...a.container,radiusPx:r}}))})]}),e.jsx(j,{label:"Starter body (used when creating a new broadcast)",children:e.jsx(be,{value:s.preview_starter_body,onChange:r=>p(a=>({...a,preview_starter_body:r})),placeholder:"Optional default content for new broadcasts using this template…",dividerColor:s.design.colors?.background??d.colors.background})})]}),e.jsxs("div",{className:"overflow-y-auto bg-muted/30 px-6 py-5",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wider text-muted-foreground mb-2",children:"Live preview"}),e.jsx("div",{className:"overflow-hidden rounded-md border border-border/60 bg-white",children:e.jsx("iframe",{title:"Template preview",srcDoc:_,sandbox:R,style:{width:"100%",height:"75vh",border:0,background:"#fff",display:"block"}})})]})]})]})})}function j({label:t,children:i}){return e.jsxs("section",{className:"space-y-3",children:[e.jsx("h3",{className:"text-[11px] uppercase tracking-wider text-muted-foreground",children:t}),e.jsx("div",{className:"space-y-3",children:i})]})}function h({label:t,children:i}){return e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(P,{className:"text-xs font-medium",children:t}),i]})}function T({label:t,value:i,onChange:o}){const[m,l]=x.useState(i);return x.useEffect(()=>l(i),[i]),e.jsxs("div",{className:"space-y-1",children:[e.jsx(P,{className:"text-[11px] text-muted-foreground",children:t}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"color",value:/^#[0-9a-fA-F]{6}$/.test(m)?m:"#000000",onChange:c=>{l(c.target.value),o(c.target.value)},className:"h-8 w-10 cursor-pointer rounded border border-border/60 bg-transparent p-0"}),e.jsx(f,{value:m,onChange:c=>{const u=c.target.value;l(u),/^#[0-9a-fA-F]{6}$/.test(u)&&o(u)},className:"h-8 font-mono text-xs"})]})]})}function D({label:t,min:i,max:o,step:m=1,value:l,onChange:c}){return e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(P,{className:"text-[11px] text-muted-foreground",children:t}),e.jsx(ge,{min:i,max:o,step:m,value:[l],onValueChange:u=>c(u[0])})]})}function _s(){const t=C(pe),i=M(),o=C(xe),m=C(he),l=W({queryKey:["broadcast","templates"],queryFn:()=>t(),staleTime:6e4}),[c,u]=x.useState(null),g=c?l.data?.find(n=>n.slug===c)??null:null,[s,p]=x.useState(null),[b,w]=x.useState(null),_=E({mutationFn:n=>m({data:{id:n}}),onSuccess:()=>{y.success("Template duplicated"),i.invalidateQueries({queryKey:["broadcast","templates"]})},onError:n=>y.error(n.message)}),v=E({mutationFn:n=>o({data:{id:n}}),onSuccess:()=>{y.success("Template deleted"),i.invalidateQueries({queryKey:["broadcast","templates"]}),w(null)},onError:n=>y.error(n.message)});return e.jsxs("div",{className:"space-y-6",children:[e.jsx(X,{eyebrow:"Broadcast",title:"Templates",subtitle:"Reusable brand shells: colors, header, footer, button style. Edit to tune any template; new broadcasts inherit the design.",actions:e.jsxs(N,{size:"sm",onClick:()=>p({mode:"create",template:null}),children:[e.jsx(fe,{className:"mr-1.5 h-4 w-4"})," New template"]})}),e.jsx(Z,{title:"Library",description:l.isLoading?"Loading…":`${l.data?.length??0} template${(l.data?.length??0)===1?"":"s"} available.`,children:l.isLoading?e.jsxs("div",{className:"flex h-32 items-center justify-center text-sm text-muted-foreground",children:[e.jsx(K,{className:"mr-2 h-4 w-4 animate-spin"})," Loading templates…"]}):!l.data||l.data.length===0?e.jsx(J,{icon:H,title:"No templates yet",description:"Create your first brand shell to share across broadcasts."}):e.jsx("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:l.data.map(n=>e.jsx(_e,{template:n,onPreview:()=>u(n.slug),onEdit:()=>p({mode:"edit",template:n}),onDuplicate:()=>_.mutate(n.id),onDelete:()=>w(n)},n.id))})}),e.jsx($,{open:!!g,onOpenChange:n=>!n&&u(null),children:e.jsx(q,{side:"right",className:"w-full max-w-2xl sm:max-w-2xl",children:g&&e.jsx(ke,{template:g})})}),s&&e.jsx(Ce,{open:!0,mode:s.mode,template:s.template,isSystem:!!s.template?.is_system,onClose:()=>p(null)}),e.jsx(te,{open:!!b,onOpenChange:n=>!n&&w(null),children:e.jsxs(ae,{children:[e.jsxs(ne,{children:[e.jsx(ie,{children:"Delete template?"}),e.jsxs(le,{children:[b?.name?e.jsxs(e.Fragment,{children:["This permanently removes ",e.jsx("strong",{children:b.name}),"."," "]}):null,"Broadcasts that already reference it will block the delete."]})]}),e.jsxs(oe,{children:[e.jsx(de,{children:"Cancel"}),e.jsx(ce,{onClick:()=>b&&v.mutate(b.id),disabled:v.isPending,children:v.isPending?"Deleting…":"Delete"})]})]})})]})}function _e({template:t,onPreview:i,onEdit:o,onDuplicate:m,onDelete:l}){const c=t.design?.colors??{}
8,u=[c.primary,c.accent,c.background].filter(Boolean);return e.jsxs("div",{className:"flex flex-col gap-3 rounded-[var(--radius)] border border-border/60 bg-card p-4 shadow-[var(--shadow-app-xs)]",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"grid h-7 w-7 place-items-center rounded-md bg-primary/10 text-primary",children:e.jsx(H,{className:"h-3.5 w-3.5"})}),e.jsx("h3",{className:"truncate text-sm font-semibold text-foreground",children:t.name})]}),e.jsx("p",{className:"mt-1 truncate text-xs text-muted-foreground",children:t.slug})]}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[t.is_system&&e.jsx(Y,{variant:"secondary",className:"text-[10px]",children:"System"}),e.jsxs(ee,{children:[e.jsx(se,{asChild:!0,children:e.jsx(N,{variant:"ghost",size:"icon",className:"h-7 w-7",children:e.jsx(ve,{className:"h-4 w-4"})})}),e.jsxs(re,{align:"end",children:[e.jsxs(S,{onClick:o,children:[e.jsx(L,{className:"mr-2 h-3.5 w-3.5"})," Edit"]}),e.jsxs(S,{onClick:m,children:[e.jsx(we,{className:"mr-2 h-3.5 w-3.5"})," Duplicate"]}),e.jsxs(S,{onClick:l,disabled:t.is_system,className:"text-destructive focus:text-destructive",children:[e.jsx(ye,{className:"mr-2 h-3.5 w-3.5"})," Delete"]})]})]})]})]}),t.description&&e.jsx("p",{className:"text-xs text-muted-foreground line-clamp-2",children:t.description}),u.length>0&&e.jsx("div",{className:"flex items-center gap-1",children:u.map((g,s)=>e.jsx("span",{className:"h-4 w-4 rounded-full border border-border/60",style:{background:g},title:g},s))}),e.jsxs("div",{className:"flex items-center justify-between border-t border-border/60 pt-3 text-[11px] text-muted-foreground",children:[e.jsxs("span",{children:["Variant: ",t.brand_variant]}),e.jsx("span",{children:new Date(t.updated_at).toLocaleDateString()})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs(N,{variant:"outline",size:"sm",onClick:i,children:[e.jsx(Ne,{className:"mr-1.5 h-3.5 w-3.5"})," Preview"]}),e.jsxs(N,{variant:"outline",size:"sm",onClick:o,children:[e.jsx(L,{className:"mr-1.5 h-3.5 w-3.5"})," Edit"]})]})]})}function ke({template:t}){const i=x.useMemo(()=>t.preview_starter_body||t.body_markdown||`# Sample heading
9
10This is a sample body rendered with the **${t.name}** template shell.
11
12- Bullet one
13- Bullet two
14
15[Call to action](https://skinnovation.at)`,[t]),o=x.useMemo(()=>O({subject:t.subject_template||t.name,preheader:"Template preview - inbox preview text",bodyMarkdown:i,design:t.design}).html,[t,i]);return e.jsxs(e.Fragment,{children:[e.jsxs(z,{children:[e.jsx(I,{children:t.name}),e.jsxs(U,{children:["Subject template: ",e.jsx("code",{children:t.subject_template||"(none)"})]})]}),e.jsx("div",{className:"mt-4 overflow-hidden rounded-md border border-border/60 bg-muted/20 p-2",children:e.jsx("iframe",{title:`${t.name} preview`,srcDoc:o,sandbox:R,style:{width:"100%",height:"70vh",border:0,background:"#fff",display:"block"}})})]})}export{_s as component};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.