PageSourceSearch

https://time2display.com/assets/dashboard-cM54T5f7.js

js time2display.com collected 2026-10-08 02:33:35 UTC 8,053 bytes, 1 lines download raw bytes

1import{m as j,n as f,u as v,r as N,g as k,j as e,q as w,b}from"./index-WJxreSlX.js";import{u as _}from"./useQuery-Cfle00VR.js";import{P as y}from"./HubShell-a_WAbMW_.js";import{r as S}from"./auth-middleware-Cm2paKoS.js";import{C as l}from"./card-DLmBESU3.js";import{B as T}from"./badge-DIoDE1GD.js";import{T as $,a as C,b as L}from"./tabs-KKv84lCN.js";import{P as A}from"./pound-sterling-BgZWsFK3.js";import{T as D}from"./trending-up-BLf6dKlx.js";import{B as p}from"./briefcase-DyCWnG1B.js";import{C as F}from"./circle-check-cag_Hajd.js";import{A as O}from"./activity-BnzSoFqb.js";import{S as R}from"./search-ovhzUuQX.js";import{U as E}from"./users-round-Bl5R2UtQ.js";import{T as G}from"./triangle-alert-C-Bw-9GO.js";import{M as P}from"./megaphone-DTIkLW0w.js";import{M as B}from"./message-square-CmSsFT0w.js";import"./index-D7UQnXBk.js";import"./index-Bscs8OO-.js";import"./index-mkR8ks2f.js";const M=j({method:"POST"}).middleware([S]).handler(f("9c929fe02616e891d8266ed4e1996231dd6fe950b4226ee5d91999d61fa8a419")),x={month:"This month","30d":"Last 30 days",ytd:"FYTD","12m":"Last 12 months",year:"This FY (Aug–Jul)",last_year:"Last FY"},g=t=>new Intl.NumberFormat("en-GB",{style:"currency",currency:"GBP",maximumFractionDigits:0}).format(t||0);function h(t){return t>=80?"text-emerald-600":t>=65?"text-pink":t>=50?"text-amber-600":"text-red-600"}function oe(){const{user:t}=v(),r=t?.user_metadata?.full_name||t?.email?.split("@")[0]||"there",[n,d]=N.useState("ytd"),m=k(M),o=_({queryKey:["dashboard-highlights",n],queryFn:()=>m({data:{range:n}})}),s=o.data;return e.jsxs("div",{children:[e.jsx(y,{eyebrow:`Welcome back, ${r}`,title:"Group dashboard",description:"Live highlights from every hub — finance, jobs, marketing and brand health at a glance."}),e.jsxs("div",{className:"space-y-6 p-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"Revenue & profit window"}),e.jsx($,{value:n,onValueChange:a=>d(a),children:e.jsx(C,{children:Object.keys(x).map(a=>e.jsx(L,{value:a,children:x[a]},a))})})]}),o.isLoading&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(w,{className:"h-4 w-4 animate-spin"})," Loading highlights…"]}),o.isError&&e.jsxs(l,{className:"p-4 text-sm text-red-600",children:["Couldn't load dashboard data. ",o.error?.message]}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[e.jsx(i,{icon:e.jsx(A,{className:"h-5 w-5"}),label:`Revenue — ${s.finance&&"label"in s.finance?s.finance.label:x[n]}`,value:s.finance.connected?g(s.finance.revenue):"Xero not connected",sub:s.finance.connected?s.finance.gross_margin_pct!==null?`Gross margin ${s.finance.gross_margin_pct}%`:"—":"Connect Xero in Settings",tone:"pink"}),e.jsx(i,{icon:e.jsx(D,{className:"h-5 w-5"}),label:"Net profit",value:s.finance.connected?g(s.finance.net):"—",sub:s.finance.connected&&s.finance.net_margin_pct!==null?`Net margin ${s.finance.net_margin_pct}%`:"—",tone:s.finance.connected&&s.finance.net_margin_pct!==null&&s.finance.net_margin_pct>=0?"green":"amber"}),e.jsx(i,{icon:e.jsx(p,{className:"h-5 w-5"}),label:"Open jobs",value:s.jobs?.open??"—",sub:s.jobs?`${s.jobs.total} jobs in system`:"No access",tone:"pink"}),e.jsx(i,{icon:e.jsx(F,{className:"h-5 w-5"}),label:"Jobs completed",value:s.jobs?.completed_in_range??"—",sub:s.jobs?s.jobs.completed_range_label:"No access",tone:"green"}),e.jsx(i,{icon:e.jsx(O,{className:"h-5 w-5"}),label:"Digital voice score",value:s.digital_voice?.combined??"—",sub:s.digital_voice?s.digital_voice.brands.map(a=>`${a.name}: ${a.score}`).join(" · "):"Marketing hub only",tone:"pink",accent:s.digital_voice?h(s.digital_voice.combined):void 0}),e.jsx(i,{icon:e.jsx(R,{className:"h-5 w-5"}),label:"SEO / GEO score",value:s.seo?.score??"—",sub:s.seo?`Updated ${new Date(s.seo.updated_at).toLocaleDateString()}`:"Run an audit in Admin → GEO",tone:"pink",accent:s.seo?h(s.seo.score):void 0}),e.jsx(i,{icon:e.jsx(E,{className:"h-5 w-5"}),label:"Contacts",value:s.crm?.contacts??"—",sub:s.crm?`+${s.crm.new_30d} new in 30 days`:"CRM hub only",tone:"pink"}),e.jsx(i,{icon:e.jsx(G,{className:"h-5 w-5"}),label:"Open tasks",value:s.tasks.open,sub:s.tasks.overdue?`${s.tasks.overdue} overdue`:"All on schedule",tone:s.tasks.overdue?"amber":"green"})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-3",children:[s.marketing&&e.jsxs(l,{className:"p-5",children:[e.jsx(u,{icon:e.jsx(P,{className:"h-4 w-4"}),label:"Marketing",to:"/marketing"}),e.jsxs("div",{className:"mt-4 grid grid-cols-3 gap-3 text-center",children:[e.jsx(c,{label:"Campaigns sent",value:s.marketing.campaigns_sent}),e.jsx(c,{label:"Open rate",value:`${s.marketing.open_rate_pct}%`}),e.jsx(c,{label:"Clicks",value:s.marketing.clicks})]}),e.jsxs("div",{className:"mt-4 space-y-2",children:[s.marketing.recent_campaigns.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"No campaigns yet."}),s.marketing.recent_campaigns.map(a=>e.jsxs(b,{to:"/sales/campaigns/$id",params:{id:a.id},className:"flex items-center justify-between rounded-md border p-2 text-sm hover:border-pink",children:[e.jsx("span",{className:"line-clamp-1 font-medium",children:a.name}),e.jsx(T,{variant:"outline",className:"text-[10px] uppercase",children:a.status})]},a.id))]})]}),s.mentions&&e.jsxs(l,{className:"p-5",children:[e.jsx(u,{icon:e.jsx(B,{className:"h-4 w-4"}),label:"Online mentions",to:"/marketing/mentions"}),e.jsxs("div",{className:"mt-4 grid grid-cols-3 gap-3 text-center",children:[e.jsx(c,{label:"Total",value:s.mentions.total}),e.jsx(c,{label:"Positive",value:s.mentions.positive,tone:"text-emerald-600"}),e.jsx(c,{label:"New 30d",value:s.mentions.new_30d})]}),e.jsx("p",{className:"mt-4 text-xs text-muted-foreground",children:"Signal across news, social, forums and directories for Time 2 Display Group and Fordingbridge Print."})]}),s.jobs&&e.jsxs(l,{className:"p-5",children:[e.jsx(u,{icon:e.jsx(p,{className:"h-4 w-4"}),label:"Upcoming jobs",to:"/jobs"}),e.jsxs("div",{className:"mt-4 space-y-2",children:[s.jobs.upcoming.length===0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"No open jobs scheduled."}),s.jobs.upcoming.map(a=>e.jsxs("div",{className:"flex items-start justify-between rounded-md border p-2 text-sm",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"line-clamp-1 font-medium",children:a.title||a.client}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["#",a.job_number," · ",a.client]})]}),e.jsx("div",{className:"ml-3 whitespace-nowrap text-xs text-muted-foreground",children:a.job_date?new Date(a.job_date).toLocaleDateString():"—"})]},a.id))]})]})]})]})]})]})}function i({icon:t,label:r,value:n,sub:d,tone:m="pink",accent:o}){const s=m==="green"?"text-emerald-600 bg-emerald-50":m==="amber"?"text-amber-600 bg-amber-50":"text-pink bg-pink/10";return e.jsxs(l,{className:"p-5",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("div",{className:`rounded-md p-2 ${s}`,children:t})}),e.jsx("div",{className:"mt-3 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",children:r}),e.jsx("div",{className:`mt-1 text-2xl font-bold tabular-nums ${o??""}`,children:n}),d&&e.jsx("div",{className:"mt-1 text-xs text-muted-foreground",children:d})]})}function c({label:t,value:r,tone:n}){return e.jsxs("div",{children:[e.jsx("div",{className:`text-xl font-bold tabular-nums ${n??""}`,children:r}),e.jsx("div",{className:"text-[10px] uppercase tracking-wider text-muted-foreground",children:t})]})}function u({icon:t,label:r,to:n}){return e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm font-semibold uppercase tracking-wider text-muted-foreground",children:[t,r]}),e.jsx(b,{to:n,className:"text-xs font-medium text-pink hover:underline",children:"Open →"})]})}
1export{oe 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.