PageSourceSearch

https://smartmaths.ai/assets/CalibrationPage-Ds5-qKgG.js

js smartmaths.ai collected 2026-10-05 15:06:10 UTC 29,887 bytes, 1 lines download raw bytes

1import{r as l,j as e,c as v,g as L,e as E,Q as M}from"./main-Dt7Bgl8i.js";import"./curriculum-data-UeTaQjv3.js";import"./worked-examples-BExh4ce1.js";const X=[{value:"incorrect_answer",label:"Wrong answer"},{value:"not_suitable",label:"Not suitable"},{value:"other",label:"Other"}];function U({questionId:i,sessionId:n,judgeName:o,onFlagged:u}){const[m,d]=l.useState(!1),[p,r]=l.useState(null),[a,c]=l.useState(""),[t,s]=l.useState(!1),[f,S]=l.useState(!1),_=l.useRef(null);async function q(){if(!(!p||!v)){s(!0);try{await v.from("calibration_flags").insert({session_id:n,question_id:i,flag_type:p,notes:a.trim()||null,judge_name:o}),S(!0),d(!1),u(p)}finally{s(!1)}}}return f?e.jsx("div",{className:"cal-flag-btn cal-flag-btn--active",title:"Flagged",children:"Flagged"}):e.jsxs("div",{className:"cal-flag-wrap",children:[e.jsx("button",{className:"cal-flag-btn",type:"button",onClick:()=>d(h=>!h),title:"Flag this question",children:"Flag"}),m&&e.jsxs("div",{className:"cal-flag-popover",children:[e.jsx("div",{className:"cal-flag-popover-title",children:"Flag this question"}),e.jsx("div",{className:"cal-flag-options",children:X.map(h=>e.jsx("button",{type:"button",className:`cal-flag-option ${p===h.value?"cal-flag-option--active":""}`,onClick:()=>{r(h.value),_.current?.focus()},children:h.label},h.value))}),e.jsx("input",{ref:_,className:"cal-flag-notes",type:"text",placeholder:"Notes (optional)",value:a,onChange:h=>c(h.target.value),onKeyDown:h=>{h.key==="Enter"&&p&&q()}}),e.jsxs("div",{className:"cal-flag-popover-actions",children:[e.jsx("button",{type:"button",className:"cal-flag-save",onClick:()=>{q()},disabled:!p||t,children:t?"Saving...":"Save flag"}),e.jsx("button",{type:"button",className:"cal-flag-cancel",onClick:()=>d(!1),children:"Cancel"})]})]})]})}const W={number_place_value:"Number & Place Value",addition_subtraction:"Addition & Subtraction",multiplication_division:"Multiplication & Division",fractions_decimals_percentages:"Fractions, Decimals & Percentages",measurement:"Measurement",geometry:"Shape & Space",data_statistics:"Data & Statistics"},Z=["reception","year_1","year_2","year_3","year_4","year_5","year_6"];function ee({pairs:i,onBackToSetup:n}){const o=l.useMemo(()=>L(),[]),[u,m]=l.useState("setup"),[d,p]=l.useState(""),[r,a]=l.useState("year_1"),[c,t]=l.useState(null),[s,f]=l.useState(0),[S,_]=l.useState(new Set),[q,h]=l.useState(!1),[x,y]=l.useState(null),j=i[s]??null,C=j?o.byId.get(j.left_id)??null:null,w=j?o.byId.get(j.right_id)??null:null;async function D(){if(!(!d.trim()||!v)){h(!0),y(null);try{const{data:b,error:R}=await v.from("calibration_sessions").insert({judge_name:d.trim(),judge_year_group:r,year_group_target:"year_1"}).select("id").single();if(R)throw R;t(b.id),m("running")}catch(b){const R=b instanceof Error?b.message:b?.message??"Failed to start session";y(R)}finally{h(!1)}}}async function A(b){if(!j||!c||!v)return;const R=j.expected;await v.from("calibration_responses").insert({session_id:c,left_question_id:j.left_id,right_question_id:j.right_id,left_band:j.left_band,right_band:j.right_band,mathematical_form:j.mathematical_form,pair_type:j.pair_type,response:b,expected:R,agreement:b!=="same"&&b===R}),s<i.length-1?f(P=>P+1):m("done")}if(u==="setup")return e.jsxs("div",{className:"cal-setup",children:[e.jsx("h2",{className:"cal-setup-title",children:"Who is doing the review?"}),e.jsx("div",{className:"cal-setup-fields",children:e.jsxs("label",{className:"cal-setup-label",children:["Name",e.jsx("input",{className:"cal-setup-input",type:"text",placeholder:"e.g. Luca",value:d,onChange:b=>p(b.target.value),onKeyDown:b=>{b.key==="Enter"&&d.trim()&&D()},autoFocus:!0})]})}),e.jsx("p",{className:"cal-setup-count",children:"Your year group"}),e.jsx("div",{className:"count-pill-row qr-year-pill-row",role:"group","aria-label":"Year group",children:Z.map(b=>e.jsx("button",{type:"button",className:`count-pill ${r===b?"active":""}`,onClick:()=>a(b),children:e.jsx("span",{children:b==="reception"?"Reception":b.replace(/_/g," ").replace(/\b\w/g,R=>R.toUpperCase())})},b))}),e.jsxs("p",{className:"cal-setup-count",children:[i.length," pairs to review"]}),x&&e.jsx("p",{className:"cal-setup-error",children:x}),e.jsx("button",{className:"cal-setup-start",type:"button",onClick:()=>{D()},disabled:!d.trim()||q,children:q?"Starting...":"Start"})]});if(u==="done")return e.jsxs("div",{className:"cal-done",children:[e.jsx("div",{className:"cal-done-check",children:"✓"}),e.jsx("h2",{children:"All done!"}),e.jsxs("p",{children:["Reviewed all ",i.length," pairs."]}),e.jsx("button",{type:"button",className:"cal-setup-start",onClick:n,children:"Back"})]});if(!j||!C||!w)return e.jsxs("div",{className:"cal-done",children:[e.jsx("p",{children:"Question not found in bank. Skipping."}),e.jsx("button",{type:"button",className:"cal-setup-start",onClick:()=>f(b=>b+1),children:"Next"})]});const k=E(C,W[C.strand_id]??C.strand_id),T=E(w,W[w.strand_id]??w.strand_id);return e.jsxs("div",{className:"cal-runner",children:[e.jsxs("div",{className:"cal-runner-progress",children:["Pair ",s+1," of ",i.length,e.jsx("span",{className:"cal-runner-form",children:j.mathematical_form}),e.jsx("span",{className:"cal-runner-type",children:j.pair_type})]}),e.jsxs("div",{className:"cal-pair-row",children:[e.jsxs("div",{className:"cal-question-col",children:[e.jsx(M,{question:k,selectedAnswer:null,status:"incorrect",attemptsExhausted:!0,onChangeAnswer:()=>{}
1,onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1,hideDebugBar:!0,hideKeypad:!0}),e.jsx("div",{className:"cal-answer-strip",children:V(C)}),c&&e.jsx(U,{questionId:j.left_id,sessionId:c,judgeName:d,onFlagged:()=>_(b=>new Set([...b,j.left_id]))})]}),e.jsx("div",{className:"cal-vs-divider",children:"vs"}),e.jsxs("div",{className:"cal-question-col",children:[e.jsx(M,{question:T,selectedAnswer:null,status:"incorrect",attemptsExhausted:!0,onChangeAnswer:()=>{},onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1,hideDebugBar:!0,hideKeypad:!0}),e.jsx("div",{className:"cal-answer-strip",children:V(w)}),c&&e.jsx(U,{questionId:j.right_id,sessionId:c,judgeName:d,onFlagged:()=>_(b=>new Set([...b,j.right_id]))})]})]}),e.jsx("p",{className:"cal-runner-question",children:"Which question would be harder for a Year 1 student?"}),e.jsxs("div",{className:"cal-response-row",children:[e.jsx("button",{type:"button",className:"cal-response-btn cal-response-left",onClick:()=>{A("left_harder")},children:"Left is harder"}),e.jsx("button",{type:"button",className:"cal-response-btn cal-response-same",onClick:()=>{A("same")},children:"Same"}),e.jsx("button",{type:"button",className:"cal-response-btn cal-response-right",onClick:()=>{A("right_harder")},children:"Right is harder"})]})]})}function V(i){const n=i.answer_spec;if(n.kind==="select"){const o=n;return o.options.filter(u=>o.correct_option_ids.includes(u.id)).map(u=>u.label).join(", ")}return n.kind==="free_response"?(n.accepted_values??[]).join(", "):n.kind==="number_line"?n.accepted_values.join(", "):n.kind==="ordering"?n.correct_order.join(" → "):""}function te(){const[i,n]=l.useState([]),[o,u]=l.useState([]),[m,d]=l.useState(!0),[p,r]=l.useState(null);l.useEffect(()=>{if(!v){r("Supabase not configured"),d(!1);return}(async()=>{try{const[s,f]=await Promise.all([v.from("calibration_responses").select("*").order("created_at",{ascending:!0}),v.from("calibration_flags").select("*").order("created_at",{ascending:!0})]);if(s.error)throw s.error;if(f.error)throw f.error;n(s.data??[]),u(f.data??[])}catch(s){r(s instanceof Error?s.message:"Failed to load calibration data")}finally{d(!1)}})()},[]);const a=se(i),c=i.filter(s=>s.pair_type==="anchor"),t=i.filter(s=>s.pair_type==="adjacent");return{responses:i,flags:o,formSummaries:a,anchorAgreementPct:Y(c),adjacentAgreementPct:Y(t),overallAgreementPct:Y(i),loading:m,error:p}}function Y(i){return i.length===0?null:Math.round(i.filter(n=>n.agreement).length/i.length*100)}function se(i){const n=new Map;for(const o of i)n.has(o.mathematical_form)||n.set(o.mathematical_form,[]),n.get(o.mathematical_form).push(o);return[...n.entries()].map(([o,u])=>{const m=u.filter(a=>a.pair_type==="adjacent"),d=u.filter(a=>a.pair_type==="anchor"),p=new Map;for(const a of m){const c=`${Math.min(a.left_band,a.right_band)}v${Math.max(a.left_band,a.right_band)}`;p.has(c)||p.set(c,{boundary:c,total:0,agreed:0});const t=p.get(c);t.total++,a.agreement&&t.agreed++}const r=[...p.values()].filter(a=>a.total>0).sort((a,c)=>a.agreed/a.total-c.agreed/c.total)[0]??null;return{form:o,total:u.length,agreed:u.filter(a=>a.agreement).length,agreementPct:Math.round(u.filter(a=>a.agreement).length/u.length*100),adjacentTotal:m.length,adjacentAgreed:m.filter(a=>a.agreement).length,anchorTotal:d.length,anchorAgreed:d.filter(a=>a.agreement).length,weakestBoundary:r?r.boundary:null}}).sort((o,u)=>o.agreementPct-u.agreementPct)}const O={number_place_value:"Number & Place Value",addition_subtraction:"Addition & Subtraction",multiplication_division:"Multiplication & Division",fractions_decimals_percentages:"Fractions, Decimals & Percentages",measurement:"Measurement",geometry:"Shape & Space",data_statistics:"Data & Statistics"};function ae(){const{responses:i,flags:n,formSummaries:o,anchorAgreementPct:u,adjacentAgreementPct:m,overallAgreementPct:d,loading:p,error:r}=te(),a=l.useMemo(()=>L(),[]);if(p)return e.jsx("div",{className:"cal-review-loading",children:"Loading results..."});if(r)return e.jsx("div",{className:"cal-review-error",children:r});if(i.length===0)return e.jsx("div",{className:"cal-review-empty",children:"No calibration sessions recorded yet. Run a session first."});const c=i.filter(t=>!t.agreement);return e.jsxs("div",{className:"cal-review",children:[e.jsxs("div",{className:"cal-review-stats",children:[e.jsx($,{label:"Overall agreement",value:d,total:i.length}),e.jsx($,{label:"Anchor (band 1v5+)",value:u,total:i.filter(t=>t.pair_type==="anchor").length}),e.jsx($,{label:"Adjacent boundaries",value:m,total:i.filter(t=>t.pair_type==="adjacent").length}),e.jsx($,{label:"Questions flagged",value:null,total:n.length,unit:"flags"})]}),e.jsxs("section",{className:"cal-review-section",children:[e.jsx("h3",{children:"Agreement by form"}),e.jsx("div",{className:"cal-review-table-wrap",children:e.jsxs("table",{className:"cal-review-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Form"}),e.jsx("th",{children:"Pairs"}),e.jsx("th",{children:"Agreement"}),e.jsx("th",{children:"Adjacent"}),e.jsx("th",{children:"Anchor"}),e.jsx("th",{children:"Weakest boundary"})]})}),e.jsx("tbody",{children:o.map(t=>e.jsxs("tr",{className:t.agreementPct<70?"cal-row-warn":"",children:[e.jsx("td",{className:"cal-cell-form",children:t.form}),e.jsx("td",{children:t.total}),e.jsxs("td",{className:"cal-cell-pct",children:[t.agreementPct,"%"]}),e.jsx("td",{children:t.adjacentTotal>0?`${Math.round(t.adjacentAgreed/t.adjacentTotal*100)}%`:"—"}),e.jsx("td",{children:t.anchorTotal>0?`${Math.round(t.anchorAgreed/t.anchorTotal*100)}%`:"—"}),e.jsx("td",{children:t.weakestBoundary??"—"})]},t.form))})]})})]}),n.length>0&&e.jsxs("section",{className:"cal-review-section",children:[e.jsxs("h3",{children:["Flagged questions (",n.length,")"]}),e.jsx("div",{className:"cal-flag-list",children:n.map(t=>{const s=a.byId.get(t.question_id)??null,f=s?E(s,O[s.strand_id]??s.strand_id):null;return e.jsxs("div",{className:"cal-flag-item",children:[e.jsxs("div",{className:"cal-flag-item-meta",children:[e.jsx("span",{className:"cal-flag-item-id",children:t.question_id}),e.jsx("span",{className:`cal-flag-type-badge cal-flag-type-${t.flag_type}`,children:t.flag_type.replace(/_/g," ")}),t.notes&&e.jsx("span",{className:"cal-flag-item-notes",children:t.notes}),e.jsxs("span",{className:"cal-flag-item-judge",children:["— ",t.judge_name]})]}),f&&e.jsx("div",{className:"cal-flag-item-preview",children:e.jsx(M,{question:f,selectedAnswer:null,status:"incorrect",attemptsExhausted:!0,onChangeAnswer:()=>{}
1,onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1,hideDebugBar:!0,hideKeypad:!0})})]},t.id)})})]}),c.length>0&&e.jsxs("section",{className:"cal-review-section",children:[e.jsxs("h3",{children:["Disagreements — formula vs judge (",c.length,")"]}),e.jsx("div",{className:"cal-disagreement-list",children:c.map(t=>{const s=a.byId.get(t.left_question_id)??null,f=a.byId.get(t.right_question_id)??null;return e.jsxs("div",{className:"cal-disagreement-item",children:[e.jsxs("div",{className:"cal-disagreement-meta",children:[e.jsx("span",{className:"cal-cell-form",children:t.mathematical_form}),e.jsxs("span",{className:"cal-disagreement-bands",children:["bands ",t.left_band," vs ",t.right_band]}),e.jsxs("span",{className:"cal-disagreement-verdict",children:["Formula: ",t.expected==="left_harder"?"Left":"Right"," harder · Judge: ",t.response==="same"?"Same":t.response==="left_harder"?"Left":"Right"," harder"]})]}),e.jsxs("div",{className:"cal-pair-row cal-pair-row--compact",children:[s&&e.jsxs("div",{className:"cal-question-col",children:[e.jsx(M,{question:E(s,O[s.strand_id]??s.strand_id),selectedAnswer:null,status:"incorrect",attemptsExhausted:!0,onChangeAnswer:()=>{},onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1,hideDebugBar:!0,hideKeypad:!0}),e.jsxs("div",{className:"cal-band-label",children:["Band ",t.left_band]})]}),e.jsx("div",{className:"cal-vs-divider",children:"vs"}),f&&e.jsxs("div",{className:"cal-question-col",children:[e.jsx(M,{question:E(f,O[f.strand_id]??f.strand_id),selectedAnswer:null,status:"incorrect",attemptsExhausted:!0,onChangeAnswer:()=>{},onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1,hideDebugBar:!0,hideKeypad:!0}),e.jsxs("div",{className:"cal-band-label",children:["Band ",t.right_band]})]})]})]},t.id)})})]})]})}function $({label:i,value:n,total:o,unit:u="responses"}){return e.jsxs("div",{className:"cal-stat-card",children:[e.jsx("div",{className:"cal-stat-value",children:n!==null?`${n}%`:o}),e.jsx("div",{className:"cal-stat-label",children:i}),e.jsxs("div",{className:"cal-stat-sub",children:[o," ",u]})]})}const ne={number_place_value:"Number & Place Value",addition_subtraction:"Addition & Subtraction",multiplication_division:"Multiplication & Division",fractions_decimals_percentages:"Fractions, Decimals & Percentages",measurement:"Measurement",geometry:"Shape & Space",data_statistics:"Data & Statistics"},ie=[10,20,30,50];function re(){const i=l.useState(()=>[...L().byId.values()].filter(N=>N.typical_year_band_id==="year_1"&&N.status==="approved"))[0],[n,o]=l.useState("setup"),[u,m]=l.useState(""),[d,p]=l.useState("year_1"),[r,a]=l.useState(20),[c,t]=l.useState(0),[s,f]=l.useState([]),[S,_]=l.useState(!1),[q,h]=l.useState(null),[x,y]=l.useState(null),[j,C]=l.useState(""),[w,D]=l.useState(new Map),A=s.slice(0,r),k=A[c]??null,T=c===A.length-1,b=l.useMemo(()=>{if(!k)return[];const g=k.answer_spec;if(g.kind!=="select")return[];const N=g;return N.options.filter(I=>!N.correct_option_ids.includes(I.id)).map(I=>({id:I.id,label:I.label}))},[k]),R=x!==null&&(b.length===0||b.every(g=>w.has(g.id))),P=()=>{y(null),C(""),D(new Map),h(null)},J=()=>{u.trim()&&(f([...i].sort(()=>Math.random()-.5)),o("running"),t(0),P())},B=async(g=!1,N)=>{const I=N??x;if(!g&&k&&I){_(!0),h(null);try{if(v&&(await v.from("clarity_reviews").insert({question_id:k.id,judge_name:u.trim(),year_group:d,rating:I,notes:j.trim()||null}),!N))for(const[Q,H]of w.entries()){const z=b.find(G=>G.id===Q)?.label??Q;await v.from("distractor_reviews").insert({question_id:k.id,distractor_id:Q,distractor_label:z,judge_name:u.trim(),year_group:d,rating:H})}}catch{h("Failed to save — check Supabase connection"),_(!1);return}_(!1)}T?o("done"):(t(Q=>Q+1),P())};if(n==="setup")return e.jsxs("div",{className:"cal-setup",children:[e.jsx("h2",{className:"cal-setup-title",children:"Question Review Setup"}),e.jsxs("p",{className:"qr-setup-available",children:[i.length," Year 1 approved questions available"]}),e.jsx("div",{className:"cal-setup-fields",children:e.jsxs("label",{className:"cal-setup-label",children:["Your name",e.jsx("input",{className:"cal-setup-input",type:"text",placeholder:"e.g. Luca",value:u,onChange:g=>m(g.target.value)})]})}),e.jsx("p",{className:"cal-setup-count",children:"Your year group"}),e.jsx("div",{className:"count-pill-row qr-year-pill-row",role:"group","aria-label":"Year group",children:["reception","year_1","year_2","year_3","year_4","year_5","year_6"].map(g=>e.jsx("button",{type:"button",className:`count-pill ${d===g?"active":""}`,onClick:()=>p(g),children:e.jsx("span",{children:g==="reception"?"Reception":g.replace(/_/g," ").replace(/\b\w/g,N=>N.toUpperCase())})},g))}),e.jsx("p",{className:"cal-setup-count",children:"How many questions?"}),e.jsx("div",{className:"count-pill-row qr-count-pill-row",role:"group","aria-label":"Question count",children:ie.map(g=>e.jsxs("button",{type:"button",className:`count-pill ${r===g?"active":""}`,onClick:()=>a(g),children:[e.jsx("span",{children:g}),e.jsx("small",{children:"questions"})]},g))}),e.jsx("button",{className:"cal-setup-start",type:"button",disabled:!u.trim(),onClick:J,children:"Start reviewing"})]});if(n==="done")return e.jsxs("div",{className:"cal-done",children:[e.jsx("div",{className:"cal-done-check",children:"✓"}),e.jsx("h2",{children:"Review complete!"}),e.jsxs("p",{children:["All ",A.length," questions reviewed. Results saved to Supabase."]}),e.jsx("button",{className:"cal-setup-start",type:"button",onClick:()=>{f([]),o("setup"),t(0),P()},children:"Start another session"})]});if(!k)return null;const K=E(k,ne[k.strand_id]??k.strand_id);return e.jsxs("div",{className:"qr-runner",children:[e.jsxs("div",{className:"cal-runner-progress",children:[e.jsxs("span",{children:[c+1," / ",A.length]}),e.jsx("span",{className:"cal-runner-form",children:k.mathematical_form}),e.jsx("span",{className:"cal-runner-type",children:k.interaction_type})]}),e.jsx("div",{className:"qr-question-wrap",children:e.jsx(M,{question:K,selectedAnswer:K.correctAnswer,status:"incorrect",attemptsExhausted:!0,hideKeypad:!0,onChangeAnswer:()=>{}
1,onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1})}),e.jsxs("div",{className:"qr-section",children:[e.jsx("p",{className:"qr-section-label",children:"Wording clarity"}),e.jsx("p",{className:"qr-section-hint",children:"Would a Year 1 child understand what this question is asking?"}),e.jsx("div",{className:"qr-rating-row",children:["clear","unsure","confusing"].map(g=>e.jsx("button",{type:"button",className:`qr-rating-btn qr-clarity-${g} ${x===g?"qr-rating-btn--active":""}`,onClick:()=>{y(g),g==="clear"&&B(!1,"clear")},children:g==="clear"?"Clear ✓":g==="unsure"?"Unsure ?":"Confusing ✗"},g))}),x&&x!=="clear"&&e.jsx("input",{className:"qr-notes-input",type:"text",placeholder:"Optional: what's confusing about it?",value:j,onChange:g=>C(g.target.value)})]}),b.length>0&&e.jsxs("div",{className:"qr-section",children:[e.jsx("p",{className:"qr-section-label",children:"Wrong answers"}),e.jsx("p",{className:"qr-section-hint",children:"Rate each wrong answer — would it fool a Year 1 child?"}),e.jsx("div",{className:"qr-distractor-list",children:b.map(g=>e.jsxs("div",{className:"qr-distractor-row",children:[e.jsxs("span",{className:"qr-distractor-label",children:["“",g.label,"”"]}),e.jsx("div",{className:"qr-rating-row",children:["too_easy","plausible","tricky"].map(N=>e.jsx("button",{type:"button",className:`qr-rating-btn qr-dist-${N} ${w.get(g.id)===N?"qr-rating-btn--active":""}`,onClick:()=>D(I=>new Map(I).set(g.id,N)),children:N==="too_easy"?"Too obvious":N==="plausible"?"Could fool them":"Nearly got them"},N))})]},g.id))})]}),q&&e.jsx("p",{className:"cal-setup-error",children:q}),e.jsxs("div",{className:"qr-nav-row",children:[e.jsx("button",{className:"qr-skip-btn",type:"button",onClick:()=>{B(!0)},children:"Skip"}),e.jsx("button",{className:"cal-setup-start",type:"button",disabled:!R||S,onClick:()=>{B(!1)},children:S?"Saving…":T?"Finish":"Next question →"})]})]})}function le(){const[i,n]=l.useState([]),[o,u]=l.useState([]),[m,d]=l.useState([]),[p,r]=l.useState(!0),[a,c]=l.useState(null),[t,s]=l.useState(0);l.useEffect(()=>{if(!v){c("Supabase not configured"),r(!1);return}(async()=>{r(!0);try{const[h,x,y]=await Promise.all([v.from("clarity_reviews").select("*").order("created_at",{ascending:!0}),v.from("distractor_reviews").select("*").order("created_at",{ascending:!0}),v.from("question_actions").select("*").order("created_at",{ascending:!0})]);if(h.error)throw h.error;if(x.error)throw x.error;if(y.error)throw y.error;n(h.data??[]),u(x.data??[]),d(y.data??[])}catch(h){c(h instanceof Error?h.message:"Failed to load review data")}finally{r(!1)}})()},[t]);const f=l.useCallback(()=>s(h=>h+1),[]),S=l.useCallback(async(h,x,y,j,C)=>{if(!v)return;const w=m.find(A=>A.question_id===h&&A.issue_type===x),D=new Date().toISOString();w?await v.from("question_actions").update({status:y,action_notes:j??w.action_notes,actioned_by:C??w.actioned_by,actioned_at:y==="done"?D:w.actioned_at}).eq("id",w.id):await v.from("question_actions").insert({question_id:h,issue_type:x,status:y,action_notes:j??null,actioned_by:C??null,actioned_at:y==="done"?D:null}),f()},[m,f]),_=ce(i,o,m),q={totalClarityReviewed:new Set(i.map(h=>h.question_id)).size,confusingCount:_.filter(h=>h.issueTypes.includes("clarity")).length,totalDistractorReviewed:new Set(o.map(h=>h.question_id)).size,weakDistractorCount:_.filter(h=>h.issueTypes.includes("distractor")).length,openIssues:_.filter(h=>!h.action||h.action.status==="open").length,doneIssues:_.filter(h=>h.action?.status==="done").length};return{clarityReviews:i,distractorReviews:o,actions:m,issues:_,stats:q,loading:p,error:a,reload:f,updateActionStatus:S}}function ce(i,n,o){const u=new Set(i.filter(r=>r.rating!=="clear").map(r=>r.question_id)),m=new Map;for(const r of n)m.has(r.question_id)||m.set(r.question_id,[]),m.get(r.question_id).push(r);const d=new Set([...m.entries()].filter(([,r])=>r.some(a=>a.rating==="too_easy")).map(([r])=>r));return[...new Set([...u,...d])].map(r=>{const a=i.filter(x=>x.question_id===r),c=m.get(r)??[],t=a.some(x=>x.rating==="confusing"),s=a.some(x=>x.rating==="unsure"),f=t?"confusing":s?"unsure":null,S=a.find(x=>x.notes)?.notes??null,_=[...new Set(c.filter(x=>x.rating==="too_easy").map(x=>x.distractor_label))],q=[];u.has(r)&&q.push("clarity"),d.has(r)&&q.push("distractor");const h=o.filter(x=>x.question_id===r).sort((x,y)=>new Date(y.created_at).getTime()-new Date(x.created_at).getTime())[0]??null;return{questionId:r,issueTypes:q,clarityRating:f,clarityNotes:S,weakDistractors:_,action:h}})}const oe={number_place_value:"Number & Place Value",addition_subtraction:"Addition & Subtraction",multiplication_division:"Multiplication & Division",fractions_decimals_percentages:"Fractions, Decimals & Percentages",measurement:"Measurement",geometry:"Shape & Space",data_statistics:"Data & Statistics"};function de(){const{issues:i,stats:n,loading:o,error:u,updateActionStatus:m}=le(),d=l.useMemo(()=>L(),[]),[p,r]=l.useState("all"),[a,c]=l.useState(null),t=i.filter(s=>p==="all"?!0:(s.action?.status??"open")===p);return o?e.jsx("div",{className:"cal-review-loading",children:"Loading review data…"}):u?e.jsx("div",{className:"cal-review-error",children:u}):i.length===0?e.jsxs("div",{className:"cal-review-empty",children:[e.jsx("p",{children:"No issues found yet."}),e.jsx("p",{children:"Run a Question Review session to collect clarity and distractor ratings."})]}):e.jsxs("div",{className:"qr-dashboard",children:[e.jsxs("div",{className:"cal-review-stats",children:[e.jsx(F,{value:n.totalClarityReviewed,label:"Reviewed for clarity",sub:"unique questions"}),e.jsx(F,{value:n.confusingCount,label:"Clarity issues",sub:"unsure or confusing"}),e.jsx(F,{value:n.totalDistractorReviewed,label:"Reviewed for distractors",sub:"unique questions"}),e.jsx(F,{value:n.weakDistractorCount,label:"Weak distractor issues",sub:"too-easy options foun
1d"}),e.jsx(F,{value:n.openIssues,label:"Open issues",sub:"need action"}),e.jsx(F,{value:n.doneIssues,label:"Fixed",sub:"marked done"})]}),e.jsx("div",{className:"qr-filter-row",children:["all","open","in_progress","done"].map(s=>e.jsx("button",{type:"button",className:`cal-tab ${p===s?"cal-tab--active":""}`,onClick:()=>r(s),children:s==="all"?"All":s==="in_progress"?"In progress":s.charAt(0).toUpperCase()+s.slice(1)},s))}),t.length===0?e.jsx("div",{className:"cal-review-empty",children:"No issues matching this filter."}):e.jsx("div",{className:"qr-issues-list",children:t.map(s=>e.jsx(ue,{issue:s,index:d,expanded:a===s.questionId,onToggle:()=>c(f=>f===s.questionId?null:s.questionId),onStatusChange:f=>{m(s.questionId,s.issueTypes[0],f)}},s.questionId))})]})}function F({value:i,label:n,sub:o}){return e.jsxs("div",{className:"cal-stat-card",children:[e.jsx("div",{className:"cal-stat-value",children:i}),e.jsx("div",{className:"cal-stat-label",children:n}),e.jsx("div",{className:"cal-stat-sub",children:o})]})}function ue({issue:i,index:n,expanded:o,onToggle:u,onStatusChange:m}){const d=n.byId.get(i.questionId),p=i.action?.status??"open",r=d?E(d,oe[d.strand_id]??d.strand_id):null;return e.jsxs("div",{className:`qr-issue-item qr-issue-status-${p}`,children:[e.jsxs("div",{className:"qr-issue-head",children:[e.jsxs("div",{className:"qr-issue-meta",children:[e.jsx("span",{className:"cal-cell-form",children:i.questionId}),d&&e.jsx("span",{className:"cal-runner-form",children:d.mathematical_form}),i.issueTypes.map(a=>e.jsx("span",{className:`qr-issue-badge qr-issue-badge--${a}`,children:a==="clarity"?`Clarity: ${i.clarityRating}`:`Distractors: ${i.weakDistractors.length} too easy`},a))]}),e.jsxs("div",{className:"qr-issue-actions",children:[e.jsxs("select",{className:"qr-status-select",value:p,onChange:a=>m(a.target.value),children:[e.jsx("option",{value:"open",children:"Open"}),e.jsx("option",{value:"in_progress",children:"In progress"}),e.jsx("option",{value:"done",children:"Done"})]}),e.jsx("button",{type:"button",className:"qr-expand-btn",onClick:u,children:o?"▲ Hide":"▼ Show"})]})]}),d&&e.jsx("p",{className:"qr-issue-stem",children:d.prompt.stem}),i.clarityNotes&&e.jsxs("p",{className:"qr-issue-notes",children:["Note: “",i.clarityNotes,"”"]}),i.weakDistractors.length>0&&e.jsxs("p",{className:"qr-issue-notes",children:["Too-easy answers: ",i.weakDistractors.map(a=>`"${a}"`).join(", ")]}),o&&r&&e.jsx("div",{className:"qr-issue-preview",children:e.jsx(M,{question:r,selectedAnswer:r.correctAnswer,status:"incorrect",attemptsExhausted:!0,hideKeypad:!0,onChangeAnswer:()=>{},onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1})})]})}function fe({onBackHome:i}){const[n,o]=l.useState("session"),[u,m]=l.useState([]),[d,p]=l.useState(!0),[r,a]=l.useState(null);l.useEffect(()=>{if(!v){a("Supabase is not configured. Add VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY to your .env file."),p(!1);return}(async()=>{try{const{data:t,error:s}=await v.from("questions").select("id, mathematical_form, complexity_band, typical_year_band_id").eq("status","approved").eq("typical_year_band_id","year_1").not("complexity_band","is",null);if(s)throw s;m(t??[])}catch(t){a(t instanceof Error?t.message:"Failed to load questions")}finally{p(!1)}})()},[]);const c=l.useMemo(()=>u.length?he(u):[],[u]);return e.jsxs("div",{className:"cal-page",children:[e.jsxs("header",{className:"cal-header",children:[e.jsx("button",{className:"cal-back-btn",type:"button",onClick:i,children:"← Back"}),e.jsx("h1",{children:"Difficulty Calibration"}),e.jsxs("div",{className:"cal-tabs",children:[e.jsx("span",{className:"cal-tab-group-label",children:"Difficulty"}),e.jsx("button",{type:"button",className:`cal-tab ${n==="session"?"cal-tab--active":""}`,onClick:()=>o("session"),children:"Run Session"}),e.jsx("button",{type:"button",className:`cal-tab ${n==="review"?"cal-tab--active":""}`,onClick:()=>o("review"),children:"Results"}),e.jsx("span",{className:"cal-tab-divider"}),e.jsx("span",{className:"cal-tab-group-label",children:"Question Review"}),e.jsx("button",{type:"button",className:`cal-tab ${n==="qr-session"?"cal-tab--active":""}`,onClick:()=>o("qr-session"),children:"Run Session"}),e.jsx("button",{type:"button",className:`cal-tab ${n==="qr-review"?"cal-tab--active":""}`,onClick:()=>o("qr-review"),children:"Issues"})]})]}),e.jsxs("div",{className:"cal-body",children:[r&&e.jsx("div",{className:"cal-error-banner",children:r}),n==="session"&&!r&&(d?e.jsx("div",{className:"cal-loading",children:"Loading questions..."}):c.length===0?e.jsxs("div",{className:"cal-empty",children:[e.jsxs("p",{children:["No Year 1 questions with ",e.jsx("code",{children:"complexity_band"})," found."]}),e.jsx("p",{children:"Run the Track C Phase 1 migration to populate complexity scores, then return here."})]}):e.jsx(ee,{pairs:c,onBackToSetup:()=>o("session")})),n==="review"&&e.jsx(ae,{}),n==="qr-session"&&e.jsx(re,{}),n==="qr-review"&&e.jsx(de,{})]})]})}function he(i){const n=new Map;for(const u of i){const m=u.mathematical_form??"unknown";n.has(m)||n.set(m,[]),n.get(m).push(u)}const o=[];for(const[u,m]of n){const d=new Map;for(const c of m){const t=c.complexity_band;d.has(t)||d.set(t,[]),d.get(t).push(c)}const p=[...d.keys()].sort((c,t)=>c-t);if(p.length<2)continue;for(let c=0;c<p.length-1;
1c++){const t=p[c],s=p[c+1],f=d.get(t)[0],S=d.get(s)[0];if(!f||!S)continue;const _=Math.random()<.5;o.push({question_a_id:f.id,question_b_id:S.id,a_band:t,b_band:s,mathematical_form:u,pair_type:"adjacent",left_id:_?f.id:S.id,right_id:_?S.id:f.id,left_band:_?t:s,right_band:_?s:t,expected:_?"right_harder":"left_harder"})}const r=p[0],a=p[p.length-1];if(a-r>1){const c=d.get(r)[0],t=d.get(a)[0];if(c&&t){const s=Math.random()<.5;o.push({question_a_id:c.id,question_b_id:t.id,a_band:r,b_band:a,mathematical_form:u,pair_type:"anchor",left_id:s?c.id:t.id,right_id:s?t.id:c.id,left_band:s?r:a,right_band:s?a:r,expected:s?"right_harder":"left_harder"})}}}return o.sort(()=>Math.random()-.5)}export{fe as CalibrationPage};

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.