PageSourceSearch

https://smartmaths.ai/assets/WexReviewScreen-CCGVrCOJ.js

js smartmaths.ai collected 2026-10-05 15:06:12 UTC 14,373 bytes, 1 lines download raw bytes

1import{r as c,j as e,F as me,h as xe,g as z,l as fe,i as ve,k as Z,n as Q,o as ee,e as we,Q as ye}from"./main-Dt7Bgl8i.js";import"./curriculum-data-UeTaQjv3.js";import"./worked-examples-BExh4ce1.js";function ge({example:l}){const[n,i]=c.useState(0),[o,x]=c.useState(0),y=c.useRef(null);c.useEffect(()=>{i(0)},[l]),c.useEffect(()=>{x(v=>v+1)},[n]),c.useEffect(()=>()=>{y.current?.cancel(),y.current=null},[l]);const b=l.steps,f=b[n],I=n+1,g=n===b.length-1,E=()=>{window.setTimeout(()=>{y.current?.cancel(),y.current=xe(f.spoken,{rate:.92,pitch:1.02})},0)},p=()=>{window.setTimeout(()=>x(v=>v+1),0)};return e.jsxs("div",{className:"wexr-player",children:[e.jsx("p",{className:"wexr-demo-title",children:l.title}),e.jsx("div",{className:"wexr-stage",children:e.jsx(me,{step:f,stepNumber:I,replayKey:o})}),e.jsx("p",{className:"wexr-caption",children:f.caption},`cap-${n}-${o}`),e.jsxs("div",{className:"wexr-controls",children:[e.jsx("button",{type:"button",onClick:()=>i(v=>Math.max(0,v-1)),disabled:n===0,children:"‹ Prev"}),e.jsxs("span",{className:"wexr-stepnum",children:["Step ",n+1," / ",b.length]}),e.jsx("button",{type:"button",onClick:()=>i(v=>Math.min(b.length-1,v+1)),disabled:g,children:"Next ›"}),e.jsx("button",{type:"button",className:"wexr-icon",onClick:p,title:"Replay animation",children:"↻ Replay"}),e.jsx("button",{type:"button",className:"wexr-icon",onClick:E,title:"Play narration",children:"🔊 Voice"})]}),e.jsxs("details",{className:"wexr-script",children:[e.jsx("summary",{children:"Full script (caption + narration)"}),e.jsx("ol",{children:b.map((v,j)=>e.jsxs("li",{children:[e.jsx("b",{children:v.caption}),e.jsxs("span",{className:"wexr-script-spoken",children:[" ",v.spoken]})]},j))})]})]})}const te="wex-review-v1",se="wex-review-filters-v1";function je(){try{return JSON.parse(window.localStorage.getItem(se)??"{}")}catch{return{}}}function ke(l,n){const i=new Date;switch(l){case"today":return new Date(i.getFullYear(),i.getMonth(),i.getDate()).getTime();case"7d":return i.getTime()-10080*60*1e3;case"30d":return i.getTime()-720*60*60*1e3;case"month":return new Date(i.getFullYear(),i.getMonth(),1).getTime();case"custom":return n?new Date(n).getTime():null;default:return null}}function U(l){return new Date(l).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})}const be={AS:"addition_subtraction",NPV:"number_place_value",MD:"multiplication_division",FDP:"fractions_decimals_percentages",MEA:"measurement",GEO:"geometry",DS:"data_statistics",RP:"ratio_proportion"},P={addition_subtraction:"Addition & Subtraction",number_place_value:"Number & Place Value",multiplication_division:"Multiplication & Division",fractions_decimals_percentages:"Fractions",measurement:"Measurement",geometry:"Geometry",data_statistics:"Data & Statistics",ratio_proportion:"Ratio & Proportion"},M=Object.keys(P);function q(l){return be[l.split(".")[0]]??"addition_subtraction"}function Ne(l){return l.form?ee(l.microSkillId,l.form):Q(l.microSkillId)}function Se(){try{return JSON.parse(window.localStorage.getItem(te)??"{}")}catch{return{}}}const ne="/api/dev-question-reviews?kind=wex";async function T(l,n){try{const i=await Z();await fetch(ne,{method:"POST",headers:{...i,"Content-Type":"application/json"},body:JSON.stringify({micro_skill_id:l,verdict:n.verdict,feedback:n.feedback,content_hash:n.contentHash})})}catch{}}function _e(l){const n=JSON.stringify(l);let i=5381;for(let o=0;o<n.length;o++)i=(i<<5)+i+n.charCodeAt(o)|0;return(i>>>0).toString(36)}function $(l){const n=Q(l);return n?_e(n):null}function Ce(l,n){const o=(z().byMicroSkill.get(l)??[]).filter(x=>x.status!=="deleted"&&x.status!=="draft");return o.find(x=>x.visual_data?.type===n)??o.find(x=>x.visual_data)??o[0]}function De({microSkillId:l,demoVisualType:n}){const i=c.useMemo(()=>{const o=Ce(l,n);if(!o)return null;try{return we(o,P[q(l)]??"")}catch{return null}},[l,n]);return i?e.jsx(ye,{question:i,selectedAnswer:null,status:"incorrect",attemptsExhausted:!0,onChangeAnswer:()=>{},onSpeakQuestion:()=>{},canSpeak:!1,isSpeaking:!1,hideDebugBar:!0,hideKeypad:!0}):e.jsx("div",{className:"wexr-noq",children:"No renderable question found for this skill."})}function Ee({onBackHome:l}){const n=c.useMemo(()=>{const t=z(),s=r=>{const a=t.byMicroSkill.get(r)?.[0]?.typical_year_band_id??"";return/^year_\d$/.test(a)?a.replace("year_","Y"):"—"},d=fe().map(r=>{const a=Q(r);return{id:r,microSkillId:r,title:a?.title??r,strandId:q(r),year:s(r)}}),u=ve().map(r=>{const[a,w]=r.split("::"),A=ee(a,w);return{id:`${a} · ${w}`,microSkillId:a,form:w,title:A?.title??r,strandId:q(a),year:s(a)}});return[...d,...u].sort((r,a)=>M.indexOf(r.strandId)-M.indexOf(a.strandId)||r.id.localeCompare(a.id))},[]),i=c.useMemo(()=>je(),[]),[o,x]=c.useState(Se),[y,b]=c.useState(i.search??""),[f,I]=c.useState(i.strand??"all"),[g,E]=c.useState(i.year??"all"),[p,v]=c.useState(i.status??"all"),[j,W]=c.useState(i.datePreset??"any"),[_,V]=c.useState(i.customDate??""),[N,H]=c.useState(i.neverReviewed??!1),[k,ae]=c.useState(i.sortBy??"strand"),[S,O]=c.useState(n[0]?.id??""),[L,Y]=c.useState(""),[re,G]=c.useState(!1);c.useEffect(()=>{window.localStorage.setItem(te,JSON.stringify(o))},[o]),c.useEffect(()=>{window.localStorage.setItem(se,JSON.stringify({search:y,strand:f,year:g,status:p,datePreset:j,customDate:_,neverReviewed:N,sortBy:k}))},[y,f,g,p,j,_,N,k]),c.useEffect(()=>{let t=!1;return Z().then(s=>fetch(ne,{headers:s})).then(s=>s.ok?s.json():null).then(s=>{t||!s?.reviews||x(d=>{const u={};for(const a of s.reviews)u[a.micro_skill_id]={verdict:a.verdict,feedback:a.feedback??"",ts:Date.parse(a.updated_at)||Date.now(),contentHash:a.content_hash??void 0};for(const a of Object.keys(d))u[a]||T(a,d[a]);const r={...d,...u};for(const a of Object.keys(r)){const w=r[a];if(w.verdict==="approve"&&!w.contentHash){const A=$(a);A&&(r[a]={...w,contentHash:A},T(a,r[a]))}}return r})}).catch(()=>{}),()=>{t=!0}},[]),c.useEffect(()=>{Y(o[S]?.feedback??"")},[S]),c.useEffect(()=>{h.length&&!h.some(t=>t.id===S)&&O(h[0].id)},[y,f,g,p,j,_,N]);const D=c.useMemo(()=>{const t=new Set;for(const s of Object.keys(o)){const d=o[s];d.verdict==="approve"&&d.contentHash&&d.contentHash!==$(s)&&t.add(s)}return t},[o]),C=t=>
1D.has(t)?"changed":o[t]?.verdict??"none",h=c.useMemo(()=>{const t=y.trim().toLowerCase(),s=ke(j,_),d=n.filter(u=>{if(g!=="all"&&u.year!==g||f!=="all"&&u.strandId!==f)return!1;const r=o[u.id];if(t&&!`${u.id} ${u.title} ${r?.feedback??""}`.toLowerCase().includes(t))return!1;if(N){if(r)return!1}else if(s!==null&&(!r||r.ts<s))return!1;const a=C(u.id);return p==="todo"?a==="none"||a==="changed":p==="needs-work"?a==="needs-work":p==="approve"?a==="approve":p==="changed"?a==="changed":!0});return k==="strand"?d:[...d].sort((u,r)=>{const a=o[u.id]?.ts??0,w=o[r.id]?.ts??0;return a===0&&w===0?u.id.localeCompare(r.id):a===0?1:w===0?-1:k==="recent"?w-a:a-w})},[n,o,D,y,f,g,p,j,_,N,k]),m=n.find(t=>t.id===S),B=m?Ne(m):null,ie=B?.steps?.[0]?.visual_data?.type,R=c.useMemo(()=>{let t=0,s=0,d=0;for(const u of n)if(D.has(u.id))d++;else{const r=o[u.id]?.verdict;r==="approve"?t++:r==="needs-work"&&s++}return{approved:t,needsWork:s,changed:d,total:n.length,unreviewed:n.length-t-s-d}},[n,o,D]),oe=t=>{const s=h.findIndex(d=>d.id===t);return(h[s+1]??h.find(d=>d.id!==t))?.id},K=t=>{if(!m)return;const s={verdict:t,feedback:t==="needs-work"?L:"",ts:Date.now(),contentHash:$(m.id)??void 0},d=t==="approve"&&p!=="all"&&p!=="approve"?oe(m.id):null;x(u=>({...u,[m.id]:s})),T(m.id,s),d&&O(d)},X=()=>{if(!m)return;const t={verdict:"needs-work",feedback:L,ts:Date.now(),contentHash:$(m.id)??void 0};x(s=>({...s,[m.id]:t})),T(m.id,t)},ce=()=>{const t=h.findIndex(s=>s.id===S);for(let s=1;s<=h.length;s++){const d=h[(t+s)%h.length],u=C(d.id);if(u==="none"||u==="changed"){O(d.id);return}}},le=async()=>{const t={generatedAt:new Date().toISOString(),approved:n.filter(s=>C(s.id)==="approve").map(s=>s.id),changed:n.filter(s=>C(s.id)==="changed").map(s=>s.id),needsWork:n.filter(s=>C(s.id)==="needs-work").map(s=>({id:s.id,title:s.title,feedback:o[s.id]?.feedback??""}))};try{await navigator.clipboard.writeText(JSON.stringify(t,null,2)),G(!0),window.setTimeout(()=>G(!1),1500)}catch{}},F=o[S]?.verdict,J=o[S],de=c.useMemo(()=>Array.from(new Set(n.map(t=>t.year).filter(t=>t!=="—"))).sort(),[n]),ue=M.filter(t=>n.some(s=>s.strandId===t)),he=y!==""||f!=="all"||g!=="all"||p!=="all"||j!=="any"||N,pe=()=>{b(""),I("all"),E("all"),v("all"),W("any"),V(""),H(!1)};return e.jsxs("div",{className:"wexr-screen",children:[e.jsxs("header",{className:"wexr-header",children:[e.jsx("button",{type:"button",className:"wexr-back",onClick:l,children:"← Home"}),e.jsx("h1",{children:"Worked-example review"}),e.jsxs("div",{className:"wexr-progress",children:[e.jsxs("span",{className:"wexr-chip ok",children:[R.approved," approved"]}),e.jsxs("span",{className:"wexr-chip warn",children:[R.needsWork," needs work"]}),R.changed>0&&e.jsxs("span",{className:"wexr-chip changed",children:[R.changed," changed"]}),e.jsxs("span",{className:"wexr-chip muted",children:[R.unreviewed," to do"]})]}),e.jsxs("div",{className:"wexr-headtools",children:[e.jsx("button",{type:"button",onClick:ce,children:"Next to do →"}),e.jsx("button",{type:"button",className:"wexr-copy",onClick:le,children:re?"Copied ✓":"Copy feedback JSON"})]})]}),e.jsxs("div",{className:"wexr-filterbar",children:[e.jsx("input",{type:"text",className:"wexr-search",placeholder:"Search skill ID, title or feedback…",value:y,onChange:t=>b(t.target.value)}),e.jsxs("select",{value:f,onChange:t=>I(t.target.value),className:f!=="all"?"wexr-filter-active":"",children:[e.jsx("option",{value:"all",children:"All strands"}),ue.map(t=>e.jsx("option",{value:t,children:P[t]},t))]}),e.jsxs("select",{value:g,onChange:t=>E(t.target.value),className:g!=="all"?"wexr-filter-active":"",children:[e.jsx("option",{value:"all",children:"All years"}),de.map(t=>e.jsxs("option",{value:t,children:["Year ",t.slice(1)]},t))]}),e.jsxs("select",{value:p,onChange:t=>v(t.target.value),className:p!=="all"?"wexr-filter-active":"",children:[e.jsx("option",{value:"all",children:"All status"}),e.jsx("option",{value:"todo",children:"To review"}),e.jsx("option",{value:"needs-work",children:"Needs work"}),e.jsx("option",{value:"approve",children:"Approved"}),e.jsx("option",{value:"changed",children:"Changed (re-review)"})]}),e.jsxs("select",{value:j,onChange:t=>{W(t.target.value),H(!1)},className:j!=="any"&&!N?"wexr-filter-active":"",title:"Filter by when the verdict was given",children:[e.jsx("option",{value:"any",children:"Reviewed any time"}),e.jsx("option",{value:"today",children:"Reviewed today"}),e.jsx("option",{value:"7d",children:"Last 7 days"}),e.jsx("option",{value:"30d",children:"Last 30 days"}),e.jsx("option",{value:"month",children:"This month"}),e.jsx("option",{value:"custom",children:"Since date…"})]}
1),j==="custom"&&e.jsx("input",{type:"date",value:_,onChange:t=>V(t.target.value),className:_?"wexr-filter-active":""}),e.jsxs("label",{className:"wexr-checkbox",children:[e.jsx("input",{type:"checkbox",checked:N,onChange:t=>{H(t.target.checked),t.target.checked&&W("any")}}),"Not yet reviewed"]}),e.jsxs("select",{value:k,onChange:t=>ae(t.target.value),title:"Order of the skill list",children:[e.jsx("option",{value:"strand",children:"Sort: by strand"}),e.jsx("option",{value:"recent",children:"Sort: recently reviewed"}),e.jsx("option",{value:"oldest",children:"Sort: oldest review"})]}),he&&e.jsx("button",{type:"button",className:"wexr-clear",onClick:pe,children:"Clear filters"}),e.jsx("span",{className:"wexr-count",children:h.length===n.length?`${n.length} demos`:`${h.length} of ${n.length} demos`})]}),e.jsxs("div",{className:"wexr-body",children:[e.jsxs("nav",{className:"wexr-rail",children:[h.length===0&&e.jsx("p",{className:"wexr-rail-empty",children:"No demos match the filters."}),(k==="strand"?M.filter(t=>h.some(s=>s.strandId===t)).map(t=>({key:t,label:P[t],items:h.filter(s=>s.strandId===t)})):h.length?[{key:"sorted",label:k==="recent"?"Recently reviewed first":"Oldest review first",items:h}]:[]).map(t=>e.jsxs("div",{className:"wexr-rail-group",children:[e.jsx("h2",{children:t.label}),t.items.map(s=>{const d=C(s.id),u=o[s.id]?.ts,r=u?`Reviewed ${U(u)}`:"Not yet reviewed";return e.jsxs("button",{type:"button",className:`wexr-rail-item${s.id===S?" active":""}`,onClick:()=>O(s.id),title:d==="changed"?`Changed since approved — re-review · ${r}`:r,children:[e.jsx("span",{className:`wexr-dot ${d}`,"aria-hidden":"true"}),e.jsx("span",{className:"wexr-rail-id",children:s.id}),k!=="strand"&&u?e.jsx("span",{className:"wexr-rail-year",children:new Date(u).toLocaleDateString("en-GB",{day:"numeric",month:"short"})}):e.jsx("span",{className:"wexr-rail-year",children:s.year})]},s.id)})]},t.key))]}),e.jsx("main",{className:"wexr-main",children:!m||!B?e.jsx("p",{className:"wexr-empty",children:"Select a skill."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"wexr-split",children:[e.jsxs("section",{className:"wexr-pane",children:[e.jsxs("h3",{children:["The demo ",e.jsx("span",{className:"wexr-paneid",children:m.id})]}),e.jsx(ge,{example:B})]}),e.jsxs("section",{className:"wexr-pane",children:[e.jsx("h3",{children:"A question it leads into"}),e.jsx("p",{className:"wexr-sample-note",children:"Sample question from the bank — the demo's numbers and picture are deliberately different (demos must never copy a live question)."}),e.jsx(De,{microSkillId:m.microSkillId,demoVisualType:ie})]})]}),e.jsxs("div",{className:`wexr-verdict${F?` is-${F}`:""}`,children:[D.has(m.id)&&e.jsx("p",{className:"wexr-changed-note",children:"↻ This demo changed since it was approved — please re-review."}),J&&e.jsxs("p",{className:"wexr-reviewed-note",children:[J.verdict==="approve"?"Approved":"Marked needs-work"," on ",U(J.ts)]}),e.jsx("button",{type:"button",className:`wexr-approve${F==="approve"?" on":""}`,onClick:()=>K("approve"),children:"✓ Approve"}),e.jsx("button",{type:"button",className:`wexr-reject${F==="needs-work"?" on":""}`,onClick:()=>K("needs-work"),children:"⚠ Needs work"}),F==="needs-work"&&e.jsxs("div",{className:"wexr-feedback",children:[e.jsx("textarea",{autoFocus:!0,placeholder:"What needs more work? (saves automatically)",value:L,onChange:t=>Y(t.target.value),onBlur:X}),e.jsx("button",{type:"button",onClick:X,children:"Save note"})]})]})]})})]})]})}export{Ee as WexReviewScreen};

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.