PageSourceSearch

https://mindgolf.ai/assets/AdminTrainingExercises-Dkhmnwfn.js

js mindgolf.ai collected 2026-10-05 14:52:47 UTC 15,492 bytes, 1 lines download raw bytes

1import{n as X,r as x,j as e}from"./vendor-ahVw9cdH.js";import{a as J,u as Y,b as Z}from"./query-CeIq2NOR.js";import{bz as ee,bA as C,O as z,aX as q,V as g,bB as se,ae as te,be as re,bf as ae,bg as F,bC as P,bh as A,a5 as D,a6 as T,a7 as v,am as W,S as ie,aw as ne,bD as le,bE as B,bF as G,bG as Q,bH as O,bI as H,bJ as _,bK as M,bL as V}from"./index-DXi0I5ak.js";import"./radix--pSzM2y8.js";import"./supabase-DYrB2Yg5.js";import"./charts-CSweoJhv.js";import"./forms-Cc1FL3tT.js";const be=()=>{const r=X(),o=J(),{isSuperAdmin:n,isLoading:d}=ee(),[t,a]=x.useState("all"),[u,j]=x.useState(""),[k,c]=x.useState(null),[f,b]=x.useState(null),{data:l,isLoading:h,error:L,refetch:K}=Y({queryKey:["admin-exercise-catalog"],queryFn:async()=>{const{data:s,error:p}=await z.functions.invoke("admin-exercise-catalog",{body:{}});if(p)throw p;return s},enabled:n,retry:1}),y=Z({mutationFn:async s=>{const{data:p,error:U}=await z.functions.invoke("sync-exercise-provider",{body:{providerKey:s}});if(U)throw U;return p},onSuccess:s=>{C.success((s==null?void 0:s.note)??"Provider synced"),o.invalidateQueries({queryKey:["admin-exercise-catalog"]})},onError:s=>C.error(s.message)});if(d)return e.jsx("div",{className:"p-8",children:e.jsx(q,{className:"h-96 w-full"})});if(!n)return r("/dashboard"),null;const S=((l==null?void 0:l.builtin)??[]).map(s=>({id:s.id,source:"builtin",status:s.status??"active",name:s.name,category:s.category,targetKpis:s.target_kpis??[],targetContributors:s.target_contributors??[],targetReadinessFactors:s.target_readiness_factors??[],targetWhoopSubMetrics:s.target_whoop_submetrics??[]})),N=((l==null?void 0:l.coach)??[]).map(s=>({id:`coach:${s.id}`,source:"coach",status:"active",name:s.name??"Coach exercise",category:s.category??null,targetKpis:s.target_kpis??[],targetContributors:s.target_contributors??[],targetReadinessFactors:[],targetWhoopSubMetrics:[]})),E=((l==null?void 0:l.external)??[]).map(s=>({id:`${s.provider_key}:${s.external_id}`,source:"thirdparty",status:s.enabled?"active":"archived",name:s.name,category:s.category??null,targetKpis:s.target_kpis??[],targetContributors:s.target_contributors??[],targetReadinessFactors:s.target_readiness_factors??[],targetWhoopSubMetrics:s.target_whoop_submetrics??[]})),i=[...S,...N,...E],w=(l==null?void 0:l.suggestions)??[],$=(l==null?void 0:l.providers)??[],R=s=>u.trim()?s.filter(p=>[p.name,...p.targetContributors,...p.targetReadinessFactors,...p.targetKpis].join(" ").toLowerCase().includes(u.trim().toLowerCase())):s,m={all:i.length,builtin:S.length,coach:N.length,thirdparty:E.length,suggestions:w.filter(s=>s.status==="pending"||s.status==="open").length};return e.jsxs("div",{className:"p-4 md:p-8 space-y-6 max-w-7xl mx-auto",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs(g,{variant:"ghost",size:"sm",onClick:()=>r("/admin"),className:"gap-1",children:[e.jsx(se,{className:"h-4 w-4"})," Admin"]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(te,{className:"h-6 w-6 text-primary"}),e.jsx("h1",{className:"text-2xl md:text-3xl font-bold",children:"Training Exercises"})]})]}),e.jsx("p",{className:"text-sm text-muted-foreground max-w-2xl",children:"Unified view of every exercise the assistant matcher can recommend — built-in, coach-authored, and third-party providers. Gaps logged by the action-to-exercise matcher are surfaced here for review."}),L&&e.jsxs("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 p-4 text-sm flex items-center justify-between gap-3",children:[e.jsxs("span",{className:"text-destructive",children:["Failed to load exercise catalog: ",L.message]}),e.jsx(g,{size:"sm",variant:"outline",onClick:()=>K(),children:"Retry"})]}),e.jsxs(re,{value:t,onValueChange:s=>a(s),className:"space-y-4",children:[e.jsxs(ae,{className:"flex flex-wrap",children:[e.jsxs(F,{value:"all",children:["All (",m.all,")"]}),e.jsxs(F,{value:"builtin",children:["Built-in (",m.builtin,")"]}),e.jsxs(F,{value:"coach",children:["Coach (",m.coach,")"]}),e.jsxs(F,{value:"thirdparty",children:["Third-party (",m.thirdparty,")"]}
1),e.jsxs(F,{value:"suggestions",children:["Suggested / Gaps (",m.suggestions,")"]}),e.jsxs(F,{value:"providers",children:["Providers (",$.length,")"]})]}),e.jsx(P,{placeholder:"Search by name, contributor, factor, KPI…",value:u,onChange:s=>j(s.target.value),className:"max-w-md"}),e.jsx(A,{value:"all",children:e.jsx(I,{rows:R(i),loading:h})}),e.jsx(A,{value:"builtin",children:e.jsx(I,{rows:R(S),loading:h})}),e.jsx(A,{value:"coach",children:e.jsx(I,{rows:R(N),loading:h})}),e.jsx(A,{value:"thirdparty",children:e.jsx(I,{rows:R(E),loading:h})}),e.jsx(A,{value:"suggestions",children:e.jsx(oe,{rows:w,loading:h,onApprove:s=>c(s),onReject:s=>b(s)})}),e.jsx(A,{value:"providers",children:e.jsx(de,{providers:$,loading:h,onSync:s=>y.mutate(s),syncing:y.isPending?y.variables??null:null})})]}),e.jsx(xe,{suggestion:k,onClose:()=>c(null),onApproved:()=>{c(null),o.invalidateQueries({queryKey:["admin-exercise-catalog"]})}}),e.jsx(ue,{suggestion:f,onClose:()=>b(null),onRejected:()=>{b(null),o.invalidateQueries({queryKey:["admin-exercise-catalog"]})}})]})},ce={builtin:{label:"Built-in",className:"bg-violet-500/10 text-violet-700 dark:text-violet-300 border-violet-500/20"},coach:{label:"Coach",className:"bg-blue-500/10 text-blue-700 dark:text-blue-300 border-blue-500/20"},thirdparty:{label:"3rd-party",className:"bg-emerald-500/10 text-emerald-700 dark:text-emerald-300 border-emerald-500/20"}};function I({rows:r,loading:o}){return o?e.jsx(q,{className:"h-64 w-full"}):r.length===0?e.jsx(D,{children:e.jsx(T,{className:"p-8 text-center text-sm text-muted-foreground",children:"No exercises match."})}):e.jsx(D,{children:e.jsx(T,{className:"p-0",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-xs uppercase tracking-wider text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 text-left",children:"Name"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"Source"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"Category"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"KPIs"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"Targets"}),e.jsx("th",{className:"px-3 py-2 text-left",children:"Status"})]})}),e.jsx("tbody",{children:r.map(n=>{const d=ce[n.source],t=[...n.targetContributors,...n.targetReadinessFactors.map(a=>`r:${a}`),...n.targetWhoopSubMetrics.map(a=>`w:${a}`)];return e.jsxs("tr",{className:"border-t border-border/40 hover:bg-muted/30",children:[e.jsx("td",{className:"px-3 py-2 font-medium",children:n.name}),e.jsx("td",{className:"px-3 py-2",children:e.jsx(v,{variant:"outline",className:d.className,children:d.label})}),e.jsx("td",{className:"px-3 py-2 text-muted-foreground",children:n.category??"—"}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("div",{className:"flex flex-wrap gap-1",children:n.targetKpis.map(a=>e.jsx(v,{variant:"secondary",className:"text-[10px]",children:a},a))})}),e.jsx("td",{className:"px-3 py-2",children:e.jsxs("div",{className:"flex flex-wrap gap-1 max-w-md",children:[t.length===0?e.jsx("span",{className:"text-muted-foreground",children:"—"}):t.slice(0,4).map(a=>e.jsx(v,{variant:"outline",className:"text-[10px]",children:a},a)),t.length>4&&e.jsxs("span",{className:"text-[10px] text-muted-foreground",children:["+",t.length-4]})]})}),e.jsx("td",{className:"px-3 py-2 text-muted-foreground",children:n.status})]},n.id)})})]})})})})}function oe({rows:r,loading:o,onApprove:n,onReject:d}){return o?e.jsx(q,{className:"h-64 w-full"}):r.length===0?e.jsx(D,{children:e.jsxs(T,{className:"p-8 text-center text-sm text-muted-foreground",children:[e.jsx(W,{className:"h-8 w-8 mx-auto mb-2 text-emerald-500"}),"No open gaps — every driver the matcher has seen is covered."]})}):e.jsx("div",{className:"space-y-3",children:r.map(t=>{const a=t.driver_key.replace(/_/g," "),u=t.status==="fulfilled"||t.status==="rejected";return e.jsx(D,{className:u?"opacity-60":"",children:e.jsx(T,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[e.jsx(ie,{className:"h-4 w-4 text-amber-500"}),e.jsxs("span",{className:"font-medium text-sm",children:["Missing exercise for ",e.jsx("span",{className:"capitalize",children:a})]}),e.jsx(v,{variant:"outline",className:"text-[10px]",children:t.driver_kind}),t.sg_category&&e.jsx(v,{variant:"secondary",className:"text-[10px]",children:t.sg_category})]}),t.action_title&&e.jsxs("p",{className:"text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Action: "}),t.action_title]}),t.action_rationale&&e.jsx("p",{className:"text-xs text-muted-foreground italic mt-1",children:t.action_rationale}),e.jsxs("p",{className:"text-[11px] text-muted-foreground mt-1",children:["Seen ",e.jsx("strong",{children:t.occurrence_count})," times · last ",new Date(t.last_seen_at).toLocaleDateString()," · status ",t.status,t.fulfilled_by_exercise_id&&e.jsxs(e.Fragment,{children:[" · → ",e.jsx("code",{children:t.fulfilled_by_exercise_id})]})]})]}),!u&&e.jsxs("div",{className:"flex gap-2 shrink-0",children:[e.jsxs(g,{size:"sm",variant:"default",onClick:()=>n(t),className:"gap-1",children:[e.jsx(W,{className:"h-3 w-3"})," Approve"]}),e.jsxs(g,{size:"sm",variant:"ghost",onClick:()=>d(t),className:"gap-1 text-muted-foreground",children:[e.jsx(ne,{className:"h-3 w-3"})," Reject"]})]})]})})},t.id)})})}function de({providers:r,loading:o,onSync:n,syncing:d}){return o?e.jsx(q,{className:"h-48 w-full"}):r.length===0?e.jsx(D,{children:e.jsx(T,{className:"p-8 text-center text-sm text-muted-foreground",children:"No providers configured yet."})}):e.jsx("div",{className:"space-y-3",children:r.map(t=>e.jsx(D,{children:e.jsxs(T,{className:"p-4 flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:"font-medium text-sm",children:t.name}),e.jsx(v,{variant:"outline",className:"text-[10px]",children:t.provider_key}),e.jsx(v,{variant:t.enabled?"default":"secondary",className:"text-[10px]",children:t.enabled?"enabled":"disabled"}),t.last_sync_status&&e.jsx(v,{variant:"outline",className:"text-[10px]",children:t.last_sync_status})]}),t.description&&e.jsx("p",{className:"text-xs text-muted-foreground",children:t.description}),e.jsxs("p",{className:"text-[11px] text-muted-foreground mt-1",children:[t.exercise_count??0," exercises ·"," ",t.last_sync_at?`last synced ${new Date(t.last_sync_at).toLocaleStr
1ing()}`:"never synced",t.last_sync_error&&e.jsxs(e.Fragment,{children:[" · ",e.jsx("span",{className:"text-destructive",children:t.last_sync_error})]})]})]}),e.jsxs(g,{size:"sm",variant:"outline",disabled:d===t.provider_key,onClick:()=>n(t.provider_key),className:"gap-1 shrink-0",children:[e.jsx(le,{className:`h-3 w-3 ${d===t.provider_key?"animate-spin":""}`})," Sync now"]})]})},t.id))})}function xe({suggestion:r,onClose:o,onApproved:n}){const d=!!r,[t,a]=x.useState(""),[u,j]=x.useState(""),[k,c]=x.useState(""),[f,b]=x.useState(""),[l,h]=x.useState("standard"),[L,K]=x.useState(""),[y,S]=x.useState(!1);if(r&&!t&&!y){const w=`Drill: ${r.driver_key.replace(/_/g," ")}`;a(w),j(w.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")),K(r.action_rationale??r.action_title??""),b(r.sg_category??"")}const N=()=>{a(""),j(""),c(""),b(""),h("standard"),K("")},E=async()=>{if(r){if(!t.trim()){C.error("Name required");return}S(!0);try{const i=r.driver_kind==="contributor"?[r.driver_key]:[],w=r.driver_kind==="readiness_factor"?[r.driver_key]:[],$=r.driver_kind==="whoop_submetric"?[r.driver_key]:[],R=r.sg_category?[r.sg_category]:[],{data:m,error:s}=await z.functions.invoke("admin-exercise-suggestion-resolve",{body:{suggestionId:r.id,action:"approve",target:"builtin",exercise:{slug:u||void 0,name:t.trim(),description:k.trim()||void 0,category:f.trim()||void 0,intensity:l,when_to_use:L.trim()||void 0,target_contributors:i,target_readiness_factors:w,target_whoop_submetrics:$,sg_category_fit:R}}});if(s)throw s;if(m!=null&&m.error)throw new Error(m.error);C.success(`Approved → ${m.exerciseId}`),N(),n()}catch(i){C.error(i.message)}finally{S(!1)}}};return e.jsx(B,{open:d,onOpenChange:i=>{i||(N(),o())},children:e.jsxs(G,{children:[e.jsxs(Q,{children:[e.jsx(O,{children:"Approve as built-in exercise"}
1),e.jsxs(H,{children:["Creates a new ",e.jsx("code",{children:"builtin:<slug>"})," exercise mapped to"," ",e.jsx("strong",{children:r==null?void 0:r.driver_key})," (",r==null?void 0:r.driver_kind,")."]})]}),e.jsxs("div",{className:"px-4 pb-4 space-y-3 max-w-2xl mx-auto w-full",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(_,{htmlFor:"ex-name",children:"Name"}),e.jsx(P,{id:"ex-name",value:t,onChange:i=>a(i.target.value)})]}),e.jsxs("div",{children:[e.jsx(_,{htmlFor:"ex-slug",children:"Slug"}),e.jsx(P,{id:"ex-slug",value:u,onChange:i=>j(i.target.value),placeholder:"auto-from-name"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(_,{htmlFor:"ex-cat",children:"SG Category"}),e.jsx(P,{id:"ex-cat",value:f,onChange:i=>b(i.target.value),placeholder:"putting / off_the_tee / …"})]}),e.jsxs("div",{children:[e.jsx(_,{htmlFor:"ex-int",children:"Intensity"}),e.jsxs("select",{id:"ex-int",value:l,onChange:i=>h(i.target.value),className:"w-full h-10 px-3 rounded-md border border-input bg-background text-sm",children:[e.jsx("option",{value:"micro",children:"micro"}),e.jsx("option",{value:"standard",children:"standard"}),e.jsx("option",{value:"deep",children:"deep"})]})]})]}),e.jsxs("div",{children:[e.jsx(_,{htmlFor:"ex-when",children:"When to use"}),e.jsx(M,{id:"ex-when",rows:2,value:L,onChange:i=>K(i.target.value)})]}),e.jsxs("div",{children:[e.jsx(_,{htmlFor:"ex-desc",children:"Description"}),e.jsx(M,{id:"ex-desc",rows:3,value:k,onChange:i=>c(i.target.value)})]})]}),e.jsxs(V,{children:[e.jsx(g,{onClick:E,disabled:y,children:y?"Approving…":"Approve & create"}),e.jsx(g,{variant:"ghost",onClick:()=>{N(),o()},children:"Cancel"})]})]})})}function ue({suggestion:r,onClose:o,onRejected:n}){const d=!!r,[t,a]=x.useState(""),[u,j]=x.useState(!1),k=async()=>{if(r){j(!0);try{const{data:c,error:f}=await z.functions.invoke("admin-exercise-suggestion-resolve",{body:{suggestionId:r.id,action:"reject",notes:t.trim()||void 0}});if(f)throw f;if(c!=null&&c.error)throw new Error(c.error);C.success("Suggestion rejected"),a(""),n()}catch(c){C.error(c.message)}finally{j(!1)}}};return e.jsx(B,{open:d,onOpenChange:c=>{c||(a(""),o())},children:e.jsxs(G,{children:[e.jsxs(Q,{children:[e.jsx(O,{children:"Reject suggestion"}
1),e.jsxs(H,{children:["Marks ",e.jsx("strong",{children:r==null?void 0:r.driver_key})," as not-needed. The matcher will keep logging future occurrences as new rows."]})]}),e.jsxs("div",{className:"px-4 pb-4 max-w-2xl mx-auto w-full",children:[e.jsx(_,{htmlFor:"reject-notes",children:"Reason (optional)"}),e.jsx(M,{id:"reject-notes",rows:3,value:t,onChange:c=>a(c.target.value)})]}),e.jsxs(V,{children:[e.jsx(g,{variant:"destructive",onClick:k,disabled:u,children:u?"Rejecting…":"Reject suggestion"}),e.jsx(g,{variant:"ghost",onClick:()=>{a(""),o()},children:"Cancel"})]})]})})}export{be 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.