PageSourceSearch

https://harbor-os.com/assets/AdminNotificationSettings-BSS_ZPd5.js

js harbor-os.com collected 2026-10-02 01:34:10 UTC 16,549 bytes, 1 lines download raw bytes

1import{r as N,g as F,i as T,j as e,G as v,bZ as S,bD as H,M as I,dt as M,aV as G,bH as Q,c4 as W,aU as K}from"./vendor-B3bqREfz.js";import{u as Y,B as R,C as l,a as d,b as c,c as o,d as u,e as Z,I as g,g as x,f as V,q as z}from"./index-BHZdkTHk.js";import{A as D}from"./AdminLayout-C31anzfd.js";import{S as i}from"./switch-CEyu8DAw.js";import{L as n}from"./label-USjEtjxC.js";import{S as b,a as y,b as C,c as w,d as r}from"./select-CdK0CD7c.js";import"./harbor-shoppers-logo-BwiOLETu.js";import"./textarea-BFtGXtJd.js";function ie(){const{toast:j}=Y(),[m,O]=N.useState(!1),[k,P]=N.useState("claimed"),[A,B]=N.useState(""),{data:s,isLoading:L}=F({queryKey:["/api/admin/notification-settings"]}),{data:h,isLoading:U}=F({queryKey:["/api/admin/all-notification-settings"],enabled:m}),t=T({mutationFn:async a=>V("PATCH","/api/admin/notification-settings",a),onSuccess:()=>{z.invalidateQueries({queryKey:["/api/admin/notification-settings"]}),j({title:"Settings saved",description:"Your notification preferences have been updated."})},onError:()=>{j({title:"Error",description:"Failed to save settings.",variant:"destructive"})}}),f=T({mutationFn:async a=>(await V("POST","/api/admin/test-service-request-email",a)).json(),onSuccess:a=>{j({title:"Test email sent",description:(a==null?void 0:a.message)||"Check your inbox for the preview."})},onError:a=>{j({title:"Failed to send test email",description:(a==null?void 0:a.message)||"Check email configuration.",variant:"destructive"})}}),E={all:"All Notifications",digest:"Hourly Digest",important:"Important Only",none:"None"};return L?e.jsx(D,{children:e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(v,{className:"h-8 w-8 animate-spin text-muted-foreground"})})}):e.jsx(D,{children:e.jsxs("div",{className:"p-6 space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(S,{className:"h-6 w-6"}),"Notification Settings"]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"Configure how you receive alerts for support requests"})]}),e.jsxs(R,{variant:m?"secondary":"outline",onClick:()=>O(!m),children:[e.jsx(H,{className:"h-4 w-4 mr-2"}),m?"Hide":"Manage"," All Admins"]})]}),e.jsxs("div",{className:"grid gap-6 lg:grid-cols-2",children:[e.jsxs(l,{children:[e.jsxs(d,{children:[e.jsxs(c,{className:"flex items-center gap-2",children:[e.jsx(I,{className:"h-5 w-5"}),"Email Notifications"]}),e.jsx(o,{children:"Receive support alerts via email"})]}),e.jsxs(u,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(n,{htmlFor:"emailEnabled",children:"Enable Email Notifications"}),e.jsx(i,{id:"emailEnabled",checked:(s==null?void 0:s.emailEnabled)??!0,onCheckedChange:a=>t.mutate({emailEnabled:a})})]}),(s==null?void 0:s.emailEnabled)&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{children:"Email Frequency"}),e.jsxs(b,{value:(s==null?void 0:s.emailFrequency)??"all",onValueChange:a=>t.mutate({emailFrequency:a}),children:[e.jsx(y,{children:e.jsx(C,{})}),e.jsxs(w,{children:[e.jsx(r,{value:"all",children:"All Notifications"}),e.jsx(r,{value:"digest",children:"Hourly Digest"}),e.jsx(r,{value:"important",children:"Important Only"}),e.jsx(r,{value:"none",children:"None"})]})]})]})})]})]}),e.jsxs(l,{children:[e.jsxs(d,{children:[e.jsxs(c,{className:"flex items-center gap-2",children:[e.jsx(M,{className:"h-5 w-5"}),"SMS Notifications"]}),e.jsx(o,{children:"Receive text message alerts for urgent items"})]}),e.jsxs(u,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(n,{htmlFor:"smsEnabled",children:"Enable SMS Notifications"}),e.jsx(i,{id:"smsEnabled",checked:(s==null?void 0:s.smsEnabled)??!1,onCheckedChange:a=>t.mutate({smsEnabled:a})})]}),(s==null?void 0:s.smsEnabled)&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"phoneNumber",children:"Phone Number"}),e.jsx(Z,{value:(s==null?void 0:s.phoneNumber)??"",onChange:a=>{t.mutate({phoneNumber:a||null})},placeholder:"123-4567"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{children:"SMS Frequency"}),e.jsxs(b,{value:(s==null?void 0:s.smsFrequency)??"important",onValueChange:a=>t.mutate({smsFrequency:a}),children:[e.jsx(y,{children:e.jsx(C,{})}),e.jsxs(w,{children:[e.jsx(r,{value:"all",children:"All Notifications"}),e.jsx(r,{value:"important",children:"Important Only"}),e.jsx(r,{value:"none",children:"None"})]})]})]})]}),!(s!=null&&s.smsEnabled)&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"SMS notifications require Twil
1io credentials to be configured."})]})]})]}),e.jsxs(l,{children:[e.jsxs(d,{children:[e.jsxs(c,{className:"flex items-center gap-2",children:[e.jsx(G,{className:"h-5 w-5"}),"Notification Types"]}),e.jsx(o,{children:"Choose which events trigger notifications"})]}),e.jsxs(u,{children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"New Support Thread"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When a user creates a new request"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyNewThread)??!0,onCheckedChange:a=>t.mutate({notifyNewThread:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"New Message"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When a user replies to a thread"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyNewMessage)??!0,onCheckedChange:a=>t.mutate({notifyNewMessage:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Thread Assigned"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When a thread is assigned to you"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyThreadAssigned)??!0,onCheckedChange:a=>t.mutate({notifyThreadAssigned:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"System Health Alerts"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Service down / recovery emails"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyHealthAlerts)??!0,onCheckedChange:a=>t.mutate({notifyHealthAlerts:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Backup Failures"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nightly DB dump failure alerts"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyBackupFailures)??!0,onCheckedChange:a=>t.mutate({notifyBackupFailures:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"New Service Orders"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Boat history / valuation orders"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyNewOrders)??!0,onCheckedChange:a=>t.mutate({notifyNewOrders:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Vessel Intakes"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"New vessel listing submissions"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyVesselIntakes)??!0,onCheckedChange:a=>t.mutate({notifyVesselIntakes:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"New User Signups"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Alert when someone creates a new account"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyNewSignups)??!0,onCheckedChange:a=>t.mutate({notifyNewSignups:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Login & Password Reset Activity"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Account lockouts, password reset requests/completions, and first login after a reset"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyAuthActivity)??!0,onCheckedChange:a=>t.mutate({notifyAuthActivity:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Checkout Issues"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Failed buyer checkouts and guest carts still inactive after 24 hours"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyCheckoutIssues)??!0,onCheckedChange:a=>t.mutate({notifyCheckoutIssues:a}),"data-testid":"switch-checkout-issues"})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"AI Feedback"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When a user submits AI Training & Feature Feedback (sparkle button)"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyAiFeedback)??!0,onCheckedChange:a=>t.mutate({notifyAiFeedback:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Daily AI Spend Summary"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Once-a-day rollup of AI token usage & estimated spend"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyAiSpendSummary)??!1,onCheckedChange:a=>t.mutate({notifyAiSpendSummary:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Monthly Gross Receipts Reminder"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Reminder on the 3rd if last month's VI Form 720 filing isn't marked filed yet"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyGrossReceiptsReminder)??!1,onCheckedChange:a=>t.mutate({notifyGrossReceiptsReminder:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Sold Duplicates Alert"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Daily scan — alert when duplicate sales escape dedup and inflate sold totals"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifySoldDuplicates)??!0,onCheckedChange:a=>t.mutate({notifySoldDuplicates:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"CrossPost Fill Health"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Alert when a verified platform's extension auto-fill success rate drops"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifyCrosspostFillHealth)??!0,onCheckedChange:a=>t.mutate({notifyCrosspostFillHealth:a})})]}),e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Daily Support Digest"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Once-a-day summary of support threads still waiting on a reply"})]}),e.jsx(i,{checked:(s==null?void 0:s.notifySupportDigest)??!1,onCheckedChange:a=>t.mutate({notifySupportDigest:a}),"data-testid":"switch-support-digest"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-4",children:"Tip: Turning these off only stops the emails. You'll still see every alert in the header bell."})]})]}),e.jsxs(l,{children:[e.jsxs(d,{children:[e.jsxs(c,{className:"flex items-center gap-2",children:[e.jsx(Q,{className:"h-5 w-5"}),"Quiet Hours"]}),e.jsx(o,{children:"Pause notifications during specific hours"})]}),e.jsxs(u,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(n,{htmlFor:"quietHoursEnabled",children:"Enable Quiet Hours"}),e.jsx(i,{id:"quietHoursEnabled",checked:(s==null?void 0:s.quietHoursEnabled)??!1,onCheckedChange:a=>t.mutate({quietHoursEnabled:a})})]}),(s==null?void 0:s.quietHoursEnabled)&&e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"quietStart",children:"Start Time"}),e.jsx(g,{id:"quietStart",type:"time",value:(s==null?void 0:s.quietHoursStart)??"22:00",onChange:a=>t.mutate({quietHoursStart:a.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"quietEnd",children:"End Time"}),e.jsx(g,{id:"quietEnd",type:"time",value:(s==null?void 0:s.quietHoursEnd)??"08:00",onChange:a=>t.mutate({quietHoursEnd:a.target.value})})]})]})]})]}),e.jsxs(l,{children:[e.jsxs(d,{children:[e.jsxs(c,{className:"flex items-center gap-2",children:[e.jsx(W,{className:"h-5 w-5"}),"Preview Service Request Email"]}),e.jsx(o,{children:"Send a test service request notification email to verify the template renders correctly"})]}),e.jsxs(u,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"testEmailVariant",children:"Vendor Variant"}),e.jsxs(b,{value:k,onValueChange:a=>P(a),children:[e.jsx(y,{id:"testEmailVariant",children:e.jsx(C,{})}),e.jsxs(w,{children:[e.jsx(r,{value:"claimed",children:"Claimed Vendor (Respond CTA)"}),e.jsx(r,{value:"unclaimed",children:"Unclaimed Vendor (Claim Profile CTA)"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'Claimed vendors see a "Respond to Request" button. Unclaimed vendors see a "Claim your profile" prompt.'})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"testEmailAddress",children:"Send to Email (optional)"}),e.jsx(g,{id:"testEmailAddress",type:"email",placeholder:"Leave blank to send to your account email",value:A,onChange:a=>B(a.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"If left blank, the email is sent to your admin account address."})]})]}),e.jsxs(R,{onClick:()=>f.mutate({variant:k,email:A||void 0}),disabled:f.isPending,className:"gap-2",children:[f.isPending?e.jsx(v,{className:"h-4 w-4 animate-spin"}):e.jsx(K,{className:"h-4 w-4"}),"Send Test Service Request Email"]})]})]}),m&&e.jsxs(l,{children:[e.jsxs(d,{children:[e.jsxs(c,{className:"flex items-center gap-2",children:[e.jsx(H,{className:"h-5 w-5"}),"All Admin Settings"]}),e.jsx(o,{children:"Manage notification preferences for all administrators"})]}),e.jsx(u,{children:U?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(v,{className:"h-6 w-6 animate-spin"})}):e.jsxs("div",{className:"space-y-4",children:[h==null?void 0:h.map(a=>{var p,q;return e.jsxs("div",{className:"p-4 border rounded-lg space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:((p=a.user)==null?void 0:p.fullName)||"Unknown Admin"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:(q=a.user)==null?void 0:q.email})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(x,{variant:a.emailEnabled?"default":"secondary",children:[e.jsx(I,{className:"h-3 w-3 mr-1"}),a.emailEnabled?E[a.emailFrequency]:"Off"]}),e.jsxs(x,{variant:a.smsEnabled?"default":"secondary",children:[e.jsx(M,{className:"h-3 w-3 mr-1"}),a.smsEnabled?E[a.smsFrequency]:"Off"]})]})]}),e.jsxs("div",{className:"flex gap-2 text-sm text-muted-foreground",children:[e.jsxs(x,{variant:a.notifyNewThread?"outline":"secondary",children:[a.notifyNewThread?"✓":"✗"," New Threads"]}),e.jsxs(x,{variant:a.notifyNewMessage?"outline":"secondary",children:[a.notifyNewMessage?"✓":"✗"," Messages"]}),e.jsxs(x,{variant:a.notifyThreadAssigned?"outline":"secondary",children:[a.notifyThreadAssigned?"✓":"✗"," Assigned"]})]})]},a.userId)}),(!h||h.length===0)&&e.jsx("p",{className:"text-center text-muted-foreground py-8",children:"No admin accounts found."})]})})]})]})})}export{ie as default};

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.