PageSourceSearch

https://gentlebirth.com/assets/AdminNicoleDMs-CkDIAmvz.js

js gentlebirth.com collected 2026-10-01 16:05:58 UTC 28,519 bytes, 6 lines download raw bytes

1import{ao as Te,au as b,j as e,C as p,b as f,K as B,a8 as q,a9 as D,M as $e,aD as Ee,W as g,_ as ve,I as h,h as Re,aH as Ae,r as x,aG as J,c as me,a$ as ue,aR as Be,a0 as he,B as w,bb as Oe,g as Ie,ap as xe,ar as pe,as as fe,at as ge,aJ as _e,$ as Y,a2 as Pe,aK as je,J as M}from"./index-CwRyDTkN.js";import{S as Ke,a as Ue,b as He,c as Qe,d as Je}from"./select-DwBWUARa.js";import{R as Ve}from"./radio-CtXsDiPg.js";import{M as We}from"./message-square-reply-ppPqlRtG.js";import{C as ze}from"./clock-BNPp408a.js";import{C as Ge}from"./calendar-check-Vg3Azpu7.js";import{B as Ze}from"./bell-off-DGXEwFdj.js";import{C as ee}from"./circle-pause-BrEw_GK4.js";import{S as Xe}from"./shield-alert-C0Nv_DK_.js";import{A as Ye}from"./activity-Cmbc8AKR.js";import{C as es}from"./circle-play-C2xFWbS2.js";import"./chevron-up-iCYBxH0c.js";/**
2 * @license lucide-react v0.553.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const ss=[["path",{d:"m15 17 5-5-5-5",key:"nf172w"}],["path",{d:"M4 18v-2a4 4 0 0 1 4-4h12",key:"jmiej9"}]],Ne=Te("forward",ss);function V(i){return i?new Date(i).toLocaleString():"never"}function W(i,o){return o?Math.round(i/o*1e3)/10:0}function N({label:i,value:o,hint:a,accent:r}){return e.jsxs("div",{className:"rounded-lg border border-border bg-card p-4",children:[e.jsx("div",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:i}),e.jsx("div",{className:`mt-1 text-2xl font-semibold ${r?"text-primary":""}`,children:o}),a&&e.jsx("div",{className:"mt-1 text-xs text-muted-foreground",children:a})]})}function ts(){const{data:i,isLoading:o,error:a}=b({queryKey:["nicole-outreach-metrics"],refetchInterval:12e4,queryFn:async()=>{const{data:_,error:j}=await h.rpc("nicole_outreach_metrics");if(j)throw j;return _}});if(o)return e.jsx(p,{children:e.jsxs(f,{className:"flex items-center justify-center gap-2 p-10 text-muted-foreground",children:[e.jsx(B,{className:"h-4 w-4 animate-spin"})," Loading outreach results…"]})});if(a||!i)return e.jsx(p,{children:e.jsxs(f,{className:"p-6 text-sm text-destructive",children:["Could not load outreach results: ",(a==null?void 0:a.message)??"unknown error"]})});const{emails:r,email_steps:y,dms:d,autonomous:l}=i,S=W(d.conversations,r.families_emailed),F=W(d.families_replied,r.families_emailed),L=l.outreach_sent===0&&(l.decisions_total??0)===0;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(p,{children:[e.jsxs(q,{className:"pb-3",children:[e.jsxs(D,{className:"flex items-center gap-2 text-base",children:[e.jsx($e,{className:"h-4 w-4"})," Outreach and response"]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"What Nicole actually sent, and what came back. Emails below are the nurture sequence; chats are DM Nicole threads."})]}),e.jsxs(f,{className:"space-y-6",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[e.jsx(N,{label:"Emails sent",value:r.sent_total.toLocaleString(),hint:`${r.sent_7d.toLocaleString()} in the last 7 days`}),e.jsx(N,{label:"Families emailed",value:r.families_emailed.toLocaleString(),hint:`first ${V(r.first_sent_at)}`}),e.jsx(N,{label:"Started a chat",value:`${d.conversations.toLocaleString()} · ${S}%`,hint:"of families emailed opened a DM thread",accent:!0}),e.jsx(N,{label:"Replied in chat",value:`${d.families_replied.toLocaleString()} · ${F}%`,hint:`last reply ${V(d.last_family_message_at)}`,accent:!0})]}),e.jsxs("div",{children:[e.jsx("div",{className:"mb-2 text-sm font-medium",children:"Nurture sequence progress"}),e.jsx("div",{className:"space-y-3",children:y.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No nurture emails sent yet."}):y.map(_=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:["Step ",_.step]}),e.jsxs("span",{className:"font-medium",children:[_.sent.toLocaleString()," sent",e.jsxs("span",{className:"ml-2 text-xs font-normal text-muted-foreground",children:["last ",V(_.last_sent_at)]})]})]}),e.jsx(Ee,{value:W(_.sent,r.families_emailed),className:"h-2"})]},_.step))}),r.failed>0&&e.jsxs("p",{className:"mt-3 text-xs text-destructive",children:[r.failed.toLocaleStr
6ing()," sends did not complete successfully."]})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-3",children:[e.jsx(N,{label:"Messages Nicole wrote",value:d.from_nicole.toLocaleString()}),e.jsx(N,{label:"Messages families wrote",value:d.from_families.toLocaleString()}),e.jsx(N,{label:"Messages per conversation",value:d.conversations?Math.round(d.messages_total/d.conversations*10)/10:0})]})]})]}),e.jsxs(p,{className:L?"border-destructive/40":void 0,children:[e.jsxs(q,{className:"pb-3",children:[e.jsxs(D,{className:"flex flex-wrap items-center gap-2 text-base",children:[e.jsx(Ve,{className:"h-4 w-4"})," Autonomous continuing care",L?e.jsxs(g,{variant:"destructive",className:"gap-1",children:[e.jsx(ve,{className:"h-3 w-3"})," Nothing sent yet"]}):e.jsx(g,{variant:"secondary",children:"Active"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"The hourly relationship loop — separate from the fixed nurture sequence above."})]}),e.jsxs(f,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[e.jsx(N,{label:"Decisions evaluated",value:l.decisions_total.toLocaleString(),hint:`${l.decisions_7d.toLocaleString()} in the last 7 days`}),e.jsx(N,{label:"Chose silence",value:l.decisions_no_action.toLocaleString(),hint:"deliberate no-action outcomes"}),e.jsx(N,{label:"Messages sent",value:l.outreach_sent.toLocaleString(),hint:l.outreach_failed>0?`${l.outreach_failed} failed`:void 0}),e.jsx(N,{label:"Responses received",value:`${l.outreach_responded.toLocaleString()} · ${W(l.outreach_responded,l.outreach_sent)}%`,hint:"of autonomous sends got a reply",accent:!0})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(We,{className:"h-4 w-4"}),"Last loop run: ",e.jsx("span",{className:"font-medium text-foreground",children:V(l.last_run_at)}),l.last_run_status&&e.jsx(g,{variant:"outline",className:"text-[10px]",children:l.last_run_status})]}),l.last_run_error&&e.jsxs("p",{className:"text-xs text-destructive",children:["Last error: ",l.last_run_error]}),L&&e.jsx("p",{className:"rounded-md bg-destructive/10 p-3 text-sm text-foreground",children:"The hourly loop is scheduled and running, but it has not recorded a single decision or send. Everything reported above came from the fixed nurture sequence — the relationship intelligence layer is not yet reaching anyone."})]})]})]})}const as="nicole_continuing_care_autonomous";function rs(i){if(!i)return"never";const o=Date.now()-new Date(i).getTime(),a=Math.round(o/6e4);if(a<1)return"just now";if(a<60)return`${a}m ago`;const r=Math.round(a/60);return r<48?`${r}h ago`:`${Math.round(r/24)}d ago`}function ns(){const{data:i,isLoading:o}=b({queryKey:["nicole-run-status"],refetchInterval:6e4,queryFn:async()=>{const L=new Date(Date.now()-1728e5).toISOString(),[_,j]=await Promise.all([h.from("nicole_job_runs").select("status, last_started_at, last_finished_at, last_error, items_processed, paused_reason").eq("job_name",as).maybeSingle(),h.from("nicole_outreach_events").select("status").gte("created_at",L)]),k=new Map;for(const P of j.data??[]){const T=String(P.status??"unknown");k.set(T,(k.get(T)??0)+1)}return{run:_.data,counts:k}}});if(o)return e.jsx(p,{children:e.jsxs(f,{className:"flex items-center gap-2 py-4 text-sm text-muted-foreground",children:[e.jsx(B,{className:"h-4 w-4 animate-spin"})," Checking Nicole's last run…"]})});const a=i==null?void 0:i.run,r=(i==null?void 0:i.counts)??new Map,y=(r.get("sent")??0)+(r.get("delivered")??0),d=r.get("blocked")??0,l=r.get("failed")??0,S=(a==null?void 0:a.last_error)??null,F=!!S||!!(a!=null&&a.paused_reason)||d>0||l>0;return e.jsx(p,{className:F?"border-amber-300":void 0,children:e.jsxs(f,{className:"space-y-3 py-5",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[F?e.jsx(ve,{className:"h-5 w-5 text-amber-500"}):e.jsx(Re,{className:"h-5 w-5 text-emerald-600"}),e.jsx("span",{className:"font-medium",children:"Nicole's outreach loop"}),e.jsxs(g,{variant:"outline",className:"gap-1",children:[e.jsx(ze,{className:"h-3 w-3"})," runs every 48 hours"]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["Last run ",rs((a==null?void 0:a.last_finished_at)??(a==null?void 0:a.last_started_at)??null),typeof(a==null?void 0:a.items_processed)=="number"?` · ${a.items_processed} families considered`:""]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 text-sm",children:[e.jsxs(g,{variant:"secondary",children:[y," sent (last 48h)"]}),d>0&&e.jsxs(g,{variant:"destructive",children:[d," held by content policy"]}),l>0&&e.jsxs(g,{variant:"destructive",children:[l," failed to send"]})]}),(a==null?void 0:a.paused_reason)&&e.jsxs("p",{className:"text-sm text-amber-700",children:["Paused: ",a.paused_reason]}),S&&e.jsxs("p",{className:"text-sm text-amber-700",children:["Last run note: ",S]})]})})}const is={rate_limited:"Rate limit",duplicate_message:"Duplicate message",admin_pause:"Admin pause"},os=[{label:"1 hour",hours:1},{label:"24 hours",hours:24},{label:"7 days",hours:24*7},{label:"30 days",hours:24*30},{label:"Forever (until I restore it)",hours:0}],ls="9999-12-31T23:59:59.000Z",cs=10*365*24*36e5;function ds(i){const o=new Date(i).getTime()-Date.now();if(o<=0)return"expired";if(o>cs)return"forever";const a=Math.round(o/6e4);if(a<60)return`${a}m left`;const r=Math.round(a/60);return r<48?`${r}h left`:`${Math.round(r/24)}d left`}function ye(i){const o=Date.now()-new Date(i).getTime(),a=Math.round(o/6e4);if(a<1)return"just now";if(a<60)return`${a}m ago`;const r=Math.round(a/60);return r<48?`${r}h ago`:`${Math.round(r/24)}d ago`}function ms(i){return Array.isArray(i)?i.map(o=>
6{if(typeof o=="string")return o;if(!o||typeof o!="object")return"";const a=o;return String(a.label??a.summary??a.topic??a.question??"Open item")}).filter(Boolean):[]}function bs(){const i=Ae(),[o,a]=x.useState(""),[r,y]=x.useState(null),[d,l]=x.useState("24"),[S,F]=x.useState("Messaging is paused after repeated spam protection triggers."),[L,_]=x.useState(null),[j,k]=x.useState(null),[P,T]=x.useState(""),{data:K=[],isLoading:we}=b({queryKey:["nicole-dm-conversations"],queryFn:async()=>{const{data:s,error:t}=await h.from("nicole_conversations").select("id, user_id, created_at, updated_at").order("updated_at",{ascending:!1,nullsFirst:!1}).limit(200);if(t)throw t;return s??[]}}),{data:z=[]}=b({queryKey:["nicole-dm-blocks"],queryFn:async()=>{const{data:s,error:t}=await h.from("nicole_dm_blocks").select("user_id, blocked_until, reason");if(t)throw t;return s??[]}}),{data:$=[],isLoading:be}=b({queryKey:["nicole-dm-block-events"],refetchInterval:6e4,queryFn:async()=>{const{data:s,error:t}=await h.from("nicole_dm_block_events").select("id, user_id, block_type, detail, retry_after_ms, message_preview, created_at").order("created_at",{ascending:!1}).limit(200);if(t)throw t;return s??[]}}),{data:E=[]}=b({queryKey:["nicole-relationship-preferences"],queryFn:async()=>{const{data:s,error:t}=await h.from("nicole_relationship_preferences").select("user_id, support_mode, cadence, proactive_email_enabled, snoozed_until, follow_up_requested_at, human_requested_at, human_request_resolved_at").limit(500);if(t)throw t;return s??[]}}),{data:O=[]}=b({queryKey:["nicole-relationship-states"],queryFn:async()=>{const{data:s,error:t}=await h.from("nicole_relationship_state").select("user_id, care_need, receptivity, continuity, relationship_depth, fatigue_level, safety_state, open_loops, confidence, next_eligible_at, next_action, suppression_reasons, source_snapshot, policy_version, computed_at").order("computed_at",{ascending:!1}).limit(500);if(t)throw t;return s??[]}}),{data:se=[]}=b({queryKey:["nicole-decision-opportunities"],queryFn:async()=>{const{data:s,error:t}=await h.from("nicole_decision_opportunities").select("id, user_id, evaluated_at, selected_action, rationale, suppression_reasons, selection_probability, dry_run").order("evaluated_at",{ascending:!1}).limit(500);if(t)throw t;return s??[]}}),{data:te=[]}=b({queryKey:["nicole-conversation-memory"],queryFn:async()=>{const{data:s,error:t}=await h.from("nicole_conversation_memory").select("user_id, summary, facts, last_message_at").limit(500);if(t)throw t;return s??[]}}),R=x.useMemo(()=>{const s=new Set;return K.forEach(t=>s.add(t.user_id)),$.forEach(t=>
6s.add(t.user_id)),E.forEach(t=>s.add(t.user_id)),O.forEach(t=>s.add(t.user_id)),Array.from(s)},[K,$,E,O]),{data:ae=[]}=b({queryKey:["nicole-dm-profiles",R.join(",")],enabled:R.length>0,queryFn:async()=>{const{data:s,error:t}=await h.from("profiles").select("id, first_name, last_name, email").in("id",R);if(t)throw t;return s??[]}}),U=s=>[s==null?void 0:s.first_name,s==null?void 0:s.last_name].filter(Boolean).join(" ").trim(),A=x.useMemo(()=>new Map(ae.map(s=>[s.id,s])),[ae]),re=x.useMemo(()=>new Map(z.map(s=>[s.user_id,s])),[z]),Se=x.useMemo(()=>new Map(E.map(s=>[s.user_id,s])),[E]),H=x.useMemo(()=>new Map(O.map(s=>[s.user_id,s])),[O]),ke=x.useMemo(()=>new Map(te.map(s=>[s.user_id,s])),[te]),Ce=x.useMemo(()=>{const s=new Map;return se.forEach(t=>{s.has(t.user_id)||s.set(t.user_id,t)}),s},[se]),G=J({mutationFn:async({userId:s,hoursValue:t,note:n})=>{var u;const{data:c}=await h.auth.getUser(),v=t<=0?ls:new Date(Date.now()+t*36e5).toISOString(),{error:m}=await h.from("nicole_dm_blocks").upsert({user_id:s,blocked_until:v,reason:n||null,blocked_by:((u=c.user)==null?void 0:u.id)??null},{onConflict:"user_id"});if(m)throw m},onSuccess:()=>{M.success("Nicole DMs paused for this person"),y(null),i.invalidateQueries({queryKey:["nicole-dm-blocks"]})},onError:s=>M.error(s.message)}),ne=J({mutationFn:async s=>{const{error:t}=await h.from("nicole_dm_blocks").delete().eq("user_id",s);if(t)throw t},onSuccess:()=>{M.success("Messaging restored"),i.invalidateQueries({queryKey:["nicole-dm-blocks"]})},onError:s=>M.error(s.message)}),Z=J({mutationFn:async({userId:s,note:t})=>{const{data:n,error:c}=await h.functions.invoke("nicole-forward-to-team",{body:{userId:s,note:t}});if(c)throw c;if(n&&typeof n=="object"&&"error"in n)throw new Error(String(n.error))},onSuccess:()=>{M.success("Sent to [email protected]"),k(null),T("")},onError:s=>M.error(s.message)}),ie=J({mutationFn:async s=>{const{error:t}=await h.rpc("resolve_nicole_human_request",{_user_id:s});if(t)throw t;const{error:n}=await h.functions.invoke("nicole-continuing-care",{body:{action:"evaluate",user_id:s,trigger_type:"human_request_resolved"}});n&&console.warn("Human request was handled, but relationship state refresh failed",n)},onSuccess:()=>{M.success("Human follow-up marked as handled"),i.invalidateQueries({queryKey:["nicole-relationship-preferences"]}),i.invalidateQueries({queryKey:["nicole-relationship-states"]})},onError:s=>M.error(s.message)}),oe=x.useMemo(()=>{const s=o.trim().toLowerCase(),t=new Map(K.map(n=>[n.user_id,n]));return R.map(n=>{var c,v;return t.get(n)??{id:`relationship-${n}`,user_id:n,created_at:((c=H.get(n))==null?void 0:c.computed_at)??new Date(0).toISOString(),updated_at:((v=H.get(n))==null?void 0:v.computed_at)??null}}).filter(n=>{if(!s)return!0;const c=A.get(n.user_id);return n.user_id.includes(s)||U(c).toLowerCase().includes(s)||((c==null?void 0:c.email)??"").toLowerCase().includes(s)})},[K,A,R,o,H]),Me=z.filter(s=>new Date(s.blocked_until).getTime()>Date.now()).length,qe=$.filter(s=>Date.now()-new Date(s.created_at).getTime()<864e5).length,De=E.filter(s=>s.follow_up_requested_at&&new Date(s.follow_up_requested_at).getTime()<=Date.now()).length,Le=O.filter(s=>s.next_action==="NO_ACTION").length,Fe=E.filter(s=>s.human_requested_at&&(!s.human_request_resolved_at||new Date(s.human_requested_at).getTime()>new Date(s.human_request_resolved_at).getTime())).length,le=x.useMemo(()=>{const s=o.trim().toLowerCase();return s?$.filter(t=>{const n=A.get(t.user_id);return t.user_id.includes(s)||U(n).toLowerCase().includes(s)||((n==null?void 0:n.email)??"").toLowerCase().includes(s)}):$},[$,A,o]);return e.jsxs("div",{className:"space-y-8",children:[e.jsx("div",{className:"flex flex-wrap items-start justify-between gap-4",children:e.jsxs("div",{className:"max-w-3xl space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h1",{className:"text-3xl font-semibold tracking-tight",children:"Nicole relationship intelligence"}),e.jsx(g,{variant:"secondary",children:"Autonomous"})]}),e.jsx("p",{className:"text-muted-foreground",children:"Nicole evaluates every relationship and reaches out on her own, hourly, inside the guardrails. This page is here to watch what she decided and why — including deliberate silence. No staff evaluation or approval is needed."})]})}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 xl:grid-cols-6",children:[e.jsxs(p,{children:[e.jsx(q,{className:"pb-2",children:e.jsxs(D,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx(me,{className:"h-4 w-4"})," Conversations"]})}),e.jsx(f,{className:"text-3xl font-semibold",children:R.length})]}),e.jsxs(p,{children:[e.jsx(q,{className:"pb-2",children:e.jsxs(D,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx(Ge,{className:"h-4 w-4"})," Follow-ups due"]})}),e.jsx(f,{className:"text-3xl font-semibold",children:De})]}),e.jsxs(p,{children:[e.jsx(q,{className:"pb-2",children:e.jsxs(D,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx(Ze,{className:"h-4 w-4"})," Intentionally quiet"]})}),e.jsx(f,{className:"text-3xl font-semibold",children:Le})]}),e.jsxs(p,{children:[e.jsx(q,{className:"pb-2",children:e.jsxs(D,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx(ue,{className:"h-4 w-4"})," Human requested"]})}),e.jsx(f,{className:"text-3xl font-semibold",children:Fe})]}),e.jsxs(p,{children:[e.jsx(q,{className:"pb-2",children:e.jsxs(D,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx(ee,{className:"h-4 w-4"})," DMs paused"]})}),e.jsx(f,{className:"text-3xl font-semibold",children:Me})]}),e.jsxs(p,{children:[e.jsx(q,{className:"pb-2",children:e.jsxs(D,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx(Xe,{className:"h-4 w-4"})," Blocked sends (24h)"]})}),e.jsx(f,{className:"text-3xl font-semibold",children:qe})]})]}),e.jsx(ns,{}),e.jsx(ts,{}),e.jsxs("div",{className:"relative max-w-md",children:[e.jsx(Be,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(he,{value:o,onChange:s=>a(s.target.value),placeholder:"Search by name, email or user ID",className:"pl-9 min-h-[44px]","aria-label":"Search Nicole conversations"})]}),e.jsx(p,{children:e.jsx(f,{className:"p-0",children:we?e.jsxs("div",{className:"flex items-center justify-center gap-2 p-10 text-muted-foreground",children:[e.jsx(B,{className:"h-4 w-4 animate-spin"})," Loading conversations…"]}):oe.length===0?e.jsx("p",{className:"p-10 text-center text-muted-foreground",children:"No conversations foun
6d."}):e.jsx("ul",{className:"divide-y divide-border",children:oe.map(s=>{const t=A.get(s.user_id),n=re.get(s.user_id),c=n&&new Date(n.blocked_until).getTime()>Date.now(),v=U(t)||(t==null?void 0:t.email)||s.user_id,m=Se.get(s.user_id),u=H.get(s.user_id),C=Ce.get(s.user_id),X=ke.get(s.user_id),ce=ms(u==null?void 0:u.open_loops),de=!!(m!=null&&m.human_requested_at&&(!m.human_request_resolved_at||new Date(m.human_requested_at).getTime()>new Date(m.human_request_resolved_at).getTime())),Q=L===s.user_id;return e.jsxs("li",{className:"p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium",children:v}),u&&e.jsx(g,{variant:u.next_action==="NO_ACTION"?"secondary":"default",children:u.next_action==="NO_ACTION"?"Intentionally quiet":u.next_action.replaceAll("_"," ")}),de&&e.jsx(g,{variant:"destructive",children:"Human requested"}),c&&e.jsxs(g,{variant:"destructive",children:["DMs paused · ",ds(n.blocked_until)]})]}),e.jsxs("p",{className:"truncate text-sm text-muted-foreground",children:[(t==null?void 0:t.email)??s.user_id,m!=null&&m.support_mode?` · ${m.support_mode.replaceAll("_"," ")}`:"",m!=null&&m.cadence?` · ${m.cadence.replaceAll("_"," ")}`:""]})]}),e.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.jsxs(w,{variant:"ghost",className:"min-h-[44px]",onClick:()=>_(Q?null:s.user_id),"aria-expanded":Q,children:["Details",e.jsx(Oe,{className:`ml-2 h-4 w-4 transition-transform ${Q?"rotate-180":""}`})]})})]}),Q&&e.jsxs("div",{className:"mt-4 grid gap-4 rounded-xl bg-muted/40 p-4 lg:grid-cols-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"flex items-center gap-2 text-sm font-medium",children:[e.jsx(me,{className:"h-4 w-4"})," What Nicole remembers"]}),e.jsx("p",{className:"text-sm leading-relaxed text-muted-foreground",children:(X==null?void 0:X.summary)||"No relationship summary has been recorded yet."}),ce.length>0&&e.jsx("ul",{className:"list-disc space-y-1 pl-4 text-sm text-muted-foreground",children:ce.map(I=>e.jsx("li",{children:I},I))})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"flex items-center gap-2 text-sm font-medium",children:[e.jsx(Ye,{className:"h-4 w-4"})," Current relationship state"]}),u?e.jsxs("div",{className:"space-y-1 text-sm text-muted-foreground",children:[e.jsxs("p",{children:["Need: ",u.care_need||"not inferred"]}),e.jsxs("p",{children:["Receptivity: ",u.receptivity]}),e.jsxs("p",{children:["Continuity: ",u.continuity]}),e.jsxs("p",{children:["Relationship depth: ",u.relationship_depth]}),e.jsxs("p",{children:["Fatigue: ",u.fatigue_level,"/3"]}),e.jsxs("p",{children:["Safety route: ",u.safety_state]})]}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nicole has not evaluated this family yet — the hourly autonomous run will pick them up."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"flex items-center gap-2 text-sm font-medium",children:[e.jsx(Ie,{className:"h-4 w-4"})," Latest decision"]}),C?e.jsxs("div",{className:"space-y-2 text-sm text-muted-foreground",children:[e.jsxs("p",{children:[e.jsx("span",{className:"font-medium text-foreground",children:C.selected_action.replaceAll("_"," ")})," ","· ",ye(C.evaluated_at)," · ",C.dry_run?"dry run":"live"]}),C.rationale.map(I=>e.jsx("p",{children:I},I)),C.suppression_reasons.length>0&&e.jsxs("p",{children:["Held back by: ",C.suppression_reasons.join(", ")]}),e.jsxs("p",{children:["Selection probability logged: ",C.selection_probability]})]}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No decision has been recorded."})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 lg:col-span-3",children:[c?e.jsxs(w,{variant:"outline",className:"min-h-[44px]",onClick:()=>ne.mutate(s.user_id),disabled:ne.isPending,children:[e.jsx(es,{className:"mr-2 h-4 w-4"})," Restore messaging"]}):e.jsxs(w,{variant:"outline",className:"min-h-[44px]",onClick:()=>y({user_id:s.user_id,name:v}),children:[e.jsx(ee,{className:"mr-2 h-4 w-4"})," Pause DMs"]}),e.jsxs(w,{variant:"outline",className:"min-h-[44px]",onClick:()=>{T(""),k({user_id:s.user_id,name:v})},children:[e.jsx(Ne,{className:"mr-2 h-4 w-4"})," Forward to team"]}),de&&e.jsxs(w,{className:"min-h-[44px]",onClick:()=>
6ie.mutate(s.user_id),disabled:ie.isPending,children:[e.jsx(ue,{className:"mr-2 h-4 w-4"})," Mark human request handled"]}),e.jsx("p",{className:"self-center text-xs text-muted-foreground",children:"Staff review does not overwrite the family's explicit preferences."})]})]})]},s.id)})})})}),e.jsxs("section",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("h2",{className:"text-xl font-semibold tracking-tight",children:"Spam attempt log"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Every send Nicole refused — rate limits, duplicate messages and admin pauses. Most recent 200 attempts, refreshed every minute."})]}),e.jsx(p,{children:e.jsx(f,{className:"p-0",children:be?e.jsxs("div",{className:"flex items-center justify-center gap-2 p-10 text-muted-foreground",children:[e.jsx(B,{className:"h-4 w-4 animate-spin"})," Loading log…"]}):le.length===0?e.jsx("p",{className:"p-10 text-center text-muted-foreground",children:"No blocked sends recorded. Nothing has tripped spam protection."}):e.jsx("ul",{className:"divide-y divide-border",children:le.map(s=>{const t=A.get(s.user_id),n=U(t)||(t==null?void 0:t.email)||s.user_id,c=re.get(s.user_id),v=c&&new Date(c.blocked_until).getTime()>Date.now();return e.jsxs("li",{className:"flex flex-wrap items-start gap-4 p-4",children:[e.jsxs("div",{className:"min-w-0 flex-1 space-y-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium",children:n}),e.jsx(g,{variant:s.block_type==="admin_pause"?"destructive":"secondary",children:is[s.block_type]??s.block_type}),e.jsx("span",{className:"text-sm text-muted-foreground",children:ye(s.created_at)})]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[s.detail??"Send refused",s.retry_after_ms?` · asked to wait ${Math.max(1,Math.round(s.retry_after_ms/1e3))}s`:""]}),s.message_preview&&e.jsxs("p",{className:"truncate text-sm italic text-muted-foreground",children:["“",s.message_preview,"”"]})]}),!v&&e.jsxs(w,{variant:"outline",className:"min-h-[44px]",onClick:()=>y({user_id:s.user_id,name:n}),children:[e.jsx(ee,{className:"mr-2 h-4 w-4"})," Pause DMs"]})]},s.id)})})})})]}),e.jsx(xe,{open:!!j,onOpenChange:s=>!s&&k(null),children:e.jsxs(pe,{children:[e.jsxs(fe,{children:[e.jsx(ge,{children:"Forward to the team"}),e.jsxs(_e,{children:["We'll email [email protected] with ",j==null?void 0:j.name,"'s contact details, what their conversation is about, their recent messages and clear instructions on how to follow up. Replying to that email writes straight back to the family."]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(Y,{htmlFor:"forward-note",children:"Anything the team should know (optional)"}),e.jsx(Pe,{id:"forward-note",rows:4,placeholder:"e.g. She wants to talk to someone about her epidural decision before Friday.",value:P,onChange:s=>T(s.target.value)})]}),e.jsxs(je,{children:[e.jsx(w,{variant:"outline",className:"min-h-[44px]",onClick:()=>k(null),children:"Cancel"}),e.jsx(w,{className:"min-h-[44px]",disabled:Z.isPending,onClick:()=>j&&Z.mutate({userId:j.user_id,note:P}),children:Z.isPending?e.jsxs(e.Fragment,{children:[e.jsx(B,{className:"mr-2 h-4 w-4 animate-spin"})," Sending…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Ne,{className:"mr-2 h-4 w-4"})," Send to [email protected]"]})})]})]})}),e.jsx(xe,{open:!!r,onOpenChange:s=>!s&&y(null),children:e.jsxs(pe,{children:[e.jsxs(fe,{children:[e.jsx(ge,{children:"Pause Nicole DMs"}),e.jsxs(_e,{children:[r==null?void 0:r.name," will not be able to send messages until the pause ends. Choose Forever and it stays paused until you press Restore messaging. The chat shows them the exact wait time and your note."]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(Y,{htmlFor:"pause-duration",children:"How long"}),e.jsxs(Ke,{value:d,onValueChange:l,children:[e.jsx(Ue,{id:"pause-duration",className:"min-h-[44px]",children:e.jsx(He,{})}),e.jsx(Qe,{children:os.map(s=>e.jsx(Je,{value:String(s.hours),children:s.label},s.hours))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(Y,{htmlFor:"pause-reason",children:"Note shown to them"}),e.jsx(he,{id:"pause-reason",value:S,onChange:s=>F(s.target.value),className:"min-h-[44px]"})]})]}),e.jsxs(je,{children:[e.jsx(w,{variant:"ghost",className:"min-h-[44px]",onClick:()=>y(null),children:"Cancel"}),e.jsxs(w,{className:"min-h-[44px]",disabled:G.isPending,onClick:()=>r&&G.mutate({userId:r.user_id,hoursValue:Number(d),note:S}),children:[G.isPending&&e.jsx(B,{className:"mr-2 h-4 w-4 animate-spin"}),"Pause messaging"]})]})]})})]})}export{bs 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.