PageSourceSearch

https://careerhelper.co.za/assets/www-course-Cy__c0Ez.js

js careerhelper.co.za collected 2026-10-08 11:31:05 UTC 18,776 bytes, 1 lines download raw bytes

1import{r as o,a7 as te,af as f,j as e,bN as ie,bK as X,ba as ae,bk as de,cm as fe,d4 as oe,ag as W,X as xe,aW as ve,bc as re,aY as he,by as ye,q as le,bb as ke,k as Ce,h as Se,aH as ce,ab as Ae,b4 as qe,bT as Ie,bO as me}from"./vendor-Bzh17y1V.js";import{u as Pe,b as pe,S as O,B as c,P as ze,c as _,I as je,z as be,f as v,q as A,C as J,g as Z,h as ee,a as se,T as ue,n as Le,v as Te}from"./chunk-admin-BtrU4a8O.js";function Fe({lesson:i,enrollment:ne,progress:K,onComplete:H}){const{toast:y}=pe(),q=K.find(s=>s.lessonId===i.id),b=q?.status==="completed",[u,M]=o.useState({}),[I,U]=o.useState({}),[w,E]=o.useState({}),[V,Q]=o.useState({}),[R,x]=o.useState(!1),[h,P]=o.useState(""),[z,k]=o.useState([]),d=o.useRef(null),[p,B]=o.useState(0),{data:g,isLoading:D}=te({queryKey:["/api/www/lessons",i.id,"quiz"],queryFn:()=>fetch(`/api/www/lessons/${i.id}/quiz`,{credentials:"include"}).then(s=>s.json()),enabled:(i.quizItems?.length??0)>0}),{data:L}=te({queryKey:["/api/www/lessons",i.id,"activity-submissions"],queryFn:()=>fetch(`/api/www/lessons/${i.id}/activity-submissions`,{credentials:"include"}).then(s=>s.json()),enabled:(i.activities?.length??0)>0}),G=f({mutationFn:()=>v("POST",`/api/www/lessons/${i.id}/start`).then(s=>s.json()),onSuccess:()=>A.invalidateQueries({queryKey:["/api/www/my-enrollment"]})}),m=f({mutationFn:()=>v("POST",`/api/www/lessons/${i.id}/complete`).then(s=>s.json()),onSuccess:()=>{A.invalidateQueries({queryKey:["/api/www/my-enrollment"]}),y({title:"Lesson completed!",description:"Your progress has been saved."}),H()}}),N=f({mutationFn:({itemId:s,answer:a})=>v("POST",`/api/www/quiz/${s}/attempt`,{answer:a}).then(r=>r.json()),onSuccess:s=>{U(a=>({...a,[s.quizItemId]:s}
1)),A.invalidateQueries({queryKey:["/api/www/lessons",i.id,"quiz"]})}}),T=f({mutationFn:({activityIndex:s,submissionText:a})=>v("POST",`/api/www/lessons/${i.id}/submit-activity`,{activityIndex:s,submissionText:a}).then(r=>r.json()),onSuccess:(s,a)=>{Q(r=>({...r,[a.activityIndex]:s.aiFeedback})),A.invalidateQueries({queryKey:["/api/www/lessons",i.id,"activity-submissions"]}),y({title:"Activity submitted!",description:s.needsFacilitatorReview?"A facilitator will review your submission.":"AI feedback provided."})}}),C=f({mutationFn:s=>v("POST","/api/www/ai-tutor",{lessonId:i.id,message:s,history:z}).then(a=>a.json()),onSuccess:s=>{k(a=>[...a,{role:"assistant",content:s.reply}])},onError:()=>{k(s=>[...s,{role:"assistant",content:"Sorry, I ran into an error. Please try again."}])}});o.useEffect(()=>{d.current?.scrollIntoView({behavior:"smooth"})},[z]),o.useEffect(()=>{q?.status==="not_started"&&G.mutate()},[i.id]);const Y=()=>{if(!h.trim())return;const s=h.trim();P(""),k(a=>[...a,{role:"user",content:s}]),C.mutate(s)},S=g?.items??[],t=g?.attempts??[],n=s=>{const a=I[s];return a||t.find(r=>r.quizItemId===s)};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[b&&e.jsxs(_,{className:"gap-1 bg-emerald-600 text-white",children:[e.jsx(le,{className:"h-3 w-3"}),"Completed"]}),q?.status==="in_progress"&&e.jsxs(_,{variant:"secondary",className:"gap-1",children:[e.jsx(he,{className:"h-3 w-3"}),"In Progress"]})]}),e.jsx("h2",{className:"text-xl font-bold",children:i.title})]}),i.learnerContent&&e.jsxs(J,{children:[e.jsx(Z,{className:"pb-3",children:e.jsxs(ee,{className:"text-sm flex items-center gap-2",children:[e.jsx(ae,{className:"h-4 w-4 text-primary"})," Lesson Content"]})}),e.jsx(se,{children:e.jsx("div",{className:"prose prose-sm dark:prose-invert max-w-none whitespace-pre-wrap text-sm leading-relaxed",children:i.learnerContent})})]}),i.activities&&i.activities.length>0&&e.jsxs(J,{children:[e.jsx(Z,{className:"pb-3",children:e.jsxs(ee,{className:"text-sm flex items-center gap-2",children:[e.jsx(ke,{className:"h-4 w-4 text-amber-500"})," Activities"]})}),e.jsx(se,{className:"space-y-4",children:i.activities.map((s,a)=>{const r=(L??[]).find(l=>l.activityIndex===a),j=V[a]??r?.aiFeedback,F=p===a;return e.jsxs("div",{className:"rounded-lg border",children:[e.jsxs("button",{className:"w-full flex items-center justify-between px-4 py-3 text-left hover:bg-muted/40 rounded-lg",onClick:()=>B(F?null:a),"data-testid":`button-expand-activity-${a}`,children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-medium uppercase tracking-wide text-muted-foreground",children:s.type}),e.jsx("span",{className:"font-medium text-sm",children:s.title}),r&&e.jsxs(_,{variant:"outline",className:"gap-1 text-xs",children:[e.jsx(le,{className:"h-3 w-3 text-emerald-600"}),"Submitted"]})]}),F?e.jsx(Ce,{className:"h-4 w-4 text-muted-foreground"}):e.jsx(Se,{className:"h-4 w-4 text-muted-foreground"})]}),F&&e.jsxs("div",{className:"px-4 pb-4 space-y-3 border-t pt-3",children:[e.jsx("p",{className:"text-sm text-muted-foreground whitespace-pre-wrap",children:s.instructions}),r?null:e.jsxs("div",{className:"space-y-2",children:[e.jsx(ue,{placeholder:"Type your response here...",value:w[a]??"",onChange:l=>E($=>({...$,[a]:l.target.value})),rows:4,"data-testid":`textarea-activity-${a}`}),e.jsxs(c,{size:"sm",disabled:!w[a]?.trim()||T.isPending,onClick:()=>T.mutate({activityIndex:a,submissionText:w[a]}),"data-testid":`button-submit-activity-${a}`,children:[T.isPending?e.jsx(W,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(ce,{className:"h-4 w-4 mr-2"}),"Submit"]})]}),j&&e.jsxs("div",{className:"rounded-md bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800/40 p-3",children:[e.jsxs("p",{className:"text-xs font-medium text-amber-700 dark:text-amber-400 mb-1 flex items-center gap-1",children:[e.jsx(Ae,{className:"h-3.5 w-3.5"})," AI Feedback"]}),e.jsx("p",{className:"text-sm text-amber-900 dark:text-amber-300",children:j}),r?.needsFacilitatorReview&&e.jsxs("p",{className:"text-xs text-amber-600 dar
1k:text-amber-500 mt-2 flex items-center gap-1",children:[e.jsx(qe,{className:"h-3 w-3"})," A facilitator will also review this submission."]})]})]})]},a)})})]}),(i.quizItems?.length??0)>0&&e.jsxs(J,{children:[e.jsxs(Z,{className:"pb-3",children:[e.jsxs(ee,{className:"text-sm flex items-center gap-2",children:[e.jsx(Ie,{className:"h-4 w-4 text-primary"})," Knowledge Check"]}),e.jsx(Le,{children:"Answer these questions to check your understanding."})]}),e.jsx(se,{className:"space-y-5",children:D?e.jsx("div",{className:"space-y-3",children:[1,2,3].map(s=>e.jsx(O,{className:"h-16"},s))}):S.map((s,a)=>{const r=n(s.id),j=!!r,F=u[s.id];return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("p",{className:"text-sm font-medium",children:[a+1,". ",s.question]}),s.questionType==="mcq"&&s.options?e.jsx("div",{className:"space-y-2",children:s.options.map(l=>{const $=F===l||r?.answer===l,we=r?.isCorrect&&r.answer===l,ge=!r?.isCorrect&&r?.answer===l;return e.jsx("button",{disabled:j,onClick:()=>M(Ne=>({...Ne,[s.id]:l})),className:`w-full text-left px-3 py-2 rounded-md border text-sm transition-colors ${we?"bg-emerald-50 border-emerald-400 dark:bg-emerald-900/20 dark:border-emerald-600":ge?"bg-red-50 border-red-400 dark:bg-red-900/20 dark:border-red-600":$&&!j?"border-primary bg-primary/5":"border-border hover:border-primary/50"}`,"data-testid":`option-${s.id}-${a}`,children:l},l)})}):e.jsx("div",{className:"space-y-2",children:e.jsx(ue,{placeholder:"Type your answer...",value:u[s.id]??r?.answer??"",onChange:l=>!j&&M($=>({...$,[s.id]:l.target.value})),disabled:j,rows:3,"data-testid":`textarea-quiz-${s.id}`})}),!j&&(u[s.id]||s.questionType==="short_answer")&&e.jsxs(c,{size:"sm",disabled:!u[s.id]?.trim()||N.isPending,onClick:()=>N.mutate({itemId:s.id,answer:u[s.id]}),"data-testid":`button-submit-quiz-${s.id}`,children:[N.isPending?e.jsx(W,{className:"h-4 w-4 animate-spin mr-2"}):null,"Submit Answer"]}),r&&e.jsxs("div",{className:`rounded-md border p-3 text-sm ${r.isCorrect?"bg-emerald-50 border-emerald-200 dark:bg-emerald-900/20 dark:border-emerald-700":"bg-red-50 border-red-200 dark:bg-red-900/20 dark:border-red-700"}`,children:[e.jsx("p",{className:`font-medium mb-1 ${r.isCorrect?"text-emerald-700 dark:text-emerald-400":"text-red-700 dark:text-red-400"}`,children:r.isCorrect?"✓ Correct!":"✗ Not quite"}),r.aiFeedback&&e.jsx("p",{className:"text-muted-foreground",children:r.aiFeedback})]}),a<S.length-1&&e.jsx(Te,{})]},s.id)})})]}),!b&&e.jsxs(c,{className:"w-full gap-2",onClick:()=>m.mutate(),disabled:m.isPending,"data-testid":"button-complete-lesson",children:[m.isPending?e.jsx(W,{className:"h-4 w-4 animate-spin"}):e.jsx(re,{className:"h-4 w-4"}),"Mark Lesson Complete"]}),b&&e.jsxs("div",{className:"flex items-center gap-2 rounded-lg bg-emerald-50 dark:bg-emerald-900/20 border border-emerald-200 dark:border-emerald-800/40 p-3",children:[e.jsx(re,{className:"h-5 w-5 text-emerald-600 dark:text-emerald-400 shrink-0"}),e.jsx("p",{className:"text-sm text-emerald-700 dark:text-emerald-400",children:"You've completed this lesson. Keep going!"})]}),e.jsx("div",{className:"fixed bottom-6 right-6 z-50",children:R?e.jsxs("div",{className:"w-80 rounded-xl border shadow-xl bg-background flex flex-col",style:{height:420},children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b bg-primary rounded-t-xl",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(me,{className:"h-4 w-4 text-primary-foreground"}),e.jsx("span",{className:"text-sm font-medium text-primary-foreground",children:"AI Tutor"})]}),e.jsx("button",{onClick:()=>x(!1),children:e.jsx(xe,{className:"h-4 w-4 text-primary-foreground"})})]}),e.jsxs(be,{className:"flex-1 p-3",children:[z.length===0&&e.jsx("p",{className:"text-xs text-muted-foreground text-center mt-4",children:"Ask me anything about this lesson! I'm here to help you understand the content."}),z.map((s,a)=>e.jsx("div",{className:`mb-3 flex ${s.role==="user"?"justify-end":"justify-start"}`,children:e.jsx("div",{className:`max-w-[85%] rounded-lg px-3 py-2 text-sm ${s.role==="user"?"bg-primary text-primary-foreground":"bg-muted"}`,children:s.content})},a)),C.isPending&&e.jsx("div",{className:"flex justify-start mb-3",children:e.jsx("div",{className:"bg-muted rounded-lg px-3 py-2",children:e.jsx(W,{className:"h-4 w-4 animate-spin text-muted-foreground"})})}),e.jsx("div",{ref:d})]}),e.jsxs("div",{className:"border-t p-2 flex gap-2",children:[e.jsx(je,{placeholder:"Ask about the lesson...",value:h,onChange:s=>P(s.target.value),onKeyDown:s=>s.key==="Enter"&&!s.shiftKey&&Y(),className:"h-8 text-sm","data-testid":"input-tutor-chat"}),e.jsx(c,{size:"sm",className:"h-8 w-8 p-0 shrink-0",onClick:Y,disabled:C.isPending,children:e.jsx(ce,{className:"h-3 w-3"})})]})]}):e.jsx(c,{size:"sm",className:"rounded-full h-12 w-12 shadow-lg p-0",onClick:()=>x(!0),"data-testid":"button-open-tutor",children:e.jsx(me,{className:"h-5 w-5"})})})]})}function Oe(){const{user:i,isLoading:ne}=Pe(),{toast:K}
1=pe(),[H,y]=o.useState(null),[q,b]=o.useState(!1),[u,M]=o.useState(""),{data:I,isLoading:U}=te({queryKey:["/api/www/my-enrollment"],queryFn:()=>fetch("/api/www/my-enrollment",{credentials:"include"}).then(t=>t.json()),enabled:!!i}),w=f({mutationFn:()=>v("POST","/api/www/whatsapp/opt-in",{phoneNumber:u}).then(t=>t.json()),onSuccess:()=>{K({title:"WhatsApp enabled!",description:"You'll receive micro-lessons and quiz nudges on WhatsApp."}),A.invalidateQueries({queryKey:["/api/www/my-enrollment"]}),b(!1)}}),E=f({mutationFn:()=>v("POST","/api/www/whatsapp/opt-out").then(t=>t.json()),onSuccess:()=>{K({title:"WhatsApp disabled",description:"You've opted out of WhatsApp delivery."}),A.invalidateQueries({queryKey:["/api/www/my-enrollment"]})}});if(ne||U)return e.jsxs("div",{className:"container max-w-5xl py-10 space-y-4",children:[e.jsx(O,{className:"h-10 w-64"}),e.jsx(O,{className:"h-4 w-48"}),e.jsxs("div",{className:"grid grid-cols-12 gap-6 mt-6",children:[e.jsx("div",{className:"col-span-3 space-y-2",children:[1,2,3,4].map(t=>e.jsx(O,{className:"h-10"},t))}),e.jsx("div",{className:"col-span-9 space-y-4",children:[1,2,3].map(t=>e.jsx(O,{className:"h-32"},t))})]})]});if(!i)return e.jsxs("div",{className:"container max-w-2xl py-20 text-center",children:[e.jsx(ie,{className:"h-12 w-12 mx-auto mb-4 text-muted-foreground"}),e.jsx("h2",{className:"text-xl font-bold mb-2",children:"Sign in required"}),e.jsx("p",{className:"text-muted-foreground mb-4",children:"Please sign in to access your course."}),e.jsx(X,{href:"/",children:e.jsx(c,{children:"Go to homepage"})})]});if(!I)return e.jsxs("div",{className:"container max-w-2xl py-20 text-center",children:[e.jsx(ae,{className:"h-12 w-12 mx-auto mb-4 text-muted-foreground opacity-50"}),e.jsx("h2",{className:"text-xl font-bold mb-2",children:"No active enrolment"}),e.jsx("p",{className:"text-muted-foreground mb-4",children:"You're not currently enrolled in a WWW course cohort. Contact your facilitator to be added to a cohort."}),e.jsx(X,{href:"/passport",children:e.jsx(c,{variant:"outline",children:"Back to Passport"})})]});const{enrollment:V,cohort:Q,versionId:R,courseTree:x,progress:h,whatsapp:P}=I,k=(R?x?.versions?.find(t=>t.id===R)??x?.versions?.[0]:x?.versions?.[0])?.modules??[],d=k.slice().sort((t,n)=>t.order-n.order).flatMap(t=>t.lessons.slice().sort((n,s)=>n.order-s.order)),p=d.length,B=h.filter(t=>t.status==="completed").length,g=p>0?Math.round(B/p*100):0,D=new Set(h.filter(t=>t.status==="completed").map(t=>t.lessonId)),L=t=>{const n=d.findIndex(s=>s.id===t);return n<=0?!0:d.slice(0,n).every(s=>D.has(s.id))},G=d.find(t=>L(t.id)&&!D.has(t.id))??d[0],m=H??G?.id??null,N=d.find(t=>t.id===m)??null,T=t=>h.find(n=>n.lessonId===t)?.status??"not_started",C=()=>{if(!m)return;const t=d.findIndex(s=>s.id===m),n=d[t+1];n&&L(n.id)&&y(n.id)},Y=()=>{if(!m)return;const t=d.findIndex(n=>n.id===m);t>0&&y(d[t-1].id)},S=d.findIndex(t=>t.id===m);return e.jsxs("div",{className:"container max-w-6xl py-6",children:[e.jsxs("div",{className:"mb-6",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground mb-1",children:[e.jsx(X,{href:"/passport",className:"hover:underline",children:"Passport"}),e.jsx(de,{className:"h-3 w-3"}),e.jsx("span",{children:Q.name})]}),e.jsx("h1",{className:"text-2xl font-bold",children:x?.course.title??Q.name}),x?.course.description&&e.jsx("p",{className:"text-muted-foreground text-sm mt-1",children:x.course.description}),e.jsxs("div",{className:"mt-4 flex items-center gap-4",children:[e.jsxs("div",{className:"flex-1 max-w-xs",children:[e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground mb-1",children:[e.jsx("span",{children:"Progress"}),e.jsxs("span",{children:[B,"/",p," lessons"]})]}),e.jsx(ze,{value:g,className:"h-2"})]}),e.jsx(_,{variant:g===100?"default":"secondary",className:"gap-1",children:g===100?e.jsxs(e.Fragment,{children:[e.jsx(fe,{className:"h-3 w-3"})," Complete"]}):`${g}%`}),P?.status==="active"&&P.optedInAt?e.jsxs(c,{variant:"outline",size:"sm",className:"gap-1 text-xs",onClick:()=>E.mutate(),disabled:E.isPending,"data-testid":"button-whatsapp-optout",children:[e.jsx(oe,{className:"h-3.5 w-3.5"}),"WhatsApp On"]}):e.jsxs(c,{variant:"outline",size:"sm",className:"gap-1 text-xs",onClick:()=>b(!0),"data-testid":"button-whatsapp-optin",children:[e.jsx(oe,{className:"h-3.5 w-3.5"}),"WhatsApp Delivery"]})]}),q&&e.jsxs("div",{className:"mt-3 rounded-lg border p-4 max-w-sm",children:[e.jsx("p",{className:"text-sm font-medium mb-2",children:"Enable WhatsApp delivery"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-3",children:"Receive micro-lessons, nudges, and quiz questions on WhatsApp. We'll use your number to send only course content."}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(je,{placeholder:"+27 xx xxx xxxx",value:u,onChange:t=>M(t.target.value),className:"h-8 text-sm","data-testid":"input-whatsapp-phone"}),e.jsx(c,{size:"sm",className:"h-8",onClick:()=>w.mutate(),disabled:w.isPending||!u.trim()&&!I?.whatsapp?.phoneNumber,"data-testid":"button-confirm-whatsapp",children:w.isPending?e.jsx(W,{className:"h-3 w-3 animate-spin"}):"Enable"}),e.jsx(c,{size:"sm",variant:"ghost",className:"h-8",onClick:()=>b(!1),children:e.jsx(xe,{className:"h-4 w-4"})})]})]})]}),p===0?e.jsxs("div",{className:"rounded-lg border border-dashed p-12 text-center",children:[e.jsx(ve,{className:"h-8 w-8 mx-auto mb-3 text-muted-foreground opacity-50"}),e.jsx("p",{className:"text-muted-foreground",children:"This course doesn't have any lessons yet. Check back soon."})]}):e.jsxs("div",{className:"grid grid-cols-12 gap-6",children:[e.jsx("div",{className:"col-span-12 md:col-span-3",children:e.jsx(be,{className:"h-[calc(100vh-220px)]",children:e.jsx("div",{className:"space-y-4 pr-2",children:k.map(t=>e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-1.5 px-1",children:t.title}),e.jsx("div",{className:"space-y-0.5",children:t.lessons.slice().sort((n,s)=>n.order-s.order).map(n=>{const s=T(n.id),a=n.id===m,r=L(n.id);return e.jsxs("button",{onClick:()=>{r&&y(n.id)},disabled:!r,title:r?void 0:"Complete the previous lesson to unlock this one",className:`w-full flex items-center gap-2 text-left px-2.5 py-2 rounded-md text-sm transition-colors ${r?a?"bg-primary/10 text-primary font-medium":"hover:bg-muted/60 text-muted-foreground":"opacity-50 cursor-not-allowed text-muted-foreground"}`,"data-testid":`button-lesson-${n.id}`,children:[e.jsx("span",{className:"shrink-0",children:r?s==="completed"?e.jsx(re,{className:"h-4 w-4 text-emerald-500"}):s==="in_progress"?e.jsx(he,{className:"h-4 w-4 text-primary"}
1):e.jsx("div",{className:"h-4 w-4 rounded-full border-2 border-muted-foreground/40"}):e.jsx(ie,{className:"h-4 w-4 text-muted-foreground/50"})}),e.jsx("span",{className:"truncate",children:n.title})]},n.id)})})]},t.id))})})}),e.jsx("div",{className:"col-span-12 md:col-span-9",children:N?e.jsxs("div",{className:"space-y-4",children:[e.jsx(Fe,{lesson:N,enrollment:V,progress:h,onComplete:C},N.id),e.jsxs("div",{className:"flex justify-between pt-2",children:[e.jsxs(c,{variant:"outline",size:"sm",onClick:Y,disabled:S<=0,className:"gap-1","data-testid":"button-prev-lesson",children:[e.jsx(ye,{className:"h-4 w-4"})," Previous"]}),e.jsxs("span",{className:"text-xs text-muted-foreground self-center",children:[S+1," / ",p]}),e.jsxs(c,{variant:"outline",size:"sm",onClick:C,disabled:S>=p-1,className:"gap-1","data-testid":"button-next-lesson",children:["Next ",e.jsx(de,{className:"h-4 w-4"})]})]})]}):e.jsxs("div",{className:"rounded-lg border border-dashed p-12 text-center",children:[e.jsx(ae,{className:"h-8 w-8 mx-auto mb-3 text-muted-foreground opacity-40"}),e.jsx("p",{className:"text-muted-foreground",children:"Select a lesson from the sidebar to begin."})]})})]})]})}export{Oe 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.