diff --git a/README.md b/README.md index 893237f..9b85199 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ All data stays in your own Firebase project. - View poll history and attendance, grouped by poll set and session - CSV export of poll results (per-poll and per-session) - Delete individual polls from history -- Password-protected teacher and history access +- Password-protected instructor and history access ### For students - Join with just a name — no account needed @@ -137,7 +137,7 @@ Copy the example file and fill in your values: cp .env.example .env.local ``` -Edit `.env.local` with your Firebase config values and a teacher password of your choice: +Edit `.env.local` with your Firebase config values and an instructor password of your choice: ``` VITE_FIREBASE_API_KEY=your_api_key @@ -148,7 +148,7 @@ VITE_FIREBASE_STORAGE_BUCKET=your_project.firebasestorage.app VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id VITE_FIREBASE_APP_ID=your_app_id -VITE_TEACHER_PASSWORD=your_password_here +VITE_INSTRUCTOR_PASSWORD=your_password_here ``` **Never commit `.env.local` to git.** It is already listed in `.gitignore`. @@ -166,7 +166,7 @@ npm run dev ``` Open [http://localhost:5173/classroom-polling/](http://localhost:5173/classroom-polling/). -Open two browser tabs — one as teacher, one as student — to verify everything works. +Open two browser tabs — one as instructor, one as student — to verify everything works. ### Step 9 — Set your repo name in vite.config.js @@ -223,7 +223,7 @@ git merge upstream/main ### Running a poll -1. Open the app → **I'm the Teacher** → enter your password +1. Open the app → **I'm the Instructor** → enter your password 2. Click **New Poll** → enter question and options → click **Start Poll** 3. Share your app URL with students — they click **I'm a Student**, enter their name, and wait 4. Students see the poll instantly; results update live on your dashboard @@ -239,7 +239,7 @@ git merge upstream/main ### Viewing history and attendance -1. Click **History** → enter teacher password +1. Click **History** → enter instructor password 2. **Polls tab**: past polls grouped by set, expandable with per-option results 3. **Attendance tab**: students who joined, grouped by date @@ -247,7 +247,7 @@ git merge upstream/main | File | What to change | |------|---------------| -| `.env.local` | Teacher password, Firebase config | +| `.env.local` | Instructor password, Firebase config | | `firebase-rules.json` | Database security rules | | `vite.config.js` | Repository name for GitHub Pages base path | | `src/index.css` | Colors, fonts, visual design | @@ -264,7 +264,7 @@ classroom-polling/ │ │ └── csvExport.js CSV export utilities │ ├── pages/ │ │ ├── RoleSelector.jsx Landing page -│ │ ├── TeacherPage.jsx Teacher dashboard +│ │ ├── InstructorPage.jsx Instructor dashboard │ │ ├── StudentPage.jsx Student poll experience │ │ ├── PollHistory.jsx History and attendance │ │ ├── PollSets.jsx Poll set list and creation @@ -290,7 +290,7 @@ The Firebase Spark (free) plan is sufficient for typical classroom use: ## Known limitations -- Teacher password is a single shared secret; not suitable for multiple instructors sharing one instance +- Instructor password is a single shared secret; not suitable for multiple instructors sharing one instance - Code formatting in questions is plain text only (markdown support planned) - Student names are self-reported and not authenticated diff --git a/dist/assets/index-BEzP6REc.js b/dist/assets/index-CLC7Q4lX.js similarity index 89% rename from dist/assets/index-BEzP6REc.js rename to dist/assets/index-CLC7Q4lX.js index 320c850..85584bc 100644 --- a/dist/assets/index-BEzP6REc.js +++ b/dist/assets/index-CLC7Q4lX.js @@ -64,7 +64,7 @@ Error generating stack: `+s.message+` * LICENSE.md file in the root directory of this source tree. * * @license MIT - */const uC="6";try{window.__reactRouterVersion=uC}catch{}const cC="startTransition",bf=i0[cC];function dC(t){let{basename:e,children:n,future:r,window:i}=t,s=C.useRef();s.current==null&&(s.current=gS({window:i,v5Compat:!0}));let o=s.current,[l,a]=C.useState({action:o.action,location:o.location}),{v7_startTransition:u}=r||{},h=C.useCallback(d=>{u&&bf?bf(()=>a(d)):a(d)},[a,u]);return C.useLayoutEffect(()=>o.listen(h),[o,h]),C.useEffect(()=>sC(r),[r]),C.createElement(lC,{basename:e,children:n,location:l.location,navigationType:l.action,navigator:o,future:r})}var Pf;(function(t){t.UseScrollRestoration="useScrollRestoration",t.UseSubmit="useSubmit",t.UseSubmitFetcher="useSubmitFetcher",t.UseFetcher="useFetcher",t.useViewTransitionState="useViewTransitionState"})(Pf||(Pf={}));var Nf;(function(t){t.UseFetcher="useFetcher",t.UseFetchers="useFetchers",t.UseScrollRestoration="useScrollRestoration"})(Nf||(Nf={}));const hC="prof123";function fC(){const t=Sr(),[e,n]=C.useState(!1),[r,i]=C.useState(""),[s,o]=C.useState("");function l(a){a.preventDefault(),r===hC?(localStorage.setItem("role","teacher"),t("/teacher")):(o("Incorrect password."),i(""))}return c.jsxs("div",{style:Se.page,children:[c.jsxs("div",{style:Se.header,children:[c.jsx("div",{style:Se.logoMark,children:"●"}),c.jsx("span",{style:Se.logoText,children:"ClassPoll"})]}),c.jsxs("div",{style:Se.hero,className:"fade-up",children:[c.jsxs("h1",{style:Se.title,children:["Live Classroom",c.jsx("br",{}),"Polling"]}),c.jsx("p",{style:Se.sub,children:"Real-time polls, instant results, zero setup for students."})]}),c.jsxs("div",{style:Se.cards,className:"fade-up",children:[c.jsxs("button",{style:Se.roleCard,onClick:()=>t("/student"),children:[c.jsx("span",{style:Se.roleIcon,children:"🎓"}),c.jsx("span",{style:Se.roleLabel,children:"I'm a Student"}),c.jsx("span",{style:Se.roleHint,children:"Join and answer polls"})]}),e?c.jsxs("form",{style:{...Se.roleCard,gap:"0.75rem"},onSubmit:l,children:[c.jsx("span",{style:Se.roleIcon,children:"🔑"}),c.jsx("span",{style:Se.roleLabel,children:"Teacher Password"}),c.jsx("input",{className:"input",type:"password",placeholder:"Enter password",value:r,onChange:a=>{i(a.target.value),o("")},autoFocus:!0,style:{textAlign:"center"}}),s&&c.jsx("span",{style:Se.err,children:s}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{width:"100%",justifyContent:"center"},children:"Enter"}),c.jsx("button",{type:"button",className:"btn btn-secondary",style:{width:"100%",justifyContent:"center",fontSize:"0.85rem"},onClick:()=>{n(!1),o(""),i("")},children:"Cancel"})]}):c.jsxs("button",{style:Se.roleCard,onClick:()=>n(!0),children:[c.jsx("span",{style:Se.roleIcon,children:"📋"}),c.jsx("span",{style:Se.roleLabel,children:"I'm the Teacher"}),c.jsx("span",{style:Se.roleHint,children:"Create and manage polls"})]})]}),c.jsx("a",{href:"/classroom-polling/history",style:Se.historyLink,children:"View Poll History →"})]})}const Se={page:{minHeight:"100vh",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"2rem 1rem",gap:"2rem",background:"var(--paper)"},header:{position:"fixed",top:0,left:0,right:0,padding:"1rem 2rem",display:"flex",alignItems:"center",gap:"0.5rem",borderBottom:"1px solid var(--border)",background:"var(--paper)"},logoMark:{color:"var(--accent)",fontSize:"1.2rem"},logoText:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem"},hero:{textAlign:"center"},title:{fontSize:"clamp(2.2rem, 6vw, 3.5rem)",lineHeight:1.1,marginBottom:"0.75rem"},sub:{color:"var(--muted)",fontSize:"1.05rem",maxWidth:"30ch",margin:"0 auto"},cards:{display:"flex",gap:"1.25rem",flexWrap:"wrap",justifyContent:"center"},roleCard:{display:"flex",flexDirection:"column",alignItems:"center",gap:"0.5rem",padding:"2rem 2.5rem",borderRadius:"16px",border:"2px solid var(--border)",cursor:"pointer",transition:"all 0.2s",background:"white",minWidth:"200px",boxShadow:"var(--shadow)"},roleIcon:{fontSize:"2.5rem"},roleLabel:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.15rem"},roleHint:{fontSize:"0.82rem",color:"var(--muted)"},err:{color:"var(--accent)",fontSize:"0.85rem"},historyLink:{color:"var(--muted)",fontSize:"0.85rem",textDecoration:"underline",cursor:"pointer"}},pC="modulepreload",mC=function(t){return"/classroom-polling/"+t},Rf={},gC=function(e,n,r){let i=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));i=Promise.allSettled(n.map(a=>{if(a=mC(a),a in Rf)return;Rf[a]=!0;const u=a.endsWith(".css"),h=u?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${h}`))return;const d=document.createElement("link");if(d.rel=u?"stylesheet":pC,u||(d.as="script"),d.crossOrigin="",d.href=a,l&&d.setAttribute("nonce",l),document.head.appendChild(d),u)return new Promise((f,v)=>{d.addEventListener("load",f),d.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${a}`)))})}))}function s(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return i.then(o=>{for(const l of o||[])l.status==="rejected"&&s(l.reason);return e().catch(s)})};var Af={};/** + */const uC="6";try{window.__reactRouterVersion=uC}catch{}const cC="startTransition",bf=i0[cC];function dC(t){let{basename:e,children:n,future:r,window:i}=t,s=C.useRef();s.current==null&&(s.current=gS({window:i,v5Compat:!0}));let o=s.current,[l,a]=C.useState({action:o.action,location:o.location}),{v7_startTransition:u}=r||{},h=C.useCallback(d=>{u&&bf?bf(()=>a(d)):a(d)},[a,u]);return C.useLayoutEffect(()=>o.listen(h),[o,h]),C.useEffect(()=>sC(r),[r]),C.createElement(lC,{basename:e,children:n,location:l.location,navigationType:l.action,navigator:o,future:r})}var Pf;(function(t){t.UseScrollRestoration="useScrollRestoration",t.UseSubmit="useSubmit",t.UseSubmitFetcher="useSubmitFetcher",t.UseFetcher="useFetcher",t.useViewTransitionState="useViewTransitionState"})(Pf||(Pf={}));var Nf;(function(t){t.UseFetcher="useFetcher",t.UseFetchers="useFetchers",t.UseScrollRestoration="useScrollRestoration"})(Nf||(Nf={}));const hC="prof123";function fC(){const t=Sr(),[e,n]=C.useState(!1),[r,i]=C.useState(""),[s,o]=C.useState("");function l(a){a.preventDefault(),r===hC?(localStorage.setItem("role","instructor"),t("/instructor")):(o("Incorrect password."),i(""))}return c.jsxs("div",{style:Se.page,children:[c.jsxs("div",{style:Se.header,children:[c.jsx("div",{style:Se.logoMark,children:"●"}),c.jsx("span",{style:Se.logoText,children:"ClassPoll"})]}),c.jsxs("div",{style:Se.hero,className:"fade-up",children:[c.jsxs("h1",{style:Se.title,children:["Live Classroom",c.jsx("br",{}),"Polling"]}),c.jsx("p",{style:Se.sub,children:"Real-time polls, instant results, zero setup for students."})]}),c.jsxs("div",{style:Se.cards,className:"fade-up",children:[c.jsxs("button",{style:Se.roleCard,onClick:()=>t("/student"),children:[c.jsx("span",{style:Se.roleIcon,children:"🎓"}),c.jsx("span",{style:Se.roleLabel,children:"I'm a Student"}),c.jsx("span",{style:Se.roleHint,children:"Join and answer polls"})]}),e?c.jsxs("form",{style:{...Se.roleCard,gap:"0.75rem"},onSubmit:l,children:[c.jsx("span",{style:Se.roleIcon,children:"🔑"}),c.jsx("span",{style:Se.roleLabel,children:"Instructor Password"}),c.jsx("input",{className:"input",type:"password",placeholder:"Enter password",value:r,onChange:a=>{i(a.target.value),o("")},autoFocus:!0,style:{textAlign:"center"}}),s&&c.jsx("span",{style:Se.err,children:s}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{width:"100%",justifyContent:"center"},children:"Enter"}),c.jsx("button",{type:"button",className:"btn btn-secondary",style:{width:"100%",justifyContent:"center",fontSize:"0.85rem"},onClick:()=>{n(!1),o(""),i("")},children:"Cancel"})]}):c.jsxs("button",{style:Se.roleCard,onClick:()=>n(!0),children:[c.jsx("span",{style:Se.roleIcon,children:"📋"}),c.jsx("span",{style:Se.roleLabel,children:"I'm the Instructor"}),c.jsx("span",{style:Se.roleHint,children:"Create and manage polls"})]})]}),c.jsx("a",{href:"/classroom-polling/history",style:Se.historyLink,children:"View Poll History →"})]})}const Se={page:{minHeight:"100vh",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"2rem 1rem",gap:"2rem",background:"var(--paper)"},header:{position:"fixed",top:0,left:0,right:0,padding:"1rem 2rem",display:"flex",alignItems:"center",gap:"0.5rem",borderBottom:"1px solid var(--border)",background:"var(--paper)"},logoMark:{color:"var(--accent)",fontSize:"1.2rem"},logoText:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem"},hero:{textAlign:"center"},title:{fontSize:"clamp(2.2rem, 6vw, 3.5rem)",lineHeight:1.1,marginBottom:"0.75rem"},sub:{color:"var(--muted)",fontSize:"1.05rem",maxWidth:"30ch",margin:"0 auto"},cards:{display:"flex",gap:"1.25rem",flexWrap:"wrap",justifyContent:"center"},roleCard:{display:"flex",flexDirection:"column",alignItems:"center",gap:"0.5rem",padding:"2rem 2.5rem",borderRadius:"16px",border:"2px solid var(--border)",cursor:"pointer",transition:"all 0.2s",background:"white",minWidth:"200px",boxShadow:"var(--shadow)"},roleIcon:{fontSize:"2.5rem"},roleLabel:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.15rem"},roleHint:{fontSize:"0.82rem",color:"var(--muted)"},err:{color:"var(--accent)",fontSize:"0.85rem"},historyLink:{color:"var(--muted)",fontSize:"0.85rem",textDecoration:"underline",cursor:"pointer"}},pC="modulepreload",mC=function(t){return"/classroom-polling/"+t},Rf={},gC=function(e,n,r){let i=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));i=Promise.allSettled(n.map(a=>{if(a=mC(a),a in Rf)return;Rf[a]=!0;const u=a.endsWith(".css"),h=u?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${h}`))return;const d=document.createElement("link");if(d.rel=u?"stylesheet":pC,u||(d.as="script"),d.crossOrigin="",d.href=a,l&&d.setAttribute("nonce",l),document.head.appendChild(d),u)return new Promise((f,v)=>{d.addEventListener("load",f),d.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${a}`)))})}))}function s(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return i.then(o=>{for(const l of o||[])l.status==="rejected"&&s(l.reason);return e().catch(s)})};var Af={};/** * @license * Copyright 2017 Google LLC * @@ -2722,13 +2722,13 @@ FIREBASE: `))}restoreState_(){this.tryAuth(),this.tryAppCheck();for(const e of t * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */const sb=5*60,ob=kv("authIdTokenMaxAge")||sb;let Fp=null;const lb=t=>async e=>{const n=e&&await e.getIdTokenResult(),r=n&&(new Date().getTime()-Date.parse(n.issuedAtTime))/1e3;if(r&&r>ob)return;const i=n==null?void 0:n.token;Fp!==i&&(Fp=i,await fetch(t,{method:i?"POST":"DELETE",headers:i?{Authorization:`Bearer ${i}`}:{}}))};function ab(t=Av()){const e=Ed(t,"auth");if(e.isInitialized())return e.getImmediate();const n=UT(t,{popupRedirectResolver:tb,persistence:[h1,e1,__]}),r=kv("authTokenSyncURL");if(r&&typeof isSecureContext=="boolean"&&isSecureContext){const s=new URL(r,location.origin);if(location.origin===s.origin){const o=lb(s.toString());JT(n,o,()=>o(n.currentUser)),YT(n,l=>o(l))}}const i=xv("auth");return i&&BT(n,`http://${i}`),n}function ub(){var t,e;return(e=(t=document.getElementsByTagName("head"))===null||t===void 0?void 0:t[0])!==null&&e!==void 0?e:document}LT({loadJS(t){return new Promise((e,n)=>{const r=document.createElement("script");r.setAttribute("src",t),r.onload=e,r.onerror=i=>{const s=Ut("internal-error");s.customData=i,n(s)},r.type="text/javascript",r.charset="UTF-8",ub().appendChild(r)})},gapiScript:"https://apis.google.com/js/api.js",recaptchaV2Script:"https://www.google.com/recaptcha/api.js",recaptchaEnterpriseScript:"https://www.google.com/recaptcha/enterprise.js?render="});ib("Browser");const cb={apiKey:"AIzaSyBiZSV4Z_3-L0z8RP5yY_2xXlw5fKOy2jc",authDomain:"classroom-polling-dd344.firebaseapp.com",databaseURL:"https://classroom-polling-dd344-default-rtdb.firebaseio.com",projectId:"classroom-polling-dd344",storageBucket:"classroom-polling-dd344.firebasestorage.app",messagingSenderId:"528103899828",appId:"1:528103899828:web:f74274640de611a61d0de1"},k_=Rv(cb),re=aT(k_),db=ab(k_);GT(db).catch(console.error);function T_(t){const e=new Date().toLocaleDateString("en-CA");return on(ne(re,`session/students/${t}`),{joinedAt:Sp(),date:e}),on(ne(re,`sessionStudents/${e}_${t}`),{name:t,date:e,joinedAt:Sp()})}function vc(t){return vr(ne(re,`session/students/${t}`))}function b_(t,e,n){return sa(ne(re,"session/activePoll/responses"),{[t]:n})}function Pl({question:t,options:e,correctIndex:n,duration:r,resultPolicy:i,correctPolicy:s}){const o=`poll_${Date.now()}`;return on(ne(re,"session/activePoll"),{id:o,question:t,options:e,correctIndex:n??null,duration:r,resultPolicy:i,correctPolicy:s,startedAt:Date.now(),responses:{},ended:!1,revealResults:!1,revealCorrect:!1})}async function Do(t,e){const[n,r]=await Promise.all([Ns(ne(re,"session/activePoll")),Ns(ne(re,"session/queue"))]),i=n.val(),s=r.val();if(!i)return;const o={...i,revealResults:t,revealCorrect:e,endedAt:Date.now()};return s&&(o.setId=s.setId,o.setName=s.setName,o.setPosition=s.currentIndex,o.sessionKey=s.sessionKey),await on(ne(re,`pollHistory/${i.id}`),o),vr(ne(re,"session/activePoll"))}function P_(){return sa(ne(re,"session/activePoll"),{ended:!0})}function yc(t,e){return sa(ne(re,"session/activePoll"),{revealResults:t,revealCorrect:e})}function dh(t){const e=ne(re,"session/activePoll");return xr(e,n=>t(n.val()))}function N_(t){const e=ne(re,"session/students");return xr(e,n=>{const r=n.val()||{};t(Object.keys(r).map(i=>({name:i,...r[i]})))})}function R_(t){const e=ne(re,"pollHistory");return xr(e,n=>{const r=n.val()||{},i=Object.values(r).sort((s,o)=>(o.startedAt||0)-(s.startedAt||0));t(i)})}function A_(t){const e=ne(re,"pollSets");return xr(e,n=>{const r=n.val()||{},i=Object.entries(r).map(([s,o])=>({id:s,...o})).sort((s,o)=>(o.createdAt||0)-(s.createdAt||0));t(i)})}async function _c({name:t,defaults:e,polls:n}){const r=`set_${Date.now()}`;return await on(ne(re,`pollSets/${r}`),{id:r,name:t,createdAt:Date.now(),defaults:e,polls:n||[]}),r}function Lo(t,e){return Ns(ne(re,`pollSets/${t}`)).then(n=>{const r=n.val()||{};return on(ne(re,`pollSets/${t}`),{...r,...e})})}function O_(t){return vr(ne(re,`pollSets/${t}`))}function D_(t,e){const n=ne(re,`pollSets/${t}`);return xr(n,r=>e(r.val()))}function L_(t,e,n){const r=`run_${Date.now()}`;return on(ne(re,"session/queue"),{setId:t,setName:e,currentIndex:0,totalPolls:n,sessionKey:r})}function M_(t){return sa(ne(re,"session/queue"),{currentIndex:t})}function wc(){return vr(ne(re,"session/queue"))}function j_(t){const e=ne(re,"session/queue");return xr(e,n=>t(n.val()))}async function F_(t,e){const r=(await Ns(ne(re,"session/activePoll"))).val(),s=(await Ns(ne(re,"session/queue"))).val();if(!r)return;const o={...r,revealResults:t,revealCorrect:e,endedAt:Date.now()};return s&&(o.setId=s.setId,o.setName=s.setName,o.setPosition=s.currentIndex,o.sessionKey=s.sessionKey),await on(ne(re,`pollHistory/${r.id}`),o),vr(ne(re,"session/activePoll"))}const hb=Object.freeze(Object.defineProperty({__proto__:null,advanceQueue:M_,clearQueue:wc,closePoll:F_,createPollSet:_c,deletePollSet:O_,endPoll:Do,expirePoll:P_,joinSession:T_,launchSet:L_,leaveSession:vc,revealPollResults:yc,startPoll:Pl,submitAnswer:b_,updatePollSet:Lo,watchActivePoll:dh,watchPollHistory:R_,watchPollSet:D_,watchPollSets:A_,watchQueue:j_,watchStudents:N_},Symbol.toStringTag,{value:"Module"})),Up=60,fb=[{value:"on_submit",label:"After they submit"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}],pb=[{value:"with_results",label:"With results"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}];function mb(){var Ge;const t=Sr(),[e,n]=C.useState([]),[r,i]=C.useState(null),[s,o]=C.useState(0),[l,a]=C.useState("dashboard"),[u,h]=C.useState(null),[d,f]=C.useState(null),v=C.useRef(null),w=C.useRef(null),_=C.useRef(null),[E,g]=C.useState(""),[p,m]=C.useState(["",""]),[S,I]=C.useState(null),[P,b]=C.useState(Up),[A,q]=C.useState("on_submit"),[z,pe]=C.useState("with_results");C.useEffect(()=>{localStorage.getItem("role")!=="teacher"&&t("/")},[]),C.useEffect(()=>{const L=dh(xe=>{xe&&(_.current=xe),i(xe),xe&&!xe.ended&&o(Math.max(0,Math.round(xe.duration-(Date.now()-xe.startedAt)/1e3)))}),te=N_(n),Te=j_(xe=>{h(xe),xe!=null&&xe.setId?(w.current&&w.current(),gC(async()=>{const{watchPollSet:Ir}=await Promise.resolve().then(()=>hb);return{watchPollSet:Ir}},void 0).then(({watchPollSet:Ir})=>{w.current=Ir(xe.setId,f)})):(f(null),_.current=null,w.current&&(w.current(),w.current=null))});return()=>{L(),te(),Te()}},[]),C.useEffect(()=>(clearInterval(v.current),r&&!r.ended&&(v.current=setInterval(()=>{const L=Math.max(0,Math.round(r.duration-(Date.now()-r.startedAt)/1e3));o(L),L===0&&(clearInterval(v.current),P_())},500)),()=>clearInterval(v.current)),[r==null?void 0:r.id,r==null?void 0:r.ended]);function D(){p.length<6&&m([...p,""])}function Y(L,te){m(p.map((Te,xe)=>xe===L?te:Te))}function X(L){if(p.length<=2)return;const te=p.filter((Te,xe)=>xe!==L);m(te),S===L?I(null):S>L&&I(S-1)}function et(L){L.preventDefault();const te=p.filter(Te=>Te.trim());!E.trim()||te.length<2||(Pl({question:E.trim(),options:te,correctIndex:S,duration:P,resultPolicy:A,correctPolicy:z}),g(""),m(["",""]),I(null),b(Up),q("on_submit"),pe("with_results"),a("dashboard"))}async function Ee(){if(!u||!d)return;const L=u.currentIndex+1;if(r&&await Do(r.revealResults||!1,r.revealCorrect||!1),L>=u.totalPolls){await wc();return}await M_(L);const te=d.defaults||{},Te=(d.polls||[])[L];Te&&await Pl({question:Te.question,options:Te.options,correctIndex:Te.correctIndex??null,duration:Te.duration??te.duration??60,resultPolicy:Te.resultPolicy??te.resultPolicy??"on_submit",correctPolicy:Te.correctPolicy??te.correctPolicy??"with_results"})}async function Be(){r&&await Do(r.revealResults||!1,r.revealCorrect||!1),await wc()}const R=r?Object.keys(r.responses||{}).length:Object.keys(((Ge=_.current)==null?void 0:Ge.responses)||{}).length,U=r==null?void 0:r.ended,y=!!u,x=u&&u.currentIndex>=u.totalPolls-1,T=r||(y?_.current:null),O=!r&&T;function K(L){return L.revealResults?!0:!(L.resultPolicy==="never"||L.resultPolicy==="manual")}function tt(L){return L.revealCorrect?!0:L.correctPolicy==="never"||L.correctPolicy==="manual"?!1:!!(L.correctPolicy==="with_results"&&K(L))}return c.jsxs("div",{style:j.page,children:[c.jsxs("aside",{style:j.sidebar,children:[c.jsxs("div",{style:j.logo,children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsxs("nav",{style:j.nav,children:[c.jsx("button",{style:{...j.navBtn,...l==="dashboard"?j.navActive:{}},onClick:()=>a("dashboard"),children:"📊 Dashboard"}),c.jsx("button",{style:{...j.navBtn,...l==="create"?j.navActive:{},...r?j.navDisabled:{}},onClick:()=>!r&&a("create"),disabled:!!r,children:"➕ New Poll"}),c.jsx("button",{style:j.navBtn,onClick:()=>t("/pollsets"),children:"📚 Poll Sets"}),c.jsx("button",{style:j.navBtn,onClick:()=>t("/history"),children:"🕐 History"})]}),c.jsxs("div",{style:j.sidebarBottom,children:[c.jsxs("div",{style:j.studentCount,children:[c.jsx("span",{style:j.dot}),c.jsx("strong",{children:e.length})," student",e.length!==1?"s":""," online"]}),c.jsx("div",{style:j.studentList,children:e.map(L=>c.jsx("div",{style:j.studentChip,children:L.name},L.name))}),c.jsx("button",{className:"btn btn-secondary",style:{width:"100%",marginTop:"auto",fontSize:"0.8rem"},onClick:()=>{localStorage.removeItem("role"),localStorage.removeItem("historyAuth"),t("/")},children:"Exit"})]})]}),c.jsxs("main",{style:j.main,children:[l==="create"&&c.jsxs("div",{style:j.content,className:"fade-up",children:[c.jsx("h2",{style:j.pageTitle,children:"Create a Poll"}),c.jsxs("form",{onSubmit:et,style:j.form,children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Question"}),c.jsx("textarea",{className:"input",rows:2,placeholder:"e.g. Which process converts sunlight into energy?",value:E,onChange:L=>g(L.target.value),style:{resize:"vertical",width:"100%"},required:!0})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Answer Options"}),c.jsx("p",{style:j.hint,children:"Click a letter circle to mark the correct answer (optional)"}),c.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:p.map((L,te)=>c.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[c.jsx("button",{type:"button",style:{...j.correctBtn,...S===te?j.correctBtnActive:{}},onClick:()=>I(S===te?null:te),children:S===te?"✓":String.fromCharCode(65+te)}),c.jsx("input",{className:"input",style:{flex:1},placeholder:`Option ${String.fromCharCode(65+te)}`,value:L,onChange:Te=>Y(te,Te.target.value),required:!0}),c.jsx("button",{type:"button",style:j.removeBtn,onClick:()=>X(te),disabled:p.length<=2,children:"✕"})]},te))}),p.length<6&&c.jsx("button",{type:"button",className:"btn btn-ghost",style:{marginTop:"0.5rem",fontSize:"0.85rem"},onClick:D,children:"+ Add option"})]}),c.jsxs("div",{style:j.policySection,children:[c.jsx("label",{className:"label",children:"Show results to students"}),c.jsx("div",{style:j.policyRow,children:fb.map(L=>c.jsx("button",{type:"button",style:{...j.policyBtn,...A===L.value?j.policyBtnActive:{}},onClick:()=>q(L.value),children:c.jsx("span",{style:j.policyLabel,children:L.label})},L.value))})]}),S!=null&&c.jsxs("div",{style:j.policySection,children:[c.jsx("label",{className:"label",children:"Reveal correct answer to students"}),c.jsx("div",{style:j.policyRow,children:pb.map(L=>c.jsx("button",{type:"button",style:{...j.policyBtn,...z===L.value?j.policyBtnActive:{}},onClick:()=>pe(L.value),children:c.jsx("span",{style:j.policyLabel,children:L.label})},L.value))})]}),c.jsxs("div",{style:{display:"flex",gap:"1rem",alignItems:"flex-end"},children:[c.jsxs("div",{style:{flex:1},children:[c.jsx("label",{className:"label",children:"Duration (seconds)"}),c.jsx("input",{className:"input",type:"number",min:10,max:300,value:P,onChange:L=>b(Number(L.target.value))})]}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{padding:"0.65rem 2rem"},children:"Start Poll →"})]})]})]}),l==="dashboard"&&c.jsxs("div",{style:j.content,className:"fade-up",children:[y&&c.jsxs("div",{style:j.queueBanner,children:[c.jsx("span",{style:j.queueIcon,children:"📚"}),c.jsxs("div",{style:{flex:1},children:[c.jsx("div",{style:j.queueName,children:u.setName}),c.jsxs("div",{style:j.queueProgress,children:["Poll ",u.currentIndex+1," of ",u.totalPolls]})]}),c.jsx("div",{style:j.queueDots,children:Array.from({length:u.totalPolls},(L,te)=>c.jsx("div",{style:{...j.queueDot,background:tea("create"),children:"Create one →"})," ","or"," ",c.jsx("button",{style:j.link,onClick:()=>t("/pollsets"),children:"launch a set →"})]})]}),T&&c.jsxs("div",{style:j.pollCard,children:[c.jsxs("div",{style:j.timerRow,children:[r&&!U?c.jsx(gb,{timeLeft:s,total:r.duration}):c.jsx("div",{style:j.expiredBadge,children:"⏰"}),c.jsxs("div",{style:{flex:1},children:[c.jsx("div",{style:j.pollQuestion,children:T.question}),c.jsxs("div",{style:j.responseMeta,children:[R," / ",e.length," responded",(U||O)&&c.jsx("span",{style:j.expiredTag,children:O?" · Poll ended":" · Stopped accepting answers"})]})]})]}),c.jsx("div",{style:{marginTop:"1.25rem",display:"flex",flexDirection:"column",gap:"0.6rem"},children:T.options.map((L,te)=>{const Te=Object.values(T.responses||{}).filter(z_=>z_===te).length,xe=Object.keys(T.responses||{}).length,Ir=xe>0?Math.round(Te/xe*100):0,da=T.correctIndex===te;return c.jsxs("div",{style:j.optionRow,children:[c.jsxs("div",{style:{...j.optionLabel,...da?j.correctLabel:{}},children:[String.fromCharCode(65+te),da?"✓":""]}),c.jsxs("div",{style:{flex:1},children:[c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"0.25rem"},children:[c.jsx("span",{style:{fontSize:"0.9rem"},children:L}),c.jsxs("span",{style:{fontSize:"0.85rem",color:"var(--muted)"},children:[Te," (",Ir,"%)"]})]}),c.jsx("div",{style:j.barBg,children:c.jsx("div",{style:{...j.barFill,width:`${Ir}%`,background:da?"var(--success)":"var(--accent2)"}})})]})]},te)})}),R>0&&c.jsxs("div",{style:{marginTop:"1rem"},children:[c.jsx("label",{className:"label",children:"Responded"}),c.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.4rem"},children:Object.keys(T.responses).map(L=>c.jsx("span",{style:j.answeredChip,children:L},L))})]}),c.jsxs("div",{style:j.controls,children:[c.jsx("label",{className:"label",style:{marginBottom:"0.75rem"},children:"Student display"}),c.jsxs("div",{style:j.controlGrid,children:[r&&r.resultPolicy==="manual"&&c.jsxs("div",{style:j.controlItem,children:[c.jsx("span",{style:j.controlLabel,children:"Results visible"}),c.jsx(zp,{active:!!r.revealResults,onChange:L=>yc(L,r.revealCorrect)})]}),r&&r.correctPolicy==="manual"&&r.correctIndex!=null&&c.jsxs("div",{style:j.controlItem,children:[c.jsx("span",{style:j.controlLabel,children:"Correct answer visible"}),c.jsx(zp,{active:!!r.revealCorrect,onChange:L=>yc(r.revealResults,L)})]}),c.jsxs("div",{style:j.statusSummary,children:[c.jsx(Bp,{label:"Results",state:T.resultPolicy==="never"?"never":T.resultPolicy==="on_submit"?"auto":T.revealResults?"shown":"hidden"}),T.correctIndex!=null&&c.jsx(Bp,{label:"Answer",state:T.correctPolicy==="never"?"never":tt(T)?"shown":"hidden"})]}),c.jsxs("div",{style:{marginLeft:"auto",display:"flex",gap:"0.5rem",alignItems:"center"},children:[r&&c.jsx("button",{className:"btn btn-secondary",onClick:()=>y?F_(r.revealResults,r.revealCorrect):Do(r.revealResults,r.revealCorrect),children:y?"End Poll":"Close Poll"}),y&&c.jsx("button",{className:"btn btn-primary",onClick:Ee,children:x?"Finish Set ✓":`Next Poll → (${u.currentIndex+2} of ${u.totalPolls})`})]})]})]})]})]})]})]})}function zp({active:t,onChange:e}){return c.jsx("button",{onClick:()=>e(!t),style:{position:"relative",width:48,height:26,borderRadius:13,border:"none",background:t?"var(--success)":"var(--border)",cursor:"pointer",transition:"background 0.2s",flexShrink:0},children:c.jsx("span",{style:{position:"absolute",top:3,left:t?22:3,width:20,height:20,borderRadius:"50%",background:"white",transition:"left 0.2s",boxShadow:"0 1px 3px rgba(0,0,0,0.2)"}})})}function Bp({label:t,state:e}){const n={shown:{bg:"#dcfce7",color:"#15803d"},hidden:{bg:"#fee2e2",color:"#b91c1c"},auto:{bg:"#dbeafe",color:"#1d4ed8"},never:{bg:"var(--cream)",color:"var(--muted)"}},r={shown:"Shown",hidden:"Hidden",auto:"Auto",never:"Never"},i=n[e]||n.never;return c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem"},children:[c.jsxs("span",{style:{fontSize:"0.78rem",color:"var(--muted)"},children:[t,":"]}),c.jsx("span",{style:{background:i.bg,color:i.color,borderRadius:4,padding:"0.15rem 0.5rem",fontSize:"0.75rem",fontWeight:600},children:r[e]})]})}function gb({timeLeft:t,total:e}){const r=2*Math.PI*28,i=e>0?t/e:0,s=r*(1-i),o=i>.4?"var(--accent2)":i>.15?"#f59e0b":"var(--accent)";return c.jsxs("div",{style:{position:"relative",width:72,height:72,flexShrink:0},children:[c.jsxs("svg",{width:"72",height:"72",style:{transform:"rotate(-90deg)"},children:[c.jsx("circle",{cx:"36",cy:"36",r:28,fill:"none",stroke:"var(--cream)",strokeWidth:"5"}),c.jsx("circle",{cx:"36",cy:"36",r:28,fill:"none",stroke:o,strokeWidth:"5",strokeDasharray:r,strokeDashoffset:s,strokeLinecap:"round",style:{transition:"stroke-dashoffset 0.5s linear, stroke 0.5s"}})]}),c.jsx("span",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%,-50%)",fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.1rem"},children:t})]})}const j={page:{display:"flex",minHeight:"100vh",background:"var(--paper)"},sidebar:{width:220,minHeight:"100vh",background:"var(--ink)",color:"white",display:"flex",flexDirection:"column",padding:"1.5rem 1rem",gap:"0.5rem",position:"sticky",top:0,flexShrink:0},logo:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem",padding:"0 0.5rem",marginBottom:"1rem"},nav:{display:"flex",flexDirection:"column",gap:"0.25rem"},navBtn:{background:"transparent",color:"rgba(255,255,255,0.7)",border:"none",borderRadius:8,padding:"0.6rem 0.75rem",textAlign:"left",cursor:"pointer",fontSize:"0.9rem",transition:"all 0.15s"},navActive:{background:"rgba(255,255,255,0.12)",color:"white"},navDisabled:{opacity:.4,cursor:"not-allowed"},sidebarBottom:{marginTop:"auto",display:"flex",flexDirection:"column",gap:"0.75rem"},studentCount:{display:"flex",alignItems:"center",gap:"0.5rem",fontSize:"0.85rem",color:"rgba(255,255,255,0.6)"},dot:{width:8,height:8,borderRadius:"50%",background:"#4ade80",flexShrink:0,boxShadow:"0 0 6px #4ade80"},studentList:{display:"flex",flexWrap:"wrap",gap:"0.35rem",maxHeight:120,overflowY:"auto"},studentChip:{background:"rgba(255,255,255,0.1)",borderRadius:4,padding:"0.2rem 0.5rem",fontSize:"0.78rem",color:"rgba(255,255,255,0.8)"},main:{flex:1,padding:"2rem",overflowY:"auto"},content:{maxWidth:"100%",margin:"0 auto"},pageTitle:{fontSize:"1.6rem",marginBottom:"1.5rem"},form:{display:"flex",flexDirection:"column",gap:"1.25rem",background:"white",padding:"1.5rem",borderRadius:12,border:"1px solid var(--border)"},hint:{fontSize:"0.82rem",color:"var(--muted)",marginBottom:"0.5rem"},policySection:{display:"flex",flexDirection:"column",gap:"0.5rem"},policyRow:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},policyBtn:{display:"flex",flexDirection:"column",gap:"0.2rem",padding:"0.6rem 0.85rem",borderRadius:8,border:"1.5px solid var(--border)",background:"var(--paper)",cursor:"pointer",textAlign:"left",transition:"all 0.15s",flex:1,minWidth:120},policyBtnActive:{borderColor:"var(--accent2)",background:"#eff6ff"},policyLabel:{fontSize:"0.88rem",fontWeight:600,color:"var(--ink)"},empty:{textAlign:"center",padding:"4rem 2rem",color:"var(--muted)",display:"flex",flexDirection:"column",alignItems:"center",gap:"0.75rem"},link:{background:"none",border:"none",color:"var(--accent2)",cursor:"pointer",fontSize:"inherit",textDecoration:"underline"},queueBanner:{display:"flex",alignItems:"center",gap:"0.75rem",background:"#eff6ff",border:"1.5px solid var(--accent2)",borderRadius:12,padding:"0.75rem 1rem",marginBottom:"1.25rem"},queueIcon:{fontSize:"1.4rem"},queueName:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"0.95rem"},queueProgress:{color:"var(--accent2)",fontSize:"0.82rem",marginTop:"0.1rem"},queueDots:{display:"flex",gap:"0.35rem",alignItems:"center"},queueDot:{width:10,height:10,borderRadius:"50%",transition:"background 0.3s"},queueExit:{background:"none",border:"1px solid var(--border)",borderRadius:6,padding:"0.3rem 0.6rem",fontSize:"0.78rem",cursor:"pointer",color:"var(--muted)"},pollCard:{background:"white",borderRadius:12,border:"1px solid var(--border)",padding:"1.5rem"},timerRow:{display:"flex",alignItems:"center",gap:"1rem"},pollQuestion:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.1rem"},responseMeta:{color:"var(--muted)",fontSize:"0.85rem",marginTop:"0.2rem"},expiredBadge:{width:72,height:72,borderRadius:"50%",background:"var(--cream)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"1.8rem",flexShrink:0},expiredTag:{color:"var(--accent)",fontWeight:500},optionRow:{display:"flex",alignItems:"center",gap:"0.75rem"},optionLabel:{width:28,height:28,borderRadius:"50%",background:"var(--cream)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"0.8rem",fontWeight:700,flexShrink:0},correctLabel:{background:"#dcfce7",color:"var(--success)"},barBg:{height:8,borderRadius:4,background:"var(--cream)",overflow:"hidden"},barFill:{height:"100%",borderRadius:4,transition:"width 0.4s ease"},answeredChip:{background:"#dbeafe",color:"var(--accent2)",borderRadius:4,padding:"0.15rem 0.5rem",fontSize:"0.78rem"},correctBtn:{width:32,height:32,borderRadius:"50%",border:"2px solid var(--border)",background:"var(--cream)",cursor:"pointer",fontWeight:700,fontSize:"0.8rem",flexShrink:0,transition:"all 0.15s"},correctBtnActive:{background:"var(--success)",color:"white",borderColor:"var(--success)"},removeBtn:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",fontSize:"0.9rem",padding:"0.25rem",borderRadius:4},controls:{marginTop:"1.25rem",paddingTop:"1.25rem",borderTop:"1px solid var(--border)"},controlGrid:{display:"flex",gap:"1rem",alignItems:"center",flexWrap:"wrap"},controlItem:{display:"flex",alignItems:"center",gap:"0.6rem"},controlLabel:{fontSize:"0.85rem",color:"var(--muted)"},statusSummary:{display:"flex",gap:"0.75rem",flexWrap:"wrap"}};function vb(){var D;const t=Sr(),[e,n]=C.useState(""),[r,i]=C.useState(!1),[s,o]=C.useState(null),[l,a]=C.useState(null),[u,h]=C.useState(!1),[d,f]=C.useState(0),[v,w]=C.useState(null),_=C.useRef(null),E=C.useRef(null);C.useEffect(()=>dh(X=>{!X&&s&&(w(s),setTimeout(()=>w(null),1e4)),X&&X.id!==E.current&&(a(null),h(!1),E.current=X.id),o(X),X&&!X.ended&&f(Math.max(0,Math.round(X.duration-(Date.now()-X.startedAt)/1e3)))}),[s]),C.useEffect(()=>(clearInterval(_.current),s&&!s.ended&&(_.current=setInterval(()=>{const Y=Math.max(0,Math.round(s.duration-(Date.now()-s.startedAt)/1e3));f(Y),Y===0&&clearInterval(_.current)},500)),()=>clearInterval(_.current)),[s==null?void 0:s.id,s==null?void 0:s.ended]),C.useEffect(()=>{if(!r||!e)return;const Y=()=>vc(e);return window.addEventListener("beforeunload",Y),()=>{Y(),window.removeEventListener("beforeunload",Y)}},[r,e]);function g(Y){Y.preventDefault();const X=e.trim();X&&T_(X).then(()=>i(!0))}function p(Y){u||d===0||s!=null&&s.ended||a(Y)}function m(){l===null||u||!s||(b_(e,s.id,l),h(!0))}const S=s&&((D=s.responses)==null?void 0:D[e])!==void 0,I=S?s.responses[e]:l,P=s?Object.keys(s.responses||{}).length:0,b=(s==null?void 0:s.ended)||d===0;function A(){return s?s.revealResults?!0:s.resultPolicy==="never"||s.resultPolicy==="manual"?!1:s.resultPolicy==="on_submit"?u||S:!1:!1}function q(){return!s||s.correctIndex==null?!1:s.revealCorrect?!0:s.correctPolicy==="never"||s.correctPolicy==="manual"?!1:s.correctPolicy==="with_results"?A():!1}const z=A(),pe=q();return r?!s&&!v?c.jsx("div",{style:se.center,children:c.jsxs("div",{style:se.waitCard,className:"fade-up",children:[c.jsx("div",{style:se.pulse}),c.jsxs("h2",{style:{fontFamily:"var(--font-display)",fontSize:"1.5rem"},children:["Hi, ",e,"! 👋"]}),c.jsx("p",{style:{color:"var(--muted)"},children:"Waiting for the teacher to start a poll…"}),c.jsx("button",{style:se.backLink,onClick:()=>{vc(e),t("/")},children:"Leave session"})]})}):!s&&v?c.jsx("div",{style:se.center,children:c.jsxs("div",{style:se.waitCard,className:"fade-up",children:[c.jsx("span",{style:{fontSize:"2.5rem"},children:"✅"}),c.jsx("h2",{style:{fontFamily:"var(--font-display)"},children:"Poll closed!"}),c.jsx("p",{style:{color:"var(--muted)",textAlign:"center"},children:c.jsx("em",{children:v.question})}),v.correctIndex!=null&&v.revealCorrect&&c.jsxs("p",{style:{color:"var(--success)",fontWeight:600},children:["Correct answer: ",v.options[v.correctIndex]]}),c.jsx("p",{style:{color:"var(--muted)",fontSize:"0.85rem"},children:"Waiting for next poll…"})]})}):c.jsxs("div",{style:se.pollPage,children:[c.jsxs("header",{style:se.pollHeader,children:[c.jsxs("span",{style:{fontFamily:"var(--font-display)",fontWeight:700},children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsxs("span",{style:{color:"var(--muted)",fontSize:"0.9rem"},children:["Signed in as ",c.jsx("strong",{children:e})]})]}),c.jsxs("div",{style:se.pollContent,className:"fade-up",children:[!s.ended&&c.jsxs(c.Fragment,{children:[c.jsx("div",{style:se.timerBar,children:c.jsx("div",{style:{...se.timerFill,width:`${d/s.duration*100}%`,background:d>s.duration*.4?"var(--accent2)":d>s.duration*.15?"#f59e0b":"var(--accent)"}})}),c.jsxs("div",{style:se.timerLabel,children:[d,"s remaining · ",P," responded"]})]}),s.ended&&c.jsx("div",{style:se.stoppedBanner,children:"⏰ Time's up — waiting for teacher"}),c.jsx("h2",{style:se.questionText,children:s.question}),c.jsx("div",{style:se.optionGrid,children:s.options.map((Y,X)=>{const et=I===X,Ee=s.correctIndex===X,Be=Object.values(s.responses||{}).filter(U=>U===X).length,R=P>0?Math.round(Be/P*100):0;return c.jsxs("button",{style:{...se.optionBtn,...et?se.optionSelected:{},...pe&&Ee?se.optionCorrect:{},...b||S?{cursor:"default"}:{}},onClick:()=>p(X),disabled:b||S,children:[c.jsx("span",{style:se.optionLetter,children:String.fromCharCode(65+X)}),c.jsx("span",{style:{flex:1,textAlign:"left"},children:Y}),z&&c.jsxs("span",{style:se.optionPct,children:[R,"%"]}),z&&c.jsx("div",{style:{...se.optionBar,width:`${R}%`,background:pe&&Ee?"rgba(22,163,74,0.15)":"rgba(37,99,235,0.1)"}})]},X)})}),!S&&!u&&!b&&c.jsx("button",{className:"btn btn-primary",style:{width:"100%",justifyContent:"center",padding:"0.85rem",fontSize:"1rem",marginTop:"0.5rem"},onClick:m,disabled:l===null,children:"Submit Answer"}),(u||S)&&!b&&c.jsx("div",{style:se.submittedBadge,children:"✓ Answer submitted"}),b&&!S&&!u&&c.jsx("div",{style:{...se.submittedBadge,background:"#fef9c3",color:"#854d0e",borderColor:"#fef08a"},children:"⏰ Time's up — no answer recorded"}),b&&(S||u)&&c.jsx("div",{style:se.submittedBadge,children:"✓ Answer submitted — waiting for teacher"})]})]}):c.jsx("div",{style:se.center,children:c.jsxs("div",{style:se.joinCard,className:"fade-up",children:[c.jsxs("div",{style:se.joinLogo,children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsx("h1",{style:{fontSize:"1.8rem",marginBottom:"0.25rem"},children:"Join Session"}),c.jsx("p",{style:{color:"var(--muted)",marginBottom:"1.5rem"},children:"Enter your name to start answering polls"}),c.jsxs("form",{onSubmit:g,style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[c.jsx("input",{className:"input",placeholder:"Your first name",value:e,onChange:Y=>n(Y.target.value),autoFocus:!0,style:{fontSize:"1.1rem",textAlign:"center"},required:!0}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{justifyContent:"center",padding:"0.75rem"},children:"Join →"})]}),c.jsx("button",{style:se.backLink,onClick:()=>t("/"),children:"← Back"})]})})}const se={center:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"var(--paper)"},joinCard:{background:"white",borderRadius:16,border:"1px solid var(--border)",padding:"2.5rem 2rem",maxWidth:380,width:"100%",textAlign:"center",boxShadow:"var(--shadow)"},joinLogo:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem",marginBottom:"1.5rem",display:"block"},backLink:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",marginTop:"1rem",fontSize:"0.85rem",display:"block",textAlign:"center"},waitCard:{display:"flex",flexDirection:"column",alignItems:"center",gap:"0.75rem",background:"white",borderRadius:16,border:"1px solid var(--border)",padding:"3rem 2rem",maxWidth:380,width:"100%",textAlign:"center",boxShadow:"var(--shadow)"},pulse:{width:16,height:16,borderRadius:"50%",background:"var(--accent2)",boxShadow:"0 0 0 0 rgba(37,99,235,0.4)",animation:"pulse-ring 1.5s ease-out infinite"},pollPage:{minHeight:"100vh",background:"var(--paper)",display:"flex",flexDirection:"column"},pollHeader:{padding:"1rem 1.5rem",borderBottom:"1px solid var(--border)",display:"flex",justifyContent:"space-between",alignItems:"center",background:"white"},pollContent:{maxWidth:620,margin:"0 auto",padding:"2rem 1rem",width:"100%"},timerBar:{height:6,background:"var(--cream)",borderRadius:3,overflow:"hidden",marginBottom:"0.4rem"},timerFill:{height:"100%",borderRadius:3,transition:"width 0.5s linear, background 0.5s"},timerLabel:{color:"var(--muted)",fontSize:"0.82rem",marginBottom:"1.5rem"},stoppedBanner:{background:"#fef9c3",color:"#854d0e",border:"1px solid #fef08a",borderRadius:8,padding:"0.6rem 1rem",fontSize:"0.9rem",marginBottom:"1.5rem",textAlign:"center"},questionText:{fontFamily:"var(--font-display)",fontSize:"clamp(1.2rem, 3vw, 1.6rem)",lineHeight:1.25,marginBottom:"1.25rem"},optionGrid:{display:"flex",flexDirection:"column",gap:"0.6rem"},optionBtn:{position:"relative",overflow:"hidden",display:"flex",alignItems:"center",gap:"0.75rem",padding:"0.9rem 1rem",borderRadius:10,border:"2px solid var(--border)",background:"white",cursor:"pointer",transition:"all 0.15s",textAlign:"left",fontFamily:"var(--font-body)",fontSize:"0.95rem"},optionSelected:{borderColor:"var(--accent2)",background:"#eff6ff"},optionCorrect:{borderColor:"var(--success)",background:"#f0fdf4"},optionLetter:{width:28,height:28,borderRadius:"50%",background:"var(--cream)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"0.8rem",fontWeight:700,flexShrink:0},optionPct:{color:"var(--muted)",fontSize:"0.82rem",fontWeight:600,flexShrink:0,zIndex:1},optionBar:{position:"absolute",left:0,top:0,height:"100%",transition:"width 0.4s ease",zIndex:0,pointerEvents:"none"},submittedBadge:{marginTop:"1rem",padding:"0.75rem",borderRadius:8,background:"#f0fdf4",color:"var(--success)",textAlign:"center",fontWeight:500,fontSize:"0.9rem",border:"1px solid #bbf7d0"}};function U_(t,e={}){const{duration:n=60,resultPolicy:r="on_submit",correctPolicy:i="with_results"}=e,s=t.split(/^---$/m).map(l=>l.trim()).filter(Boolean),o=[];for(const l of s){const a=l.split(` + */const sb=5*60,ob=kv("authIdTokenMaxAge")||sb;let Fp=null;const lb=t=>async e=>{const n=e&&await e.getIdTokenResult(),r=n&&(new Date().getTime()-Date.parse(n.issuedAtTime))/1e3;if(r&&r>ob)return;const i=n==null?void 0:n.token;Fp!==i&&(Fp=i,await fetch(t,{method:i?"POST":"DELETE",headers:i?{Authorization:`Bearer ${i}`}:{}}))};function ab(t=Av()){const e=Ed(t,"auth");if(e.isInitialized())return e.getImmediate();const n=UT(t,{popupRedirectResolver:tb,persistence:[h1,e1,__]}),r=kv("authTokenSyncURL");if(r&&typeof isSecureContext=="boolean"&&isSecureContext){const s=new URL(r,location.origin);if(location.origin===s.origin){const o=lb(s.toString());JT(n,o,()=>o(n.currentUser)),YT(n,l=>o(l))}}const i=xv("auth");return i&&BT(n,`http://${i}`),n}function ub(){var t,e;return(e=(t=document.getElementsByTagName("head"))===null||t===void 0?void 0:t[0])!==null&&e!==void 0?e:document}LT({loadJS(t){return new Promise((e,n)=>{const r=document.createElement("script");r.setAttribute("src",t),r.onload=e,r.onerror=i=>{const s=Ut("internal-error");s.customData=i,n(s)},r.type="text/javascript",r.charset="UTF-8",ub().appendChild(r)})},gapiScript:"https://apis.google.com/js/api.js",recaptchaV2Script:"https://www.google.com/recaptcha/api.js",recaptchaEnterpriseScript:"https://www.google.com/recaptcha/enterprise.js?render="});ib("Browser");const cb={apiKey:"AIzaSyBiZSV4Z_3-L0z8RP5yY_2xXlw5fKOy2jc",authDomain:"classroom-polling-dd344.firebaseapp.com",databaseURL:"https://classroom-polling-dd344-default-rtdb.firebaseio.com",projectId:"classroom-polling-dd344",storageBucket:"classroom-polling-dd344.firebasestorage.app",messagingSenderId:"528103899828",appId:"1:528103899828:web:f74274640de611a61d0de1"},k_=Rv(cb),re=aT(k_),db=ab(k_);GT(db).catch(console.error);function T_(t){const e=new Date().toLocaleDateString("en-CA");return on(ne(re,`session/students/${t}`),{joinedAt:Sp(),date:e}),on(ne(re,`sessionStudents/${e}_${t}`),{name:t,date:e,joinedAt:Sp()})}function vc(t){return vr(ne(re,`session/students/${t}`))}function b_(t,e,n){return sa(ne(re,"session/activePoll/responses"),{[t]:n})}function Pl({question:t,options:e,correctIndex:n,duration:r,resultPolicy:i,correctPolicy:s}){const o=`poll_${Date.now()}`;return on(ne(re,"session/activePoll"),{id:o,question:t,options:e,correctIndex:n??null,duration:r,resultPolicy:i,correctPolicy:s,startedAt:Date.now(),responses:{},ended:!1,revealResults:!1,revealCorrect:!1})}async function Do(t,e){const[n,r]=await Promise.all([Ns(ne(re,"session/activePoll")),Ns(ne(re,"session/queue"))]),i=n.val(),s=r.val();if(!i)return;const o={...i,revealResults:t,revealCorrect:e,endedAt:Date.now()};return s&&(o.setId=s.setId,o.setName=s.setName,o.setPosition=s.currentIndex,o.sessionKey=s.sessionKey),await on(ne(re,`pollHistory/${i.id}`),o),vr(ne(re,"session/activePoll"))}function P_(){return sa(ne(re,"session/activePoll"),{ended:!0})}function yc(t,e){return sa(ne(re,"session/activePoll"),{revealResults:t,revealCorrect:e})}function dh(t){const e=ne(re,"session/activePoll");return xr(e,n=>t(n.val()))}function N_(t){const e=ne(re,"session/students");return xr(e,n=>{const r=n.val()||{};t(Object.keys(r).map(i=>({name:i,...r[i]})))})}function R_(t){const e=ne(re,"pollHistory");return xr(e,n=>{const r=n.val()||{},i=Object.values(r).sort((s,o)=>(o.startedAt||0)-(s.startedAt||0));t(i)})}function A_(t){const e=ne(re,"pollSets");return xr(e,n=>{const r=n.val()||{},i=Object.entries(r).map(([s,o])=>({id:s,...o})).sort((s,o)=>(o.createdAt||0)-(s.createdAt||0));t(i)})}async function _c({name:t,defaults:e,polls:n}){const r=`set_${Date.now()}`;return await on(ne(re,`pollSets/${r}`),{id:r,name:t,createdAt:Date.now(),defaults:e,polls:n||[]}),r}function Lo(t,e){return Ns(ne(re,`pollSets/${t}`)).then(n=>{const r=n.val()||{};return on(ne(re,`pollSets/${t}`),{...r,...e})})}function O_(t){return vr(ne(re,`pollSets/${t}`))}function D_(t,e){const n=ne(re,`pollSets/${t}`);return xr(n,r=>e(r.val()))}function L_(t,e,n){const r=`run_${Date.now()}`;return on(ne(re,"session/queue"),{setId:t,setName:e,currentIndex:0,totalPolls:n,sessionKey:r})}function M_(t){return sa(ne(re,"session/queue"),{currentIndex:t})}function wc(){return vr(ne(re,"session/queue"))}function j_(t){const e=ne(re,"session/queue");return xr(e,n=>t(n.val()))}async function F_(t,e){const r=(await Ns(ne(re,"session/activePoll"))).val(),s=(await Ns(ne(re,"session/queue"))).val();if(!r)return;const o={...r,revealResults:t,revealCorrect:e,endedAt:Date.now()};return s&&(o.setId=s.setId,o.setName=s.setName,o.setPosition=s.currentIndex,o.sessionKey=s.sessionKey),await on(ne(re,`pollHistory/${r.id}`),o),vr(ne(re,"session/activePoll"))}const hb=Object.freeze(Object.defineProperty({__proto__:null,advanceQueue:M_,clearQueue:wc,closePoll:F_,createPollSet:_c,deletePollSet:O_,endPoll:Do,expirePoll:P_,joinSession:T_,launchSet:L_,leaveSession:vc,revealPollResults:yc,startPoll:Pl,submitAnswer:b_,updatePollSet:Lo,watchActivePoll:dh,watchPollHistory:R_,watchPollSet:D_,watchPollSets:A_,watchQueue:j_,watchStudents:N_},Symbol.toStringTag,{value:"Module"})),Up=60,fb=[{value:"on_submit",label:"After they submit"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}],pb=[{value:"with_results",label:"With results"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}];function mb(){var Ge;const t=Sr(),[e,n]=C.useState([]),[r,i]=C.useState(null),[s,o]=C.useState(0),[l,a]=C.useState("dashboard"),[u,h]=C.useState(null),[d,f]=C.useState(null),v=C.useRef(null),w=C.useRef(null),_=C.useRef(null),[E,g]=C.useState(""),[p,m]=C.useState(["",""]),[S,I]=C.useState(null),[P,b]=C.useState(Up),[A,q]=C.useState("on_submit"),[z,pe]=C.useState("with_results");C.useEffect(()=>{localStorage.getItem("role")!=="instructor"&&t("/")},[]),C.useEffect(()=>{const L=dh(xe=>{xe&&(_.current=xe),i(xe),xe&&!xe.ended&&o(Math.max(0,Math.round(xe.duration-(Date.now()-xe.startedAt)/1e3)))}),te=N_(n),Te=j_(xe=>{h(xe),xe!=null&&xe.setId?(w.current&&w.current(),gC(async()=>{const{watchPollSet:Ir}=await Promise.resolve().then(()=>hb);return{watchPollSet:Ir}},void 0).then(({watchPollSet:Ir})=>{w.current=Ir(xe.setId,f)})):(f(null),_.current=null,w.current&&(w.current(),w.current=null))});return()=>{L(),te(),Te()}},[]),C.useEffect(()=>(clearInterval(v.current),r&&!r.ended&&(v.current=setInterval(()=>{const L=Math.max(0,Math.round(r.duration-(Date.now()-r.startedAt)/1e3));o(L),L===0&&(clearInterval(v.current),P_())},500)),()=>clearInterval(v.current)),[r==null?void 0:r.id,r==null?void 0:r.ended]);function D(){p.length<6&&m([...p,""])}function Y(L,te){m(p.map((Te,xe)=>xe===L?te:Te))}function X(L){if(p.length<=2)return;const te=p.filter((Te,xe)=>xe!==L);m(te),S===L?I(null):S>L&&I(S-1)}function et(L){L.preventDefault();const te=p.filter(Te=>Te.trim());!E.trim()||te.length<2||(Pl({question:E.trim(),options:te,correctIndex:S,duration:P,resultPolicy:A,correctPolicy:z}),g(""),m(["",""]),I(null),b(Up),q("on_submit"),pe("with_results"),a("dashboard"))}async function Ee(){if(!u||!d)return;const L=u.currentIndex+1;if(r&&await Do(r.revealResults||!1,r.revealCorrect||!1),L>=u.totalPolls){await wc();return}await M_(L);const te=d.defaults||{},Te=(d.polls||[])[L];Te&&await Pl({question:Te.question,options:Te.options,correctIndex:Te.correctIndex??null,duration:Te.duration??te.duration??60,resultPolicy:Te.resultPolicy??te.resultPolicy??"on_submit",correctPolicy:Te.correctPolicy??te.correctPolicy??"with_results"})}async function Be(){r&&await Do(r.revealResults||!1,r.revealCorrect||!1),await wc()}const R=r?Object.keys(r.responses||{}).length:Object.keys(((Ge=_.current)==null?void 0:Ge.responses)||{}).length,U=r==null?void 0:r.ended,y=!!u,x=u&&u.currentIndex>=u.totalPolls-1,T=r||(y?_.current:null),O=!r&&T;function K(L){return L.revealResults?!0:!(L.resultPolicy==="never"||L.resultPolicy==="manual")}function tt(L){return L.revealCorrect?!0:L.correctPolicy==="never"||L.correctPolicy==="manual"?!1:!!(L.correctPolicy==="with_results"&&K(L))}return c.jsxs("div",{style:j.page,children:[c.jsxs("aside",{style:j.sidebar,children:[c.jsxs("div",{style:j.logo,children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsxs("nav",{style:j.nav,children:[c.jsx("button",{style:{...j.navBtn,...l==="dashboard"?j.navActive:{}},onClick:()=>a("dashboard"),children:"📊 Dashboard"}),c.jsx("button",{style:{...j.navBtn,...l==="create"?j.navActive:{},...r?j.navDisabled:{}},onClick:()=>!r&&a("create"),disabled:!!r,children:"➕ New Poll"}),c.jsx("button",{style:j.navBtn,onClick:()=>t("/pollsets"),children:"📚 Poll Sets"}),c.jsx("button",{style:j.navBtn,onClick:()=>t("/history"),children:"🕐 History"})]}),c.jsxs("div",{style:j.sidebarBottom,children:[c.jsxs("div",{style:j.studentCount,children:[c.jsx("span",{style:j.dot}),c.jsx("strong",{children:e.length})," student",e.length!==1?"s":""," online"]}),c.jsx("div",{style:j.studentList,children:e.map(L=>c.jsx("div",{style:j.studentChip,children:L.name},L.name))}),c.jsx("button",{className:"btn btn-secondary",style:{width:"100%",marginTop:"auto",fontSize:"0.8rem"},onClick:()=>{localStorage.removeItem("role"),localStorage.removeItem("historyAuth"),t("/")},children:"Exit"})]})]}),c.jsxs("main",{style:j.main,children:[l==="create"&&c.jsxs("div",{style:j.content,className:"fade-up",children:[c.jsx("h2",{style:j.pageTitle,children:"Create a Poll"}),c.jsxs("form",{onSubmit:et,style:j.form,children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Question"}),c.jsx("textarea",{className:"input",rows:2,placeholder:"e.g. Which process converts sunlight into energy?",value:E,onChange:L=>g(L.target.value),style:{resize:"vertical",width:"100%"},required:!0})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Answer Options"}),c.jsx("p",{style:j.hint,children:"Click a letter circle to mark the correct answer (optional)"}),c.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:p.map((L,te)=>c.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[c.jsx("button",{type:"button",style:{...j.correctBtn,...S===te?j.correctBtnActive:{}},onClick:()=>I(S===te?null:te),children:S===te?"✓":String.fromCharCode(65+te)}),c.jsx("input",{className:"input",style:{flex:1},placeholder:`Option ${String.fromCharCode(65+te)}`,value:L,onChange:Te=>Y(te,Te.target.value),required:!0}),c.jsx("button",{type:"button",style:j.removeBtn,onClick:()=>X(te),disabled:p.length<=2,children:"✕"})]},te))}),p.length<6&&c.jsx("button",{type:"button",className:"btn btn-ghost",style:{marginTop:"0.5rem",fontSize:"0.85rem"},onClick:D,children:"+ Add option"})]}),c.jsxs("div",{style:j.policySection,children:[c.jsx("label",{className:"label",children:"Show results to students"}),c.jsx("div",{style:j.policyRow,children:fb.map(L=>c.jsx("button",{type:"button",style:{...j.policyBtn,...A===L.value?j.policyBtnActive:{}},onClick:()=>q(L.value),children:c.jsx("span",{style:j.policyLabel,children:L.label})},L.value))})]}),S!=null&&c.jsxs("div",{style:j.policySection,children:[c.jsx("label",{className:"label",children:"Reveal correct answer to students"}),c.jsx("div",{style:j.policyRow,children:pb.map(L=>c.jsx("button",{type:"button",style:{...j.policyBtn,...z===L.value?j.policyBtnActive:{}},onClick:()=>pe(L.value),children:c.jsx("span",{style:j.policyLabel,children:L.label})},L.value))})]}),c.jsxs("div",{style:{display:"flex",gap:"1rem",alignItems:"flex-end"},children:[c.jsxs("div",{style:{flex:1},children:[c.jsx("label",{className:"label",children:"Duration (seconds)"}),c.jsx("input",{className:"input",type:"number",min:10,max:300,value:P,onChange:L=>b(Number(L.target.value))})]}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{padding:"0.65rem 2rem"},children:"Start Poll →"})]})]})]}),l==="dashboard"&&c.jsxs("div",{style:j.content,className:"fade-up",children:[y&&c.jsxs("div",{style:j.queueBanner,children:[c.jsx("span",{style:j.queueIcon,children:"📚"}),c.jsxs("div",{style:{flex:1},children:[c.jsx("div",{style:j.queueName,children:u.setName}),c.jsxs("div",{style:j.queueProgress,children:["Poll ",u.currentIndex+1," of ",u.totalPolls]})]}),c.jsx("div",{style:j.queueDots,children:Array.from({length:u.totalPolls},(L,te)=>c.jsx("div",{style:{...j.queueDot,background:tea("create"),children:"Create one →"})," ","or"," ",c.jsx("button",{style:j.link,onClick:()=>t("/pollsets"),children:"launch a set →"})]})]}),T&&c.jsxs("div",{style:j.pollCard,children:[c.jsxs("div",{style:j.timerRow,children:[r&&!U?c.jsx(gb,{timeLeft:s,total:r.duration}):c.jsx("div",{style:j.expiredBadge,children:"⏰"}),c.jsxs("div",{style:{flex:1},children:[c.jsx("div",{style:j.pollQuestion,children:T.question}),c.jsxs("div",{style:j.responseMeta,children:[R," / ",e.length," responded",(U||O)&&c.jsx("span",{style:j.expiredTag,children:O?" · Poll ended":" · Stopped accepting answers"})]})]})]}),c.jsx("div",{style:{marginTop:"1.25rem",display:"flex",flexDirection:"column",gap:"0.6rem"},children:T.options.map((L,te)=>{const Te=Object.values(T.responses||{}).filter(z_=>z_===te).length,xe=Object.keys(T.responses||{}).length,Ir=xe>0?Math.round(Te/xe*100):0,da=T.correctIndex===te;return c.jsxs("div",{style:j.optionRow,children:[c.jsxs("div",{style:{...j.optionLabel,...da?j.correctLabel:{}},children:[String.fromCharCode(65+te),da?"✓":""]}),c.jsxs("div",{style:{flex:1},children:[c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"0.25rem"},children:[c.jsx("span",{style:{fontSize:"0.9rem"},children:L}),c.jsxs("span",{style:{fontSize:"0.85rem",color:"var(--muted)"},children:[Te," (",Ir,"%)"]})]}),c.jsx("div",{style:j.barBg,children:c.jsx("div",{style:{...j.barFill,width:`${Ir}%`,background:da?"var(--success)":"var(--accent2)"}})})]})]},te)})}),R>0&&c.jsxs("div",{style:{marginTop:"1rem"},children:[c.jsx("label",{className:"label",children:"Responded"}),c.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.4rem"},children:Object.keys(T.responses).map(L=>c.jsx("span",{style:j.answeredChip,children:L},L))})]}),c.jsxs("div",{style:j.controls,children:[c.jsx("label",{className:"label",style:{marginBottom:"0.75rem"},children:"Student display"}),c.jsxs("div",{style:j.controlGrid,children:[r&&r.resultPolicy==="manual"&&c.jsxs("div",{style:j.controlItem,children:[c.jsx("span",{style:j.controlLabel,children:"Results visible"}),c.jsx(zp,{active:!!r.revealResults,onChange:L=>yc(L,r.revealCorrect)})]}),r&&r.correctPolicy==="manual"&&r.correctIndex!=null&&c.jsxs("div",{style:j.controlItem,children:[c.jsx("span",{style:j.controlLabel,children:"Correct answer visible"}),c.jsx(zp,{active:!!r.revealCorrect,onChange:L=>yc(r.revealResults,L)})]}),c.jsxs("div",{style:j.statusSummary,children:[c.jsx(Bp,{label:"Results",state:T.resultPolicy==="never"?"never":T.resultPolicy==="on_submit"?"auto":T.revealResults?"shown":"hidden"}),T.correctIndex!=null&&c.jsx(Bp,{label:"Answer",state:T.correctPolicy==="never"?"never":tt(T)?"shown":"hidden"})]}),c.jsxs("div",{style:{marginLeft:"auto",display:"flex",gap:"0.5rem",alignItems:"center"},children:[r&&c.jsx("button",{className:"btn btn-secondary",onClick:()=>y?F_(r.revealResults,r.revealCorrect):Do(r.revealResults,r.revealCorrect),children:y?"End Poll":"Close Poll"}),y&&c.jsx("button",{className:"btn btn-primary",onClick:Ee,children:x?"Finish Set ✓":`Next Poll → (${u.currentIndex+2} of ${u.totalPolls})`})]})]})]})]})]})]})]})}function zp({active:t,onChange:e}){return c.jsx("button",{onClick:()=>e(!t),style:{position:"relative",width:48,height:26,borderRadius:13,border:"none",background:t?"var(--success)":"var(--border)",cursor:"pointer",transition:"background 0.2s",flexShrink:0},children:c.jsx("span",{style:{position:"absolute",top:3,left:t?22:3,width:20,height:20,borderRadius:"50%",background:"white",transition:"left 0.2s",boxShadow:"0 1px 3px rgba(0,0,0,0.2)"}})})}function Bp({label:t,state:e}){const n={shown:{bg:"#dcfce7",color:"#15803d"},hidden:{bg:"#fee2e2",color:"#b91c1c"},auto:{bg:"#dbeafe",color:"#1d4ed8"},never:{bg:"var(--cream)",color:"var(--muted)"}},r={shown:"Shown",hidden:"Hidden",auto:"Auto",never:"Never"},i=n[e]||n.never;return c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem"},children:[c.jsxs("span",{style:{fontSize:"0.78rem",color:"var(--muted)"},children:[t,":"]}),c.jsx("span",{style:{background:i.bg,color:i.color,borderRadius:4,padding:"0.15rem 0.5rem",fontSize:"0.75rem",fontWeight:600},children:r[e]})]})}function gb({timeLeft:t,total:e}){const r=2*Math.PI*28,i=e>0?t/e:0,s=r*(1-i),o=i>.4?"var(--accent2)":i>.15?"#f59e0b":"var(--accent)";return c.jsxs("div",{style:{position:"relative",width:72,height:72,flexShrink:0},children:[c.jsxs("svg",{width:"72",height:"72",style:{transform:"rotate(-90deg)"},children:[c.jsx("circle",{cx:"36",cy:"36",r:28,fill:"none",stroke:"var(--cream)",strokeWidth:"5"}),c.jsx("circle",{cx:"36",cy:"36",r:28,fill:"none",stroke:o,strokeWidth:"5",strokeDasharray:r,strokeDashoffset:s,strokeLinecap:"round",style:{transition:"stroke-dashoffset 0.5s linear, stroke 0.5s"}})]}),c.jsx("span",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%,-50%)",fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.1rem"},children:t})]})}const j={page:{display:"flex",minHeight:"100vh",background:"var(--paper)"},sidebar:{width:220,minHeight:"100vh",background:"var(--ink)",color:"white",display:"flex",flexDirection:"column",padding:"1.5rem 1rem",gap:"0.5rem",position:"sticky",top:0,flexShrink:0},logo:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem",padding:"0 0.5rem",marginBottom:"1rem"},nav:{display:"flex",flexDirection:"column",gap:"0.25rem"},navBtn:{background:"transparent",color:"rgba(255,255,255,0.7)",border:"none",borderRadius:8,padding:"0.6rem 0.75rem",textAlign:"left",cursor:"pointer",fontSize:"0.9rem",transition:"all 0.15s"},navActive:{background:"rgba(255,255,255,0.12)",color:"white"},navDisabled:{opacity:.4,cursor:"not-allowed"},sidebarBottom:{marginTop:"auto",display:"flex",flexDirection:"column",gap:"0.75rem"},studentCount:{display:"flex",alignItems:"center",gap:"0.5rem",fontSize:"0.85rem",color:"rgba(255,255,255,0.6)"},dot:{width:8,height:8,borderRadius:"50%",background:"#4ade80",flexShrink:0,boxShadow:"0 0 6px #4ade80"},studentList:{display:"flex",flexWrap:"wrap",gap:"0.35rem",maxHeight:120,overflowY:"auto"},studentChip:{background:"rgba(255,255,255,0.1)",borderRadius:4,padding:"0.2rem 0.5rem",fontSize:"0.78rem",color:"rgba(255,255,255,0.8)"},main:{flex:1,padding:"2rem",overflowY:"auto"},content:{maxWidth:"100%",margin:"0 auto"},pageTitle:{fontSize:"1.6rem",marginBottom:"1.5rem"},form:{display:"flex",flexDirection:"column",gap:"1.25rem",background:"white",padding:"1.5rem",borderRadius:12,border:"1px solid var(--border)"},hint:{fontSize:"0.82rem",color:"var(--muted)",marginBottom:"0.5rem"},policySection:{display:"flex",flexDirection:"column",gap:"0.5rem"},policyRow:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},policyBtn:{display:"flex",flexDirection:"column",gap:"0.2rem",padding:"0.6rem 0.85rem",borderRadius:8,border:"1.5px solid var(--border)",background:"var(--paper)",cursor:"pointer",textAlign:"left",transition:"all 0.15s",flex:1,minWidth:120},policyBtnActive:{borderColor:"var(--accent2)",background:"#eff6ff"},policyLabel:{fontSize:"0.88rem",fontWeight:600,color:"var(--ink)"},empty:{textAlign:"center",padding:"4rem 2rem",color:"var(--muted)",display:"flex",flexDirection:"column",alignItems:"center",gap:"0.75rem"},link:{background:"none",border:"none",color:"var(--accent2)",cursor:"pointer",fontSize:"inherit",textDecoration:"underline"},queueBanner:{display:"flex",alignItems:"center",gap:"0.75rem",background:"#eff6ff",border:"1.5px solid var(--accent2)",borderRadius:12,padding:"0.75rem 1rem",marginBottom:"1.25rem"},queueIcon:{fontSize:"1.4rem"},queueName:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"0.95rem"},queueProgress:{color:"var(--accent2)",fontSize:"0.82rem",marginTop:"0.1rem"},queueDots:{display:"flex",gap:"0.35rem",alignItems:"center"},queueDot:{width:10,height:10,borderRadius:"50%",transition:"background 0.3s"},queueExit:{background:"none",border:"1px solid var(--border)",borderRadius:6,padding:"0.3rem 0.6rem",fontSize:"0.78rem",cursor:"pointer",color:"var(--muted)"},pollCard:{background:"white",borderRadius:12,border:"1px solid var(--border)",padding:"1.5rem"},timerRow:{display:"flex",alignItems:"center",gap:"1rem"},pollQuestion:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.1rem"},responseMeta:{color:"var(--muted)",fontSize:"0.85rem",marginTop:"0.2rem"},expiredBadge:{width:72,height:72,borderRadius:"50%",background:"var(--cream)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"1.8rem",flexShrink:0},expiredTag:{color:"var(--accent)",fontWeight:500},optionRow:{display:"flex",alignItems:"center",gap:"0.75rem"},optionLabel:{width:28,height:28,borderRadius:"50%",background:"var(--cream)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"0.8rem",fontWeight:700,flexShrink:0},correctLabel:{background:"#dcfce7",color:"var(--success)"},barBg:{height:8,borderRadius:4,background:"var(--cream)",overflow:"hidden"},barFill:{height:"100%",borderRadius:4,transition:"width 0.4s ease"},answeredChip:{background:"#dbeafe",color:"var(--accent2)",borderRadius:4,padding:"0.15rem 0.5rem",fontSize:"0.78rem"},correctBtn:{width:32,height:32,borderRadius:"50%",border:"2px solid var(--border)",background:"var(--cream)",cursor:"pointer",fontWeight:700,fontSize:"0.8rem",flexShrink:0,transition:"all 0.15s"},correctBtnActive:{background:"var(--success)",color:"white",borderColor:"var(--success)"},removeBtn:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",fontSize:"0.9rem",padding:"0.25rem",borderRadius:4},controls:{marginTop:"1.25rem",paddingTop:"1.25rem",borderTop:"1px solid var(--border)"},controlGrid:{display:"flex",gap:"1rem",alignItems:"center",flexWrap:"wrap"},controlItem:{display:"flex",alignItems:"center",gap:"0.6rem"},controlLabel:{fontSize:"0.85rem",color:"var(--muted)"},statusSummary:{display:"flex",gap:"0.75rem",flexWrap:"wrap"}};function vb(){var D;const t=Sr(),[e,n]=C.useState(""),[r,i]=C.useState(!1),[s,o]=C.useState(null),[l,a]=C.useState(null),[u,h]=C.useState(!1),[d,f]=C.useState(0),[v,w]=C.useState(null),_=C.useRef(null),E=C.useRef(null);C.useEffect(()=>dh(X=>{!X&&s&&(w(s),setTimeout(()=>w(null),1e4)),X&&X.id!==E.current&&(a(null),h(!1),E.current=X.id),o(X),X&&!X.ended&&f(Math.max(0,Math.round(X.duration-(Date.now()-X.startedAt)/1e3)))}),[s]),C.useEffect(()=>(clearInterval(_.current),s&&!s.ended&&(_.current=setInterval(()=>{const Y=Math.max(0,Math.round(s.duration-(Date.now()-s.startedAt)/1e3));f(Y),Y===0&&clearInterval(_.current)},500)),()=>clearInterval(_.current)),[s==null?void 0:s.id,s==null?void 0:s.ended]),C.useEffect(()=>{if(!r||!e)return;const Y=()=>vc(e);return window.addEventListener("beforeunload",Y),()=>{Y(),window.removeEventListener("beforeunload",Y)}},[r,e]);function g(Y){Y.preventDefault();const X=e.trim();X&&T_(X).then(()=>i(!0))}function p(Y){u||d===0||s!=null&&s.ended||a(Y)}function m(){l===null||u||!s||(b_(e,s.id,l),h(!0))}const S=s&&((D=s.responses)==null?void 0:D[e])!==void 0,I=S?s.responses[e]:l,P=s?Object.keys(s.responses||{}).length:0,b=(s==null?void 0:s.ended)||d===0;function A(){return s?s.revealResults?!0:s.resultPolicy==="never"||s.resultPolicy==="manual"?!1:s.resultPolicy==="on_submit"?u||S:!1:!1}function q(){return!s||s.correctIndex==null?!1:s.revealCorrect?!0:s.correctPolicy==="never"||s.correctPolicy==="manual"?!1:s.correctPolicy==="with_results"?A():!1}const z=A(),pe=q();return r?!s&&!v?c.jsx("div",{style:se.center,children:c.jsxs("div",{style:se.waitCard,className:"fade-up",children:[c.jsx("div",{style:se.pulse}),c.jsxs("h2",{style:{fontFamily:"var(--font-display)",fontSize:"1.5rem"},children:["Hi, ",e,"! 👋"]}),c.jsx("p",{style:{color:"var(--muted)"},children:"Waiting for the instructor to start a poll…"}),c.jsx("button",{style:se.backLink,onClick:()=>{vc(e),t("/")},children:"Leave session"})]})}):!s&&v?c.jsx("div",{style:se.center,children:c.jsxs("div",{style:se.waitCard,className:"fade-up",children:[c.jsx("span",{style:{fontSize:"2.5rem"},children:"✅"}),c.jsx("h2",{style:{fontFamily:"var(--font-display)"},children:"Poll closed!"}),c.jsx("p",{style:{color:"var(--muted)",textAlign:"center"},children:c.jsx("em",{children:v.question})}),v.correctIndex!=null&&v.revealCorrect&&c.jsxs("p",{style:{color:"var(--success)",fontWeight:600},children:["Correct answer: ",v.options[v.correctIndex]]}),c.jsx("p",{style:{color:"var(--muted)",fontSize:"0.85rem"},children:"Waiting for next poll…"})]})}):c.jsxs("div",{style:se.pollPage,children:[c.jsxs("header",{style:se.pollHeader,children:[c.jsxs("span",{style:{fontFamily:"var(--font-display)",fontWeight:700},children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsxs("span",{style:{color:"var(--muted)",fontSize:"0.9rem"},children:["Signed in as ",c.jsx("strong",{children:e})]})]}),c.jsxs("div",{style:se.pollContent,className:"fade-up",children:[!s.ended&&c.jsxs(c.Fragment,{children:[c.jsx("div",{style:se.timerBar,children:c.jsx("div",{style:{...se.timerFill,width:`${d/s.duration*100}%`,background:d>s.duration*.4?"var(--accent2)":d>s.duration*.15?"#f59e0b":"var(--accent)"}})}),c.jsxs("div",{style:se.timerLabel,children:[d,"s remaining · ",P," responded"]})]}),s.ended&&c.jsx("div",{style:se.stoppedBanner,children:"⏰ Time's up — waiting for instructor"}),c.jsx("h2",{style:se.questionText,children:s.question}),c.jsx("div",{style:se.optionGrid,children:s.options.map((Y,X)=>{const et=I===X,Ee=s.correctIndex===X,Be=Object.values(s.responses||{}).filter(U=>U===X).length,R=P>0?Math.round(Be/P*100):0;return c.jsxs("button",{style:{...se.optionBtn,...et?se.optionSelected:{},...pe&&Ee?se.optionCorrect:{},...b||S?{cursor:"default"}:{}},onClick:()=>p(X),disabled:b||S,children:[c.jsx("span",{style:se.optionLetter,children:String.fromCharCode(65+X)}),c.jsx("span",{style:{flex:1,textAlign:"left"},children:Y}),z&&c.jsxs("span",{style:se.optionPct,children:[R,"%"]}),z&&c.jsx("div",{style:{...se.optionBar,width:`${R}%`,background:pe&&Ee?"rgba(22,163,74,0.15)":"rgba(37,99,235,0.1)"}})]},X)})}),!S&&!u&&!b&&c.jsx("button",{className:"btn btn-primary",style:{width:"100%",justifyContent:"center",padding:"0.85rem",fontSize:"1rem",marginTop:"0.5rem"},onClick:m,disabled:l===null,children:"Submit Answer"}),(u||S)&&!b&&c.jsx("div",{style:se.submittedBadge,children:"✓ Answer submitted"}),b&&!S&&!u&&c.jsx("div",{style:{...se.submittedBadge,background:"#fef9c3",color:"#854d0e",borderColor:"#fef08a"},children:"⏰ Time's up — no answer recorded"}),b&&(S||u)&&c.jsx("div",{style:se.submittedBadge,children:"✓ Answer submitted — waiting for instructor"})]})]}):c.jsx("div",{style:se.center,children:c.jsxs("div",{style:se.joinCard,className:"fade-up",children:[c.jsxs("div",{style:se.joinLogo,children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsx("h1",{style:{fontSize:"1.8rem",marginBottom:"0.25rem"},children:"Join Session"}),c.jsx("p",{style:{color:"var(--muted)",marginBottom:"1.5rem"},children:"Enter your name to start answering polls"}),c.jsxs("form",{onSubmit:g,style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[c.jsx("input",{className:"input",placeholder:"Your first name",value:e,onChange:Y=>n(Y.target.value),autoFocus:!0,style:{fontSize:"1.1rem",textAlign:"center"},required:!0}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{justifyContent:"center",padding:"0.75rem"},children:"Join →"})]}),c.jsx("button",{style:se.backLink,onClick:()=>t("/"),children:"← Back"})]})})}const se={center:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"var(--paper)"},joinCard:{background:"white",borderRadius:16,border:"1px solid var(--border)",padding:"2.5rem 2rem",maxWidth:380,width:"100%",textAlign:"center",boxShadow:"var(--shadow)"},joinLogo:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem",marginBottom:"1.5rem",display:"block"},backLink:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",marginTop:"1rem",fontSize:"0.85rem",display:"block",textAlign:"center"},waitCard:{display:"flex",flexDirection:"column",alignItems:"center",gap:"0.75rem",background:"white",borderRadius:16,border:"1px solid var(--border)",padding:"3rem 2rem",maxWidth:380,width:"100%",textAlign:"center",boxShadow:"var(--shadow)"},pulse:{width:16,height:16,borderRadius:"50%",background:"var(--accent2)",boxShadow:"0 0 0 0 rgba(37,99,235,0.4)",animation:"pulse-ring 1.5s ease-out infinite"},pollPage:{minHeight:"100vh",background:"var(--paper)",display:"flex",flexDirection:"column"},pollHeader:{padding:"1rem 1.5rem",borderBottom:"1px solid var(--border)",display:"flex",justifyContent:"space-between",alignItems:"center",background:"white"},pollContent:{maxWidth:620,margin:"0 auto",padding:"2rem 1rem",width:"100%"},timerBar:{height:6,background:"var(--cream)",borderRadius:3,overflow:"hidden",marginBottom:"0.4rem"},timerFill:{height:"100%",borderRadius:3,transition:"width 0.5s linear, background 0.5s"},timerLabel:{color:"var(--muted)",fontSize:"0.82rem",marginBottom:"1.5rem"},stoppedBanner:{background:"#fef9c3",color:"#854d0e",border:"1px solid #fef08a",borderRadius:8,padding:"0.6rem 1rem",fontSize:"0.9rem",marginBottom:"1.5rem",textAlign:"center"},questionText:{fontFamily:"var(--font-display)",fontSize:"clamp(1.2rem, 3vw, 1.6rem)",lineHeight:1.25,marginBottom:"1.25rem"},optionGrid:{display:"flex",flexDirection:"column",gap:"0.6rem"},optionBtn:{position:"relative",overflow:"hidden",display:"flex",alignItems:"center",gap:"0.75rem",padding:"0.9rem 1rem",borderRadius:10,border:"2px solid var(--border)",background:"white",cursor:"pointer",transition:"all 0.15s",textAlign:"left",fontFamily:"var(--font-body)",fontSize:"0.95rem"},optionSelected:{borderColor:"var(--accent2)",background:"#eff6ff"},optionCorrect:{borderColor:"var(--success)",background:"#f0fdf4"},optionLetter:{width:28,height:28,borderRadius:"50%",background:"var(--cream)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"0.8rem",fontWeight:700,flexShrink:0},optionPct:{color:"var(--muted)",fontSize:"0.82rem",fontWeight:600,flexShrink:0,zIndex:1},optionBar:{position:"absolute",left:0,top:0,height:"100%",transition:"width 0.4s ease",zIndex:0,pointerEvents:"none"},submittedBadge:{marginTop:"1rem",padding:"0.75rem",borderRadius:8,background:"#f0fdf4",color:"var(--success)",textAlign:"center",fontWeight:500,fontSize:"0.9rem",border:"1px solid #bbf7d0"}};function U_(t,e={}){const{duration:n=60,resultPolicy:r="on_submit",correctPolicy:i="with_results"}=e,s=t.split(/^---$/m).map(l=>l.trim()).filter(Boolean),o=[];for(const l of s){const a=l.split(` `);let u="",h=[],d=null,f=n,v=r,w=i,_=0;for(;_=a.length)){for(u=a[_].replace(/^Q:\s*/i,"").trim(),_++;_{const r=[];return n.duration!==e.duration&&r.push(`duration: ${n.duration}`),n.resultPolicy!==e.resultPolicy&&r.push(`results: ${n.resultPolicy}`),n.correctPolicy!==e.correctPolicy&&r.push(`correct: ${n.correctPolicy}`),r.push(`Q: ${n.question}`),r.push(""),n.options.forEach((i,s)=>{const o=n.correctIndex===s?"* ":" ";r.push(`${o}${String.fromCharCode(65+s)}. ${i}`)}),r.join(` `)}).join(` --- -`)}const _b=[{value:"on_submit",label:"After they submit"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}],wb=[{value:"with_results",label:"With results"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}];function Sb(){const{id:t}=HS(),e=Sr(),[n,r]=C.useState(null),[i,s]=C.useState([]),[o,l]=C.useState(0),[a,u]=C.useState("form"),[h,d]=C.useState(""),[f,v]=C.useState(!1),[w,_]=C.useState(""),[E,g]=C.useState(!1),[p,m]=C.useState(!1),[S,I]=C.useState("");C.useEffect(()=>(localStorage.getItem("role")!=="teacher"&&e("/"),D_(t,y=>{y&&(r(y),s(y.polls||[]),I(y.name||""))})),[t]),C.useEffect(()=>{a==="text"&&n&&(d(yb(i,n.defaults||{})),v(!1),_(""))},[a]);function P(y){const x=(n==null?void 0:n.defaults)||{};return{...y,duration:y.duration??x.duration??60,resultPolicy:y.resultPolicy??x.resultPolicy??"on_submit",correctPolicy:y.correctPolicy??x.correctPolicy??"with_results"}}function b(y,x){s(i.map((T,O)=>O===o?{...T,[y]:x}:T))}function A(y,x){const T=P(i[o]).options.map((O,K)=>K===y?x:O);b("options",T)}function q(){const y=[...i[o].options||[],""];y.length<=6&&b("options",y)}function z(y){const x=i[o],T=x.options.filter((K,tt)=>tt!==y);if(T.length<2)return;let O=x.correctIndex;O===y?O=null:O>y&&(O=O-1),s(i.map((K,tt)=>tt===o?{...K,options:T,correctIndex:O}:K))}function pe(){const y=[...i,{question:"",options:["",""],correctIndex:null}];s(y),l(y.length-1)}function D(y){if(i.length<=1)return;const x=i.filter((T,O)=>O!==y);s(x),l(Math.min(y,x.length-1))}function Y(y,x){const T=y+x;if(T<0||T>=i.length)return;const O=[...i];[O[y],O[T]]=[O[T],O[y]],s(O),l(T)}function X(){_("");try{const y=U_(h,n.defaults||{});if(y.length===0){_("No polls found. Check your formatting.");return}s(y),v(!1),u("form"),l(0)}catch(y){_(y.message)}}async function et(){await Lo(t,{polls:i}),g(!0),setTimeout(()=>g(!1),2e3)}async function Ee(){await Lo(t,{name:S.trim()}),m(!1)}async function Be(){if(!i||i.length===0){alert("No polls in this set.");return}await Lo(t,{polls:i});const y=n.defaults||{},x=i[0];await L_(n.id,n.name,i.length),await Pl({question:x.question,options:x.options,correctIndex:x.correctIndex??null,duration:x.duration??y.duration??60,resultPolicy:x.resultPolicy??y.resultPolicy??"on_submit",correctPolicy:x.correctPolicy??y.correctPolicy??"with_results"}),e("/teacher")}if(!n)return c.jsx("div",{style:{padding:"2rem",textAlign:"center",color:"var(--muted)"},children:"Loading…"});const R=i[o]?P(i[o]):null,U=n.defaults||{};return c.jsxs("div",{style:Z.page,children:[c.jsxs("header",{style:Z.header,children:[c.jsx("button",{style:Z.back,onClick:()=>e("/pollsets"),children:"← Poll Sets"}),c.jsx("div",{style:Z.titleArea,children:p?c.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[c.jsx("input",{className:"input",value:S,onChange:y=>I(y.target.value),style:{fontSize:"1rem",padding:"0.4rem 0.6rem"},autoFocus:!0,onKeyDown:y=>{y.key==="Enter"&&Ee(),y.key==="Escape"&&m(!1)}}),c.jsx("button",{className:"btn btn-primary",style:{padding:"0.4rem 0.8rem",fontSize:"0.85rem"},onClick:Ee,children:"Save"}),c.jsx("button",{className:"btn btn-secondary",style:{padding:"0.4rem 0.8rem",fontSize:"0.85rem"},onClick:()=>m(!1),children:"Cancel"})]}):c.jsxs("span",{style:Z.title,onClick:()=>m(!0),title:"Click to rename",children:[n.name," ✎"]})}),c.jsxs("div",{style:Z.viewToggle,children:[c.jsx("button",{style:{...Z.toggleBtn,...a==="form"?Z.toggleActive:{}},onClick:()=>u("form"),children:"Form view"}),c.jsx("button",{style:{...Z.toggleBtn,...a==="text"?Z.toggleActive:{}},onClick:()=>u("text"),children:"Text view"})]}),c.jsx("button",{className:"btn btn-secondary",onClick:et,style:{background:E?"#dcfce7":void 0,borderColor:E?"var(--success)":void 0,color:E?"var(--success)":void 0},children:E?"✓ Saved":"Save Changes"}),c.jsx("button",{className:"btn btn-primary",onClick:Be,children:"Launch →"})]}),c.jsxs("div",{style:Z.body,children:[a==="form"&&c.jsxs(c.Fragment,{children:[c.jsxs("aside",{style:Z.pollList,children:[c.jsxs("div",{style:Z.pollListHeader,children:[c.jsxs("span",{style:{fontSize:"0.8rem",color:"var(--muted)",fontWeight:600},children:[i.length," POLL",i.length!==1?"S":""]}),c.jsx("button",{className:"btn btn-ghost",style:{fontSize:"0.78rem",padding:"0.3rem 0.6rem"},onClick:pe,children:"+ Add"})]}),i.map((y,x)=>c.jsxs("div",{style:{...Z.pollItem,...o===x?Z.pollItemActive:{}},onClick:()=>l(x),children:[c.jsx("span",{style:Z.pollItemNum,children:x+1}),c.jsx("span",{style:Z.pollItemQ,children:y.question||c.jsx("em",{style:{color:"var(--muted)"},children:"Untitled"})}),c.jsxs("div",{style:Z.pollItemActions,children:[c.jsx("button",{style:Z.microBtn,onClick:T=>{T.stopPropagation(),Y(x,-1)},disabled:x===0,children:"↑"}),c.jsx("button",{style:Z.microBtn,onClick:T=>{T.stopPropagation(),Y(x,1)},disabled:x===i.length-1,children:"↓"}),c.jsx("button",{style:Z.microBtn,onClick:T=>{T.stopPropagation(),D(x)},disabled:i.length<=1,children:"✕"})]})]},x))]}),c.jsx("main",{style:Z.editor,children:R&&c.jsxs("div",{style:Z.editorInner,className:"fade-up",children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Question"}),c.jsx("textarea",{className:"input",rows:3,placeholder:"Enter your question…",value:i[o].question,onChange:y=>b("question",y.target.value),style:{resize:"vertical",width:"100%"}})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Answer Options"}),c.jsx("p",{style:Z.hint,children:"Click a letter circle to mark the correct answer (optional)"}),c.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:R.options.map((y,x)=>c.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[c.jsx("button",{type:"button",style:{...Z.correctBtn,...i[o].correctIndex===x?Z.correctBtnActive:{}},onClick:()=>b("correctIndex",i[o].correctIndex===x?null:x),children:i[o].correctIndex===x?"✓":String.fromCharCode(65+x)}),c.jsx("input",{className:"input",style:{flex:1},placeholder:`Option ${String.fromCharCode(65+x)}`,value:y,onChange:T=>A(x,T.target.value)}),c.jsx("button",{style:Z.removeBtn,onClick:()=>z(x),disabled:R.options.length<=2,children:"✕"})]},x))}),R.options.length<6&&c.jsx("button",{className:"btn btn-ghost",style:{marginTop:"0.5rem",fontSize:"0.85rem"},onClick:q,children:"+ Add option"})]}),c.jsxs("div",{style:Z.overridesBox,children:[c.jsxs("label",{className:"label",children:["Per-poll overrides",c.jsx("span",{style:{color:"var(--muted)",textTransform:"none",letterSpacing:0,marginLeft:"0.5rem",fontWeight:400,fontSize:"0.78rem"},children:"(leave blank to use set defaults)"})]}),c.jsxs("div",{style:Z.overridesRow,children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Duration (s)"}),c.jsx("input",{className:"input",type:"number",min:10,max:300,placeholder:`default: ${U.duration??60}`,value:i[o].duration??"",onChange:y=>b("duration",y.target.value===""?null:Number(y.target.value)),style:{width:100}})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Show results"}),c.jsxs("select",{className:"input",value:i[o].resultPolicy??"",onChange:y=>b("resultPolicy",y.target.value||null),children:[c.jsxs("option",{value:"",children:["Set default (",U.resultPolicy??"on_submit",")"]}),_b.map(y=>c.jsx("option",{value:y.value,children:y.label},y.value))]})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Reveal answer"}),c.jsxs("select",{className:"input",value:i[o].correctPolicy??"",onChange:y=>b("correctPolicy",y.target.value||null),children:[c.jsxs("option",{value:"",children:["Set default (",U.correctPolicy??"with_results",")"]}),wb.map(y=>c.jsx("option",{value:y.value,children:y.label},y.value))]})]})]})]})]})})]}),a==="text"&&c.jsxs("div",{style:Z.textView,children:[c.jsxs("p",{style:Z.textHint,children:["Edit all polls as plain text. Use ",c.jsx("code",{children:"---"})," to separate polls. Per-poll overrides: ",c.jsx("code",{children:"duration: 90"}),", ",c.jsx("code",{children:"results: manual"}),", ",c.jsx("code",{children:"correct: never"}),". Click ",c.jsx("strong",{children:"Apply Changes"})," to update the form view, then ",c.jsx("strong",{children:"Save Changes"})," to persist."]}),c.jsx("textarea",{className:"input",value:h,onChange:y=>{d(y.target.value),v(!0),_("")},style:{fontFamily:"monospace",fontSize:"0.88rem",minHeight:"60vh",resize:"vertical",width:"100%"}}),w&&c.jsx("p",{style:Z.err,children:w}),c.jsxs("div",{style:{display:"flex",gap:"0.75rem",marginTop:"0.75rem"},children:[c.jsx("button",{className:"btn btn-primary",onClick:X,disabled:!f,children:"Apply Changes →"}),c.jsx("button",{className:"btn btn-secondary",onClick:()=>{u("form"),_("")},children:"Cancel"})]})]})]})]})}const Z={page:{minHeight:"100vh",background:"var(--paper)",display:"flex",flexDirection:"column"},header:{padding:"1rem 1.5rem",borderBottom:"1px solid var(--border)",background:"white",display:"flex",alignItems:"center",gap:"0.75rem",flexWrap:"wrap"},back:{background:"none",border:"none",color:"var(--accent2)",cursor:"pointer",fontSize:"0.9rem"},titleArea:{flex:1},title:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.15rem",cursor:"pointer",borderBottom:"1px dashed var(--border)"},viewToggle:{display:"flex",gap:"0.25rem",background:"var(--cream)",borderRadius:8,padding:"0.25rem"},toggleBtn:{background:"none",border:"none",padding:"0.35rem 0.85rem",borderRadius:6,cursor:"pointer",fontSize:"0.85rem",color:"var(--muted)"},toggleActive:{background:"white",color:"var(--ink)",fontWeight:600,boxShadow:"0 1px 3px rgba(0,0,0,0.1)"},body:{display:"flex",flex:1,overflow:"hidden"},pollList:{width:220,borderRight:"1px solid var(--border)",background:"white",display:"flex",flexDirection:"column",overflowY:"auto"},pollListHeader:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"0.75rem 1rem",borderBottom:"1px solid var(--border)"},pollItem:{display:"flex",alignItems:"flex-start",gap:"0.5rem",padding:"0.75rem 1rem",cursor:"pointer",borderBottom:"1px solid var(--cream)",transition:"background 0.1s"},pollItemActive:{background:"#eff6ff",borderLeft:"3px solid var(--accent2)"},pollItemNum:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"0.8rem",color:"var(--muted)",flexShrink:0,marginTop:"0.1rem"},pollItemQ:{fontSize:"0.82rem",flex:1,lineHeight:1.4,display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden"},pollItemActions:{display:"flex",flexDirection:"column",gap:"0.15rem",flexShrink:0},microBtn:{background:"none",border:"none",cursor:"pointer",fontSize:"0.7rem",color:"var(--muted)",padding:"0.1rem 0.2rem",lineHeight:1},editor:{flex:1,overflowY:"auto",padding:"1.5rem"},editorInner:{maxWidth:"100%",display:"flex",flexDirection:"column",gap:"1.25rem"},hint:{fontSize:"0.82rem",color:"var(--muted)",marginBottom:"0.5rem"},overridesBox:{background:"var(--cream)",borderRadius:10,padding:"1rem",display:"flex",flexDirection:"column",gap:"0.75rem"},overridesRow:{display:"flex",gap:"1rem",flexWrap:"wrap",alignItems:"flex-end"},correctBtn:{width:32,height:32,borderRadius:"50%",border:"2px solid var(--border)",background:"var(--cream)",cursor:"pointer",fontWeight:700,fontSize:"0.8rem",flexShrink:0,transition:"all 0.15s"},correctBtnActive:{background:"var(--success)",color:"white",borderColor:"var(--success)"},removeBtn:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",fontSize:"0.9rem",padding:"0.25rem",borderRadius:4},textView:{flex:1,padding:"1.5rem",display:"flex",flexDirection:"column",gap:"0.75rem"},textHint:{fontSize:"0.85rem",color:"var(--muted)",lineHeight:1.6},err:{color:"var(--accent)",fontSize:"0.85rem"}},$p={duration:60,resultPolicy:"on_submit",correctPolicy:"with_results"},Vp=[{value:"on_submit",label:"After they submit"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}],Hp=[{value:"with_results",label:"With results"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}];function Cb(){const t=Sr(),[e,n]=C.useState([]),[r,i]=C.useState("list"),[s,o]=C.useState(null),[l,a]=C.useState(!1),[u,h]=C.useState(""),[d,f]=C.useState(""),[v,w]=C.useState($p),[_,E]=C.useState("text"),[g,p]=C.useState(""),[m,S]=C.useState(null),[I,P]=C.useState("");C.useEffect(()=>(localStorage.getItem("role")!=="teacher"&&t("/"),A_(n)),[]);function b(){f(""),w($p),E("text"),p(""),S(null),P(""),h("")}function A(){P("");try{const D=U_(g,v);if(D.length===0){P("No polls found. Check your formatting.");return}S(D)}catch(D){P(D.message)}}async function q(){if(h(""),!d.trim()){h("Please enter a set name.");return}if(!m||m.length===0){h("Preview your polls first.");return}a(!0);try{const D=await _c({name:d.trim(),defaults:v,polls:m});b(),i("list"),t(`/pollsets/${D}`)}catch(D){h("Error saving: "+D.message)}finally{a(!1)}}async function z(){if(h(""),!d.trim()){h("Please enter a set name.");return}a(!0);try{const D=await _c({name:d.trim(),defaults:v,polls:[]});b(),i("list"),t(`/pollsets/${D}`)}catch(D){h("Error saving: "+D.message)}finally{a(!1)}}function pe(D){O_(D),o(null)}return c.jsxs("div",{style:Q.page,children:[c.jsxs("header",{style:Q.header,children:[c.jsx("button",{style:Q.back,onClick:()=>t("/teacher"),children:"← Dashboard"}),c.jsx("span",{style:Q.title,children:"Poll Sets"}),r==="list"&&c.jsx("button",{className:"btn btn-primary",onClick:()=>i("create"),children:"+ New Set"}),r==="create"&&c.jsx("button",{className:"btn btn-secondary",onClick:()=>{i("list"),b()},children:"Cancel"})]}),c.jsxs("main",{style:Q.main,children:[r==="list"&&c.jsxs("div",{className:"fade-up",children:[e.length===0&&c.jsxs("div",{style:Q.empty,children:[c.jsx("span",{style:{fontSize:"2.5rem"},children:"📚"}),c.jsx("p",{children:"No poll sets yet."}),c.jsx("button",{className:"btn btn-primary",onClick:()=>i("create"),children:"Create your first set →"})]}),e.map(D=>{const Y=s===D.id;return c.jsxs("div",{style:Q.setCard,children:[c.jsxs("button",{style:Q.setCardBtn,onClick:()=>t(`/pollsets/${D.id}`),children:[c.jsxs("div",{children:[c.jsx("div",{style:Q.setName,children:D.name}),c.jsxs("div",{style:Q.setMeta,children:[(D.polls||[]).length," poll",(D.polls||[]).length!==1?"s":""," · Created ",new Date(D.createdAt).toLocaleDateString()]})]}),c.jsx("span",{style:{color:"var(--muted)"},children:"→"})]}),c.jsx("div",{style:Q.setActions,children:Y?c.jsxs("div",{style:Q.confirmRow,children:[c.jsx("span",{style:Q.confirmText,children:"Delete?"}),c.jsx("button",{className:"btn btn-primary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem",background:"#dc2626"},onClick:()=>pe(D.id),children:"Yes"}),c.jsx("button",{className:"btn btn-secondary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem"},onClick:()=>o(null),children:"Cancel"})]}):c.jsx("button",{style:Q.deleteBtn,onClick:()=>o(D.id),children:"🗑"})})]},D.id)})]}),r==="create"&&c.jsxs("div",{className:"fade-up",style:Q.createForm,children:[c.jsx("h2",{style:Q.sectionTitle,children:"New Poll Set"}),c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Set Name"}),c.jsx("input",{className:"input",placeholder:"e.g. Chapter 5 Review",value:d,onChange:D=>f(D.target.value),autoFocus:!0})]}),c.jsxs("div",{style:Q.defaultsBox,children:[c.jsx("label",{className:"label",children:"Default settings for all polls in this set"}),c.jsxs("div",{style:Q.defaultsRow,children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Duration (seconds)"}),c.jsx("input",{className:"input",type:"number",min:10,max:300,value:v.duration,onChange:D=>w({...v,duration:Number(D.target.value)}),style:{width:100}})]}),c.jsxs("div",{style:{flex:1},children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Show results to students"}),c.jsx("select",{className:"input",value:v.resultPolicy,onChange:D=>w({...v,resultPolicy:D.target.value}),children:Vp.map(D=>c.jsx("option",{value:D.value,children:D.label},D.value))})]}),c.jsxs("div",{style:{flex:1},children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Reveal correct answer"}),c.jsx("select",{className:"input",value:v.correctPolicy,onChange:D=>w({...v,correctPolicy:D.target.value}),children:Hp.map(D=>c.jsx("option",{value:D.value,children:D.label},D.value))})]})]})]}),c.jsxs("div",{children:[c.jsxs("div",{style:Q.modeTabs,children:[c.jsx("button",{style:{...Q.modeTab,..._==="text"?Q.modeTabActive:{}},onClick:()=>E("text"),children:"Paste text"}),c.jsx("button",{style:{...Q.modeTab,..._==="manual"?Q.modeTabActive:{}},onClick:()=>E("manual"),children:"Build manually"})]}),_==="text"&&c.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[c.jsx("textarea",{className:"input",rows:14,placeholder:`Q: What is photosynthesis? +`)}const _b=[{value:"on_submit",label:"After they submit"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}],wb=[{value:"with_results",label:"With results"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}];function Sb(){const{id:t}=HS(),e=Sr(),[n,r]=C.useState(null),[i,s]=C.useState([]),[o,l]=C.useState(0),[a,u]=C.useState("form"),[h,d]=C.useState(""),[f,v]=C.useState(!1),[w,_]=C.useState(""),[E,g]=C.useState(!1),[p,m]=C.useState(!1),[S,I]=C.useState("");C.useEffect(()=>(localStorage.getItem("role")!=="instructor"&&e("/"),D_(t,y=>{y&&(r(y),s(y.polls||[]),I(y.name||""))})),[t]),C.useEffect(()=>{a==="text"&&n&&(d(yb(i,n.defaults||{})),v(!1),_(""))},[a]);function P(y){const x=(n==null?void 0:n.defaults)||{};return{...y,duration:y.duration??x.duration??60,resultPolicy:y.resultPolicy??x.resultPolicy??"on_submit",correctPolicy:y.correctPolicy??x.correctPolicy??"with_results"}}function b(y,x){s(i.map((T,O)=>O===o?{...T,[y]:x}:T))}function A(y,x){const T=P(i[o]).options.map((O,K)=>K===y?x:O);b("options",T)}function q(){const y=[...i[o].options||[],""];y.length<=6&&b("options",y)}function z(y){const x=i[o],T=x.options.filter((K,tt)=>tt!==y);if(T.length<2)return;let O=x.correctIndex;O===y?O=null:O>y&&(O=O-1),s(i.map((K,tt)=>tt===o?{...K,options:T,correctIndex:O}:K))}function pe(){const y=[...i,{question:"",options:["",""],correctIndex:null}];s(y),l(y.length-1)}function D(y){if(i.length<=1)return;const x=i.filter((T,O)=>O!==y);s(x),l(Math.min(y,x.length-1))}function Y(y,x){const T=y+x;if(T<0||T>=i.length)return;const O=[...i];[O[y],O[T]]=[O[T],O[y]],s(O),l(T)}function X(){_("");try{const y=U_(h,n.defaults||{});if(y.length===0){_("No polls found. Check your formatting.");return}s(y),v(!1),u("form"),l(0)}catch(y){_(y.message)}}async function et(){await Lo(t,{polls:i}),g(!0),setTimeout(()=>g(!1),2e3)}async function Ee(){await Lo(t,{name:S.trim()}),m(!1)}async function Be(){if(!i||i.length===0){alert("No polls in this set.");return}await Lo(t,{polls:i});const y=n.defaults||{},x=i[0];await L_(n.id,n.name,i.length),await Pl({question:x.question,options:x.options,correctIndex:x.correctIndex??null,duration:x.duration??y.duration??60,resultPolicy:x.resultPolicy??y.resultPolicy??"on_submit",correctPolicy:x.correctPolicy??y.correctPolicy??"with_results"}),e("/instructor")}if(!n)return c.jsx("div",{style:{padding:"2rem",textAlign:"center",color:"var(--muted)"},children:"Loading…"});const R=i[o]?P(i[o]):null,U=n.defaults||{};return c.jsxs("div",{style:Z.page,children:[c.jsxs("header",{style:Z.header,children:[c.jsx("button",{style:Z.back,onClick:()=>e("/pollsets"),children:"← Poll Sets"}),c.jsx("div",{style:Z.titleArea,children:p?c.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[c.jsx("input",{className:"input",value:S,onChange:y=>I(y.target.value),style:{fontSize:"1rem",padding:"0.4rem 0.6rem"},autoFocus:!0,onKeyDown:y=>{y.key==="Enter"&&Ee(),y.key==="Escape"&&m(!1)}}),c.jsx("button",{className:"btn btn-primary",style:{padding:"0.4rem 0.8rem",fontSize:"0.85rem"},onClick:Ee,children:"Save"}),c.jsx("button",{className:"btn btn-secondary",style:{padding:"0.4rem 0.8rem",fontSize:"0.85rem"},onClick:()=>m(!1),children:"Cancel"})]}):c.jsxs("span",{style:Z.title,onClick:()=>m(!0),title:"Click to rename",children:[n.name," ✎"]})}),c.jsxs("div",{style:Z.viewToggle,children:[c.jsx("button",{style:{...Z.toggleBtn,...a==="form"?Z.toggleActive:{}},onClick:()=>u("form"),children:"Form view"}),c.jsx("button",{style:{...Z.toggleBtn,...a==="text"?Z.toggleActive:{}},onClick:()=>u("text"),children:"Text view"})]}),c.jsx("button",{className:"btn btn-secondary",onClick:et,style:{background:E?"#dcfce7":void 0,borderColor:E?"var(--success)":void 0,color:E?"var(--success)":void 0},children:E?"✓ Saved":"Save Changes"}),c.jsx("button",{className:"btn btn-primary",onClick:Be,children:"Launch →"})]}),c.jsxs("div",{style:Z.body,children:[a==="form"&&c.jsxs(c.Fragment,{children:[c.jsxs("aside",{style:Z.pollList,children:[c.jsxs("div",{style:Z.pollListHeader,children:[c.jsxs("span",{style:{fontSize:"0.8rem",color:"var(--muted)",fontWeight:600},children:[i.length," POLL",i.length!==1?"S":""]}),c.jsx("button",{className:"btn btn-ghost",style:{fontSize:"0.78rem",padding:"0.3rem 0.6rem"},onClick:pe,children:"+ Add"})]}),i.map((y,x)=>c.jsxs("div",{style:{...Z.pollItem,...o===x?Z.pollItemActive:{}},onClick:()=>l(x),children:[c.jsx("span",{style:Z.pollItemNum,children:x+1}),c.jsx("span",{style:Z.pollItemQ,children:y.question||c.jsx("em",{style:{color:"var(--muted)"},children:"Untitled"})}),c.jsxs("div",{style:Z.pollItemActions,children:[c.jsx("button",{style:Z.microBtn,onClick:T=>{T.stopPropagation(),Y(x,-1)},disabled:x===0,children:"↑"}),c.jsx("button",{style:Z.microBtn,onClick:T=>{T.stopPropagation(),Y(x,1)},disabled:x===i.length-1,children:"↓"}),c.jsx("button",{style:Z.microBtn,onClick:T=>{T.stopPropagation(),D(x)},disabled:i.length<=1,children:"✕"})]})]},x))]}),c.jsx("main",{style:Z.editor,children:R&&c.jsxs("div",{style:Z.editorInner,className:"fade-up",children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Question"}),c.jsx("textarea",{className:"input",rows:3,placeholder:"Enter your question…",value:i[o].question,onChange:y=>b("question",y.target.value),style:{resize:"vertical",width:"100%"}})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Answer Options"}),c.jsx("p",{style:Z.hint,children:"Click a letter circle to mark the correct answer (optional)"}),c.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:R.options.map((y,x)=>c.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[c.jsx("button",{type:"button",style:{...Z.correctBtn,...i[o].correctIndex===x?Z.correctBtnActive:{}},onClick:()=>b("correctIndex",i[o].correctIndex===x?null:x),children:i[o].correctIndex===x?"✓":String.fromCharCode(65+x)}),c.jsx("input",{className:"input",style:{flex:1},placeholder:`Option ${String.fromCharCode(65+x)}`,value:y,onChange:T=>A(x,T.target.value)}),c.jsx("button",{style:Z.removeBtn,onClick:()=>z(x),disabled:R.options.length<=2,children:"✕"})]},x))}),R.options.length<6&&c.jsx("button",{className:"btn btn-ghost",style:{marginTop:"0.5rem",fontSize:"0.85rem"},onClick:q,children:"+ Add option"})]}),c.jsxs("div",{style:Z.overridesBox,children:[c.jsxs("label",{className:"label",children:["Per-poll overrides",c.jsx("span",{style:{color:"var(--muted)",textTransform:"none",letterSpacing:0,marginLeft:"0.5rem",fontWeight:400,fontSize:"0.78rem"},children:"(leave blank to use set defaults)"})]}),c.jsxs("div",{style:Z.overridesRow,children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Duration (s)"}),c.jsx("input",{className:"input",type:"number",min:10,max:300,placeholder:`default: ${U.duration??60}`,value:i[o].duration??"",onChange:y=>b("duration",y.target.value===""?null:Number(y.target.value)),style:{width:100}})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Show results"}),c.jsxs("select",{className:"input",value:i[o].resultPolicy??"",onChange:y=>b("resultPolicy",y.target.value||null),children:[c.jsxs("option",{value:"",children:["Set default (",U.resultPolicy??"on_submit",")"]}),_b.map(y=>c.jsx("option",{value:y.value,children:y.label},y.value))]})]}),c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Reveal answer"}),c.jsxs("select",{className:"input",value:i[o].correctPolicy??"",onChange:y=>b("correctPolicy",y.target.value||null),children:[c.jsxs("option",{value:"",children:["Set default (",U.correctPolicy??"with_results",")"]}),wb.map(y=>c.jsx("option",{value:y.value,children:y.label},y.value))]})]})]})]})]})})]}),a==="text"&&c.jsxs("div",{style:Z.textView,children:[c.jsxs("p",{style:Z.textHint,children:["Edit all polls as plain text. Use ",c.jsx("code",{children:"---"})," to separate polls. Per-poll overrides: ",c.jsx("code",{children:"duration: 90"}),", ",c.jsx("code",{children:"results: manual"}),", ",c.jsx("code",{children:"correct: never"}),". Click ",c.jsx("strong",{children:"Apply Changes"})," to update the form view, then ",c.jsx("strong",{children:"Save Changes"})," to persist."]}),c.jsx("textarea",{className:"input",value:h,onChange:y=>{d(y.target.value),v(!0),_("")},style:{fontFamily:"monospace",fontSize:"0.88rem",minHeight:"60vh",resize:"vertical",width:"100%"}}),w&&c.jsx("p",{style:Z.err,children:w}),c.jsxs("div",{style:{display:"flex",gap:"0.75rem",marginTop:"0.75rem"},children:[c.jsx("button",{className:"btn btn-primary",onClick:X,disabled:!f,children:"Apply Changes →"}),c.jsx("button",{className:"btn btn-secondary",onClick:()=>{u("form"),_("")},children:"Cancel"})]})]})]})]})}const Z={page:{minHeight:"100vh",background:"var(--paper)",display:"flex",flexDirection:"column"},header:{padding:"1rem 1.5rem",borderBottom:"1px solid var(--border)",background:"white",display:"flex",alignItems:"center",gap:"0.75rem",flexWrap:"wrap"},back:{background:"none",border:"none",color:"var(--accent2)",cursor:"pointer",fontSize:"0.9rem"},titleArea:{flex:1},title:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.15rem",cursor:"pointer",borderBottom:"1px dashed var(--border)"},viewToggle:{display:"flex",gap:"0.25rem",background:"var(--cream)",borderRadius:8,padding:"0.25rem"},toggleBtn:{background:"none",border:"none",padding:"0.35rem 0.85rem",borderRadius:6,cursor:"pointer",fontSize:"0.85rem",color:"var(--muted)"},toggleActive:{background:"white",color:"var(--ink)",fontWeight:600,boxShadow:"0 1px 3px rgba(0,0,0,0.1)"},body:{display:"flex",flex:1,overflow:"hidden"},pollList:{width:220,borderRight:"1px solid var(--border)",background:"white",display:"flex",flexDirection:"column",overflowY:"auto"},pollListHeader:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"0.75rem 1rem",borderBottom:"1px solid var(--border)"},pollItem:{display:"flex",alignItems:"flex-start",gap:"0.5rem",padding:"0.75rem 1rem",cursor:"pointer",borderBottom:"1px solid var(--cream)",transition:"background 0.1s"},pollItemActive:{background:"#eff6ff",borderLeft:"3px solid var(--accent2)"},pollItemNum:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"0.8rem",color:"var(--muted)",flexShrink:0,marginTop:"0.1rem"},pollItemQ:{fontSize:"0.82rem",flex:1,lineHeight:1.4,display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden"},pollItemActions:{display:"flex",flexDirection:"column",gap:"0.15rem",flexShrink:0},microBtn:{background:"none",border:"none",cursor:"pointer",fontSize:"0.7rem",color:"var(--muted)",padding:"0.1rem 0.2rem",lineHeight:1},editor:{flex:1,overflowY:"auto",padding:"1.5rem"},editorInner:{maxWidth:"100%",display:"flex",flexDirection:"column",gap:"1.25rem"},hint:{fontSize:"0.82rem",color:"var(--muted)",marginBottom:"0.5rem"},overridesBox:{background:"var(--cream)",borderRadius:10,padding:"1rem",display:"flex",flexDirection:"column",gap:"0.75rem"},overridesRow:{display:"flex",gap:"1rem",flexWrap:"wrap",alignItems:"flex-end"},correctBtn:{width:32,height:32,borderRadius:"50%",border:"2px solid var(--border)",background:"var(--cream)",cursor:"pointer",fontWeight:700,fontSize:"0.8rem",flexShrink:0,transition:"all 0.15s"},correctBtnActive:{background:"var(--success)",color:"white",borderColor:"var(--success)"},removeBtn:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",fontSize:"0.9rem",padding:"0.25rem",borderRadius:4},textView:{flex:1,padding:"1.5rem",display:"flex",flexDirection:"column",gap:"0.75rem"},textHint:{fontSize:"0.85rem",color:"var(--muted)",lineHeight:1.6},err:{color:"var(--accent)",fontSize:"0.85rem"}},$p={duration:60,resultPolicy:"on_submit",correctPolicy:"with_results"},Vp=[{value:"on_submit",label:"After they submit"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}],Hp=[{value:"with_results",label:"With results"},{value:"manual",label:"When I choose"},{value:"never",label:"Never"}];function Cb(){const t=Sr(),[e,n]=C.useState([]),[r,i]=C.useState("list"),[s,o]=C.useState(null),[l,a]=C.useState(!1),[u,h]=C.useState(""),[d,f]=C.useState(""),[v,w]=C.useState($p),[_,E]=C.useState("text"),[g,p]=C.useState(""),[m,S]=C.useState(null),[I,P]=C.useState("");C.useEffect(()=>(localStorage.getItem("role")!=="instructor"&&t("/"),A_(n)),[]);function b(){f(""),w($p),E("text"),p(""),S(null),P(""),h("")}function A(){P("");try{const D=U_(g,v);if(D.length===0){P("No polls found. Check your formatting.");return}S(D)}catch(D){P(D.message)}}async function q(){if(h(""),!d.trim()){h("Please enter a set name.");return}if(!m||m.length===0){h("Preview your polls first.");return}a(!0);try{const D=await _c({name:d.trim(),defaults:v,polls:m});b(),i("list"),t(`/pollsets/${D}`)}catch(D){h("Error saving: "+D.message)}finally{a(!1)}}async function z(){if(h(""),!d.trim()){h("Please enter a set name.");return}a(!0);try{const D=await _c({name:d.trim(),defaults:v,polls:[]});b(),i("list"),t(`/pollsets/${D}`)}catch(D){h("Error saving: "+D.message)}finally{a(!1)}}function pe(D){O_(D),o(null)}return c.jsxs("div",{style:Q.page,children:[c.jsxs("header",{style:Q.header,children:[c.jsx("button",{style:Q.back,onClick:()=>t("/instructor"),children:"← Dashboard"}),c.jsx("span",{style:Q.title,children:"Poll Sets"}),r==="list"&&c.jsx("button",{className:"btn btn-primary",onClick:()=>i("create"),children:"+ New Set"}),r==="create"&&c.jsx("button",{className:"btn btn-secondary",onClick:()=>{i("list"),b()},children:"Cancel"})]}),c.jsxs("main",{style:Q.main,children:[r==="list"&&c.jsxs("div",{className:"fade-up",children:[e.length===0&&c.jsxs("div",{style:Q.empty,children:[c.jsx("span",{style:{fontSize:"2.5rem"},children:"📚"}),c.jsx("p",{children:"No poll sets yet."}),c.jsx("button",{className:"btn btn-primary",onClick:()=>i("create"),children:"Create your first set →"})]}),e.map(D=>{const Y=s===D.id;return c.jsxs("div",{style:Q.setCard,children:[c.jsxs("button",{style:Q.setCardBtn,onClick:()=>t(`/pollsets/${D.id}`),children:[c.jsxs("div",{children:[c.jsx("div",{style:Q.setName,children:D.name}),c.jsxs("div",{style:Q.setMeta,children:[(D.polls||[]).length," poll",(D.polls||[]).length!==1?"s":""," · Created ",new Date(D.createdAt).toLocaleDateString()]})]}),c.jsx("span",{style:{color:"var(--muted)"},children:"→"})]}),c.jsx("div",{style:Q.setActions,children:Y?c.jsxs("div",{style:Q.confirmRow,children:[c.jsx("span",{style:Q.confirmText,children:"Delete?"}),c.jsx("button",{className:"btn btn-primary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem",background:"#dc2626"},onClick:()=>pe(D.id),children:"Yes"}),c.jsx("button",{className:"btn btn-secondary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem"},onClick:()=>o(null),children:"Cancel"})]}):c.jsx("button",{style:Q.deleteBtn,onClick:()=>o(D.id),children:"🗑"})})]},D.id)})]}),r==="create"&&c.jsxs("div",{className:"fade-up",style:Q.createForm,children:[c.jsx("h2",{style:Q.sectionTitle,children:"New Poll Set"}),c.jsxs("div",{children:[c.jsx("label",{className:"label",children:"Set Name"}),c.jsx("input",{className:"input",placeholder:"e.g. Chapter 5 Review",value:d,onChange:D=>f(D.target.value),autoFocus:!0})]}),c.jsxs("div",{style:Q.defaultsBox,children:[c.jsx("label",{className:"label",children:"Default settings for all polls in this set"}),c.jsxs("div",{style:Q.defaultsRow,children:[c.jsxs("div",{children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Duration (seconds)"}),c.jsx("input",{className:"input",type:"number",min:10,max:300,value:v.duration,onChange:D=>w({...v,duration:Number(D.target.value)}),style:{width:100}})]}),c.jsxs("div",{style:{flex:1},children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Show results to students"}),c.jsx("select",{className:"input",value:v.resultPolicy,onChange:D=>w({...v,resultPolicy:D.target.value}),children:Vp.map(D=>c.jsx("option",{value:D.value,children:D.label},D.value))})]}),c.jsxs("div",{style:{flex:1},children:[c.jsx("label",{className:"label",style:{fontSize:"0.72rem"},children:"Reveal correct answer"}),c.jsx("select",{className:"input",value:v.correctPolicy,onChange:D=>w({...v,correctPolicy:D.target.value}),children:Hp.map(D=>c.jsx("option",{value:D.value,children:D.label},D.value))})]})]})]}),c.jsxs("div",{children:[c.jsxs("div",{style:Q.modeTabs,children:[c.jsx("button",{style:{...Q.modeTab,..._==="text"?Q.modeTabActive:{}},onClick:()=>E("text"),children:"Paste text"}),c.jsx("button",{style:{...Q.modeTab,..._==="manual"?Q.modeTabActive:{}},onClick:()=>E("manual"),children:"Build manually"})]}),_==="text"&&c.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[c.jsx("textarea",{className:"input",rows:14,placeholder:`Q: What is photosynthesis? * A. Converts sunlight into energy B. Breaks down glucose @@ -2744,4 +2744,4 @@ duration: 90 D. Vacuole`,value:g,onChange:D=>{p(D.target.value),S(null),P("")},style:{fontFamily:"monospace",fontSize:"0.85rem",resize:"vertical",minHeight:"320px",width:"100%"}}),c.jsxs("div",{style:{display:"flex",gap:"0.75rem",alignItems:"center"},children:[c.jsx("button",{className:"btn btn-secondary",onClick:A,children:"Preview →"}),I&&c.jsx("span",{style:Q.err,children:I})]})]}),_==="manual"&&c.jsxs("div",{style:Q.manualBox,children:[c.jsx("p",{children:"The set will be created empty. You can add and edit polls one by one in the set detail view."}),u&&c.jsx("p",{style:Q.err,children:u}),c.jsx("button",{className:"btn btn-primary",style:{marginTop:"0.5rem"},onClick:z,disabled:l,children:l?"Creating…":"Create empty set →"})]})]}),_==="text"&&m&&c.jsxs("div",{style:Q.previewBox,children:[c.jsxs("label",{className:"label",children:["Preview — ",m.length," poll",m.length!==1?"s":""," found"]}),m.map((D,Y)=>{var X,et;return c.jsxs("div",{style:Q.previewPoll,children:[c.jsxs("div",{style:Q.previewQ,children:[Y+1,". ",D.question]}),c.jsx("div",{style:Q.previewOptions,children:D.options.map((Ee,Be)=>c.jsxs("div",{style:{...Q.previewOpt,...D.correctIndex===Be?Q.previewOptCorrect:{}},children:[D.correctIndex===Be?"✓":String.fromCharCode(65+Be),". ",Ee]},Be))}),c.jsxs("div",{style:Q.previewMeta,children:[D.duration,"s · Results: ",(X=Vp.find(Ee=>Ee.value===D.resultPolicy))==null?void 0:X.label," · Answer: ",(et=Hp.find(Ee=>Ee.value===D.correctPolicy))==null?void 0:et.label]})]},Y)}),u&&c.jsx("p",{style:Q.err,children:u}),c.jsx("button",{className:"btn btn-primary",onClick:q,disabled:l,children:l?"Saving…":"Save Set →"})]})]})]})]})}const Q={page:{minHeight:"100vh",background:"var(--paper)"},header:{padding:"1rem 1.5rem",borderBottom:"1px solid var(--border)",background:"white",display:"flex",alignItems:"center",gap:"1rem"},back:{background:"none",border:"none",color:"var(--accent2)",cursor:"pointer",fontSize:"0.9rem"},title:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.2rem",flex:1},main:{maxWidth:960,margin:"0 auto",padding:"1.5rem 1rem"},empty:{textAlign:"center",padding:"4rem 2rem",color:"var(--muted)",display:"flex",flexDirection:"column",alignItems:"center",gap:"1rem"},setCard:{background:"white",borderRadius:12,border:"1px solid var(--border)",marginBottom:"0.75rem",display:"flex",alignItems:"center",overflow:"hidden"},setCardBtn:{display:"flex",alignItems:"center",justifyContent:"space-between",flex:1,padding:"1rem",background:"none",border:"none",cursor:"pointer",textAlign:"left"},setName:{fontFamily:"var(--font-display)",fontWeight:600,fontSize:"1rem"},setMeta:{color:"var(--muted)",fontSize:"0.8rem",marginTop:"0.2rem"},setActions:{padding:"0 0.75rem",display:"flex",alignItems:"center",gap:"0.4rem"},deleteBtn:{background:"none",border:"none",cursor:"pointer",fontSize:"1.1rem",padding:"0.25rem 0.4rem",borderRadius:6,opacity:.5},confirmRow:{display:"flex",alignItems:"center",gap:"0.4rem"},confirmText:{fontSize:"0.82rem",color:"var(--muted)",whiteSpace:"nowrap"},createForm:{display:"flex",flexDirection:"column",gap:"1.25rem"},sectionTitle:{fontSize:"1.4rem"},defaultsBox:{background:"white",borderRadius:12,border:"1px solid var(--border)",padding:"1rem",display:"flex",flexDirection:"column",gap:"0.75rem"},defaultsRow:{display:"flex",gap:"0.75rem",flexWrap:"wrap",alignItems:"flex-end"},modeTabs:{display:"flex",gap:"0.25rem",background:"var(--cream)",borderRadius:8,padding:"0.25rem",marginBottom:"0.75rem",width:"fit-content"},modeTab:{background:"none",border:"none",padding:"0.35rem 0.85rem",borderRadius:6,cursor:"pointer",fontSize:"0.9rem",color:"var(--muted)"},modeTabActive:{background:"white",color:"var(--ink)",fontWeight:600,boxShadow:"0 1px 3px rgba(0,0,0,0.1)"},manualBox:{background:"white",borderRadius:12,border:"1px solid var(--border)",padding:"1.25rem",color:"var(--muted)",fontSize:"0.9rem",display:"flex",flexDirection:"column",gap:"0.5rem"},previewBox:{background:"white",borderRadius:12,border:"1px solid var(--border)",padding:"1.25rem",display:"flex",flexDirection:"column",gap:"0.75rem"},previewPoll:{borderBottom:"1px solid var(--border)",paddingBottom:"0.75rem",display:"flex",flexDirection:"column",gap:"0.4rem"},previewQ:{fontWeight:600,fontSize:"0.95rem"},previewOptions:{display:"flex",flexDirection:"column",gap:"0.2rem",paddingLeft:"0.75rem"},previewOpt:{fontSize:"0.88rem",color:"var(--muted)"},previewOptCorrect:{color:"var(--success)",fontWeight:600},previewMeta:{fontSize:"0.75rem",color:"var(--muted)",marginTop:"0.25rem"},err:{color:"var(--accent)",fontSize:"0.85rem"}};function Eb(t,e=40){return t.length>e?t.slice(0,e)+"...":t}function xb(t){if(t==null)return"";const e=String(t);return e.includes(",")||e.includes('"')||e.includes(` `)?`"${e.replace(/"/g,'""')}"`:e}function nt(t){return t.map(xb).join(",")}function Ib(t){const e=t.responses||{},n=t.correctIndex!=null,r=[];r.push(nt(["Question",t.question])),r.push(nt(["Date",new Date(t.startedAt).toLocaleString()])),n&&r.push(nt(["Correct Answer",`${String.fromCharCode(65+t.correctIndex)}. ${t.options[t.correctIndex]}`])),r.push("");const i=["Student","Response"];n&&i.push("Correct (1=yes 0=no)"),r.push(nt(i));const s=Object.keys(e).sort();return s.length===0?r.push(nt(["(no responses)","",""])):s.forEach(o=>{const l=e[o],a=l!=null?`${String.fromCharCode(65+l)}. ${t.options[l]}`:"(no answer)",u=[o,a];n&&u.push(l===t.correctIndex?"1":"0"),r.push(nt(u))}),r.join(` `)}function kb(t,e){if(!e||e.length===0)return"";const n=new Set;e.forEach(o=>{Object.keys(o.responses||{}).forEach(l=>n.add(l))});const r=[...n].sort(),i=[];i.push(nt(["Set",t])),i.push(nt(["Date",new Date(e[0].startedAt).toLocaleString()])),i.push(nt(["Polls",e.length])),i.push("");const s=["Student"];return e.forEach((o,l)=>{const a=`Q${l+1}: ${Eb(o.question)}`;s.push(a),o.correctIndex!=null&&s.push(`Q${l+1} Correct (1=yes 0=no)`)}),i.push(nt(s)),r.forEach(o=>{const l=[o];e.forEach(a=>{const h=(a.responses||{})[o],d=h!=null?`${String.fromCharCode(65+h)}. ${a.options[h]}`:"(no answer)";l.push(d),a.correctIndex!=null&&l.push(h===a.correctIndex?"1":"0")}),i.push(nt(l))}),i.push(""),i.push(nt(["Summary"])),e.forEach((o,l)=>{const a=o.responses||{},u=Object.keys(a).length;i.push(""),i.push(nt([`Q${l+1}`,o.question])),o.options.forEach((h,d)=>{const f=Object.values(a).filter(_=>_===d).length,v=u>0?Math.round(f/u*100):0,w=o.correctIndex===d;i.push(nt([`${String.fromCharCode(65+d)}. ${h}`,`${f} responses`,`${v}%`,w?"correct answer":""]))})}),i.join(` -`)}function Gp(t,e){const n=new Blob([e],{type:"text/csv;charset=utf-8;"}),r=URL.createObjectURL(n),i=document.createElement("a");i.href=r,i.download=t,i.click(),URL.revokeObjectURL(r)}const Tb="prof123";function bb(){const t=Sr(),[e,n]=C.useState(!1),[r,i]=C.useState(""),[s,o]=C.useState(""),[l,a]=C.useState([]),[u,h]=C.useState({}),[d,f]=C.useState("polls"),[v,w]=C.useState(new Set),[_,E]=C.useState(new Set),[g,p]=C.useState(null),[m,S]=C.useState(null),[I,P]=C.useState({}),[b,A]=C.useState({});C.useEffect(()=>{(localStorage.getItem("historyAuth")==="true"||localStorage.getItem("role")==="teacher")&&n(!0)},[]),C.useEffect(()=>{if(!e)return;const y=R_(a),x=xr(ne(re,"sessionStudents"),T=>{const O=T.val()||{},K={};Object.values(O).forEach(Ge=>{const L=Ge.date||"unknown";K[L]||(K[L]=new Set),K[L].add(Ge.name)});const tt={};Object.entries(K).forEach(([Ge,L])=>{tt[Ge]=[...L].sort()}),h(tt)});return()=>{y(),x()}},[e]);function q(y){y.preventDefault(),r===Tb?(localStorage.setItem("historyAuth","true"),n(!0)):(o("Incorrect password."),i(""))}function z(y){vr(ne(re,`pollHistory/${y}`)),p(null),w(x=>{const T=new Set(x);return T.delete(y),T})}function pe(y,x){x.forEach(T=>vr(ne(re,`pollHistory/${T.id}`))),S(null),E(T=>{const O=new Set(T);return O.delete(y),O})}function D(y){w(x=>{const T=new Set(x);return T.has(y)?T.delete(y):T.add(y),T})}function Y(y){E(x=>{const T=new Set(x);return T.has(y)?T.delete(y):T.add(y),T})}function X(y,x){P(T=>({...T,[y]:x}))}function et(y){A(x=>({...x,[y]:!0})),setTimeout(()=>A(x=>({...x,[y]:!1})),2e3)}function Ee(y){const x=Ib(y),T=new Date(y.startedAt).toLocaleDateString().replace(/\//g,"-");Gp(`poll_${T}_${y.id}.csv`,x)}function Be(y,x){const T=kb(y,x),O=new Date(x[0].startedAt).toLocaleDateString().replace(/\//g,"-"),K=y.replace(/[^a-z0-9]/gi,"_").toLowerCase();Gp(`session_${K}_${O}.csv`,T)}function R(y){const x={},T=[];return y.forEach(O=>{if(O.setId){const K=O.sessionKey||`${O.setId}_${new Date(O.startedAt).toLocaleDateString()}`;x[K]||(x[K]={key:K,setId:O.setId,setName:O.setName,date:new Date(O.startedAt).toLocaleDateString(),startedAt:O.startedAt,polls:[]}),x[K].polls.push(O)}else T.push(O)}),Object.values(x).forEach(O=>{O.polls.sort((K,tt)=>(K.setPosition??0)-(tt.setPosition??0))}),[...Object.values(x).map(O=>({type:"set",...O})),...T.map(O=>({type:"poll",...O}))].sort((O,K)=>(K.startedAt||0)-(O.startedAt||0))}if(!e)return c.jsx("div",{style:F.center,children:c.jsxs("div",{style:F.loginCard,className:"fade-up",children:[c.jsxs("div",{style:F.loginLogo,children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsx("h2",{style:{fontSize:"1.4rem",marginBottom:"0.25rem"},children:"Poll History"}),c.jsx("p",{style:{color:"var(--muted)",marginBottom:"1.5rem",fontSize:"0.9rem"},children:"Enter the teacher password to view history and attendance."}),c.jsxs("form",{onSubmit:q,style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[c.jsx("input",{className:"input",type:"password",placeholder:"Teacher password",value:r,onChange:y=>{i(y.target.value),o("")},autoFocus:!0,style:{textAlign:"center"}}),s&&c.jsx("span",{style:F.err,children:s}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{justifyContent:"center",padding:"0.75rem"},children:"View History →"})]}),c.jsx("button",{style:F.backLink,onClick:()=>t("/"),children:"← Back"})]})});const U=R(l);return c.jsxs("div",{style:F.page,children:[c.jsxs("header",{style:F.header,children:[c.jsx("button",{style:F.back,onClick:()=>t("/"),children:"← Back"}),c.jsx("span",{style:F.title,children:"Poll History"}),c.jsxs("div",{style:F.tabs,children:[c.jsx("button",{style:{...F.tab,...d==="polls"?F.tabActive:{}},onClick:()=>f("polls"),children:"Polls"}),c.jsx("button",{style:{...F.tab,...d==="attendance"?F.tabActive:{}},onClick:()=>f("attendance"),children:"Attendance"})]})]}),c.jsxs("main",{style:F.main,children:[d==="polls"&&c.jsxs("div",{className:"fade-up",children:[U.length===0&&c.jsx("div",{style:F.empty,children:"No polls yet. Run your first one in class!"}),U.map(y=>{if(y.type==="set"){const x=_.has(y.key),T=y.polls.reduce((O,K)=>O+Object.keys(K.responses||{}).length,0);return c.jsxs("div",{style:F.setGroup,children:[c.jsxs("div",{style:F.setGroupHeaderRow,children:[c.jsxs("button",{style:F.setGroupHeaderBtn,onClick:()=>Y(y.key),children:[c.jsx("span",{style:F.triangle,children:x?"▼":"▶"}),c.jsxs("div",{style:{flex:1},children:[c.jsxs("div",{style:F.setGroupName,children:["📚 ",y.setName]}),c.jsxs("div",{style:F.setGroupMeta,children:[y.date," · ",y.polls.length," polls · ",T," total responses"]})]})]}),c.jsxs("div",{style:{display:"flex",gap:"0.4rem",alignItems:"center"},children:[c.jsx("button",{style:{...F.exportBtn,...b[y.key]?F.exportBtnSuccess:{}},onClick:()=>{Be(y.setName,y.polls),et(y.key)},children:b[y.key]?"✓ Downloading":"⬇ Session CSV"}),m!==y.key?c.jsx("button",{style:F.deleteBtn,onClick:()=>S(y.key),title:"Delete this session",children:"🗑"}):c.jsxs("div",{style:F.confirmRow,children:[c.jsxs("span",{style:F.confirmText,children:["Delete all ",y.polls.length," polls?"]}),c.jsx("button",{className:"btn btn-primary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem",background:"#dc2626"},onClick:()=>pe(y.key,y.polls),children:"Yes"}),c.jsx("button",{className:"btn btn-secondary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem"},onClick:()=>S(null),children:"Cancel"})]})]})]}),x&&c.jsx("div",{style:F.setGroupPolls,children:y.polls.map(O=>c.jsx(qp,{poll:O,expanded:v.has(O.id),viewMode:I[O.id]||"summary",confirmDelete:g,copyFeedback:b[O.id],onToggle:()=>D(O.id),onDelete:()=>z(O.id),onConfirmDelete:()=>p(O.id),onCancelDelete:()=>p(null),onSetView:K=>X(O.id,K),onDownload:()=>Ee(O),onDownloadFeedback:()=>et(O.id),positionLabel:`${(O.setPosition??0)+1}.`},O.id))})]},y.key)}return c.jsx(qp,{poll:y,expanded:v.has(y.id),viewMode:I[y.id]||"summary",confirmDelete:g,copyFeedback:b[y.id],onToggle:()=>D(y.id),onDelete:()=>z(y.id),onConfirmDelete:()=>p(y.id),onCancelDelete:()=>p(null),onSetView:x=>X(y.id,x),onDownload:()=>Ee(y),onDownloadFeedback:()=>et(y.id)},y.id)})]}),d==="attendance"&&c.jsxs("div",{className:"fade-up",children:[Object.keys(u).length===0&&c.jsx("div",{style:F.empty,children:"No attendance records yet."}),Object.entries(u).sort(([y],[x])=>x.localeCompare(y)).map(([y,x])=>c.jsxs("div",{style:F.pollCard,children:[c.jsx("div",{style:F.pollHeaderRow,children:c.jsxs("div",{style:{padding:"0.25rem 0"},children:[c.jsx("div",{style:F.pollQ,children:y}),c.jsxs("div",{style:F.pollMeta,children:[x.length," student",x.length!==1?"s":""]})]})}),c.jsx("div",{style:{padding:"0 1rem 1rem",display:"flex",flexWrap:"wrap",gap:"0.4rem"},children:x.map(T=>c.jsx("span",{style:F.chip,children:T},T))})]},y))]})]})]})}function qp({poll:t,expanded:e,viewMode:n,confirmDelete:r,copyFeedback:i,onToggle:s,onDelete:o,onConfirmDelete:l,onCancelDelete:a,onSetView:u,onDownload:h,onDownloadFeedback:d,positionLabel:f}){const v=t.responses||{},w=Object.keys(v).length,_=r===t.id,E=t.correctIndex!=null,g={};return t.options.forEach((p,m)=>{g[m]=[]}),Object.entries(v).forEach(([p,m])=>{g[m]!==void 0?g[m].push(p):g[m]=[p]}),c.jsxs("div",{style:F.pollCard,children:[c.jsxs("div",{style:F.pollHeaderRow,children:[c.jsxs("button",{style:F.pollHeaderBtn,onClick:s,children:[c.jsx("span",{style:F.triangle,children:e?"▼":"▶"}),c.jsxs("div",{children:[c.jsxs("div",{style:F.pollQ,children:[f&&c.jsxs("span",{style:F.posLabel,children:[f," "]}),t.question]}),c.jsxs("div",{style:F.pollMeta,children:[new Date(t.startedAt).toLocaleString()," · ",w," response",w!==1?"s":""]})]})]}),c.jsxs("div",{style:{display:"flex",gap:"0.4rem",alignItems:"center"},children:[!_&&c.jsx("button",{style:{...F.exportBtn,...i?F.exportBtnSuccess:{}},onClick:()=>{h(),d()},children:i?"✓ Downloading":"⬇ CSV"}),_?c.jsxs("div",{style:F.confirmRow,children:[c.jsx("span",{style:F.confirmText,children:"Delete?"}),c.jsx("button",{className:"btn btn-primary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem",background:"#dc2626"},onClick:o,children:"Yes"}),c.jsx("button",{className:"btn btn-secondary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem"},onClick:a,children:"Cancel"})]}):c.jsx("button",{style:F.deleteBtn,onClick:l,title:"Delete",children:"🗑"})]})]}),e&&c.jsxs("div",{style:F.pollDetails,children:[c.jsxs("div",{style:F.viewTabs,children:[c.jsx("button",{style:{...F.viewTab,...n==="summary"?F.viewTabActive:{}},onClick:()=>u("summary"),children:"Summary"}),c.jsx("button",{style:{...F.viewTab,...n==="students"?F.viewTabActive:{}},onClick:()=>u("students"),children:"By student"})]}),n==="summary"&&c.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.6rem"},children:t.options.map((p,m)=>{const S=Object.values(v).filter(b=>b===m).length,I=w>0?Math.round(S/w*100):0,P=E&&t.correctIndex===m;return c.jsxs("div",{style:F.histOpt,children:[c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:4},children:[c.jsxs("span",{style:{fontWeight:P?600:400,color:P?"var(--success)":"inherit"},children:[String.fromCharCode(65+m),". ",p," ",P&&"✓"]}),c.jsxs("span",{style:{color:"var(--muted)",fontSize:"0.85rem"},children:[S," (",I,"%)"]})]}),c.jsx("div",{style:F.barBg,children:c.jsx("div",{style:{...F.barFill,width:`${I}%`,background:P?"var(--success)":"var(--accent2)"}})})]},m)})}),n==="students"&&c.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[t.options.map((p,m)=>{const S=g[m]||[],I=E&&t.correctIndex===m;return S.length===0?null:c.jsxs("div",{style:F.answerGroup,children:[c.jsxs("div",{style:{...F.answerGroupHeader,...I?F.answerGroupCorrect:{}},children:[c.jsxs("span",{style:{fontWeight:600},children:[String.fromCharCode(65+m),". ",p]}),I&&c.jsx("span",{style:F.correctTag,children:"✓ correct"}),c.jsxs("span",{style:F.answerCount,children:[S.length," student",S.length!==1?"s":""]})]}),c.jsx("div",{style:F.studentNames,children:S.sort().map(P=>c.jsx("span",{style:F.chip,children:P},P))})]},m)}),w===0&&c.jsx("div",{style:{color:"var(--muted)",fontSize:"0.9rem"},children:"No responses."})]})]})]})}const F={center:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"var(--paper)"},loginCard:{background:"white",borderRadius:16,border:"1px solid var(--border)",padding:"2.5rem 2rem",maxWidth:380,width:"100%",textAlign:"center",boxShadow:"var(--shadow)"},loginLogo:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem",marginBottom:"1.5rem",display:"block"},err:{color:"var(--accent)",fontSize:"0.85rem"},backLink:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",marginTop:"1rem",fontSize:"0.85rem",display:"block",textAlign:"center"},page:{minHeight:"100vh",background:"var(--paper)"},header:{padding:"1rem 1.5rem",borderBottom:"1px solid var(--border)",background:"white",display:"flex",alignItems:"center",gap:"1rem",flexWrap:"wrap"},back:{background:"none",border:"none",color:"var(--accent2)",cursor:"pointer",fontSize:"0.9rem"},title:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.2rem",flex:1},tabs:{display:"flex",gap:"0.25rem",background:"var(--cream)",borderRadius:8,padding:"0.25rem"},tab:{background:"none",border:"none",padding:"0.35rem 0.85rem",borderRadius:6,cursor:"pointer",fontSize:"0.9rem",color:"var(--muted)",transition:"all 0.15s"},tabActive:{background:"white",color:"var(--ink)",fontWeight:600,boxShadow:"0 1px 3px rgba(0,0,0,0.1)"},main:{maxWidth:760,margin:"0 auto",padding:"1.5rem 1rem"},empty:{textAlign:"center",color:"var(--muted)",padding:"3rem",fontSize:"0.95rem"},setGroup:{background:"white",borderRadius:12,border:"1.5px solid var(--accent2)",marginBottom:"0.75rem",overflow:"hidden"},setGroupHeaderRow:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.85rem 1rem",borderBottom:"1px solid var(--cream)"},setGroupHeaderBtn:{display:"flex",alignItems:"center",gap:"0.75rem",background:"none",border:"none",cursor:"pointer",textAlign:"left",flex:1},setGroupName:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"0.95rem"},setGroupMeta:{color:"var(--muted)",fontSize:"0.8rem",marginTop:"0.2rem"},setGroupPolls:{padding:"0.5rem 0.75rem",display:"flex",flexDirection:"column",gap:"0.4rem"},triangle:{fontSize:"0.7rem",color:"var(--muted)",flexShrink:0},exportBtn:{background:"var(--cream)",border:"1px solid var(--border)",borderRadius:6,padding:"0.3rem 0.65rem",fontSize:"0.78rem",cursor:"pointer",color:"var(--ink)",whiteSpace:"nowrap",transition:"all 0.15s",flexShrink:0},exportBtnSuccess:{background:"#dcfce7",borderColor:"var(--success)",color:"var(--success)"},pollCard:{background:"white",borderRadius:12,border:"1px solid var(--border)",marginBottom:"0.75rem",overflow:"hidden"},pollHeaderRow:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.75rem 1rem"},pollHeaderBtn:{display:"flex",alignItems:"center",gap:"0.6rem",background:"none",border:"none",cursor:"pointer",textAlign:"left",flex:1,padding:"0.25rem 0"},posLabel:{color:"var(--muted)",fontWeight:400},pollQ:{fontFamily:"var(--font-display)",fontWeight:600,fontSize:"0.95rem"},pollMeta:{color:"var(--muted)",fontSize:"0.8rem",marginTop:"0.2rem"},deleteBtn:{background:"none",border:"none",cursor:"pointer",fontSize:"1.1rem",padding:"0.25rem 0.4rem",borderRadius:6,opacity:.5},confirmRow:{display:"flex",alignItems:"center",gap:"0.4rem"},confirmText:{fontSize:"0.82rem",color:"var(--muted)",whiteSpace:"nowrap"},pollDetails:{padding:"0.75rem 1rem 1rem",borderTop:"1px solid var(--border)"},viewTabs:{display:"flex",gap:"0.25rem",background:"var(--cream)",borderRadius:6,padding:"0.2rem",marginBottom:"0.75rem",width:"fit-content"},viewTab:{background:"none",border:"none",padding:"0.25rem 0.65rem",borderRadius:4,cursor:"pointer",fontSize:"0.82rem",color:"var(--muted)"},viewTabActive:{background:"white",color:"var(--ink)",fontWeight:600,boxShadow:"0 1px 2px rgba(0,0,0,0.08)"},histOpt:{marginBottom:"0.6rem"},barBg:{height:6,borderRadius:3,background:"var(--cream)",overflow:"hidden"},barFill:{height:"100%",borderRadius:3,transition:"width 0.3s"},answerGroup:{borderRadius:8,border:"1px solid var(--border)",overflow:"hidden"},answerGroupHeader:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.5rem 0.75rem",background:"var(--cream)",flexWrap:"wrap"},answerGroupCorrect:{background:"#dcfce7"},correctTag:{fontSize:"0.75rem",color:"var(--success)",fontWeight:600,background:"#bbf7d0",borderRadius:4,padding:"0.1rem 0.4rem"},answerCount:{marginLeft:"auto",fontSize:"0.78rem",color:"var(--muted)"},studentNames:{padding:"0.5rem 0.75rem",display:"flex",flexWrap:"wrap",gap:"0.35rem"},chip:{background:"var(--cream)",borderRadius:4,padding:"0.2rem 0.5rem",fontSize:"0.78rem",color:"var(--ink)"}};function Pb(){return c.jsx(dC,{basename:"/classroom-polling",children:c.jsxs(aC,{children:[c.jsx(fn,{path:"/",element:c.jsx(fC,{})}),c.jsx(fn,{path:"/teacher",element:c.jsx(mb,{})}),c.jsx(fn,{path:"/student",element:c.jsx(vb,{})}),c.jsx(fn,{path:"/pollsets/:id",element:c.jsx(Sb,{})}),c.jsx(fn,{path:"/pollsets",element:c.jsx(Cb,{})}),c.jsx(fn,{path:"/history",element:c.jsx(bb,{})}),c.jsx(fn,{path:"*",element:c.jsx(oC,{to:"/"})})]})})}Za.createRoot(document.getElementById("root")).render(c.jsx(im.StrictMode,{children:c.jsx(Pb,{})})); +`)}function Gp(t,e){const n=new Blob([e],{type:"text/csv;charset=utf-8;"}),r=URL.createObjectURL(n),i=document.createElement("a");i.href=r,i.download=t,i.click(),URL.revokeObjectURL(r)}const Tb="prof123";function bb(){const t=Sr(),[e,n]=C.useState(!1),[r,i]=C.useState(""),[s,o]=C.useState(""),[l,a]=C.useState([]),[u,h]=C.useState({}),[d,f]=C.useState("polls"),[v,w]=C.useState(new Set),[_,E]=C.useState(new Set),[g,p]=C.useState(null),[m,S]=C.useState(null),[I,P]=C.useState({}),[b,A]=C.useState({});C.useEffect(()=>{(localStorage.getItem("historyAuth")==="true"||localStorage.getItem("role")==="instructor")&&n(!0)},[]),C.useEffect(()=>{if(!e)return;const y=R_(a),x=xr(ne(re,"sessionStudents"),T=>{const O=T.val()||{},K={};Object.values(O).forEach(Ge=>{const L=Ge.date||"unknown";K[L]||(K[L]=new Set),K[L].add(Ge.name)});const tt={};Object.entries(K).forEach(([Ge,L])=>{tt[Ge]=[...L].sort()}),h(tt)});return()=>{y(),x()}},[e]);function q(y){y.preventDefault(),r===Tb?(localStorage.setItem("historyAuth","true"),n(!0)):(o("Incorrect password."),i(""))}function z(y){vr(ne(re,`pollHistory/${y}`)),p(null),w(x=>{const T=new Set(x);return T.delete(y),T})}function pe(y,x){x.forEach(T=>vr(ne(re,`pollHistory/${T.id}`))),S(null),E(T=>{const O=new Set(T);return O.delete(y),O})}function D(y){w(x=>{const T=new Set(x);return T.has(y)?T.delete(y):T.add(y),T})}function Y(y){E(x=>{const T=new Set(x);return T.has(y)?T.delete(y):T.add(y),T})}function X(y,x){P(T=>({...T,[y]:x}))}function et(y){A(x=>({...x,[y]:!0})),setTimeout(()=>A(x=>({...x,[y]:!1})),2e3)}function Ee(y){const x=Ib(y),T=new Date(y.startedAt).toLocaleDateString().replace(/\//g,"-");Gp(`poll_${T}_${y.id}.csv`,x)}function Be(y,x){const T=kb(y,x),O=new Date(x[0].startedAt).toLocaleDateString().replace(/\//g,"-"),K=y.replace(/[^a-z0-9]/gi,"_").toLowerCase();Gp(`session_${K}_${O}.csv`,T)}function R(y){const x={},T=[];return y.forEach(O=>{if(O.setId){const K=O.sessionKey||`${O.setId}_${new Date(O.startedAt).toLocaleDateString()}`;x[K]||(x[K]={key:K,setId:O.setId,setName:O.setName,date:new Date(O.startedAt).toLocaleDateString(),startedAt:O.startedAt,polls:[]}),x[K].polls.push(O)}else T.push(O)}),Object.values(x).forEach(O=>{O.polls.sort((K,tt)=>(K.setPosition??0)-(tt.setPosition??0))}),[...Object.values(x).map(O=>({type:"set",...O})),...T.map(O=>({type:"poll",...O}))].sort((O,K)=>(K.startedAt||0)-(O.startedAt||0))}if(!e)return c.jsx("div",{style:F.center,children:c.jsxs("div",{style:F.loginCard,className:"fade-up",children:[c.jsxs("div",{style:F.loginLogo,children:[c.jsx("span",{style:{color:"var(--accent)"},children:"●"})," ClassPoll"]}),c.jsx("h2",{style:{fontSize:"1.4rem",marginBottom:"0.25rem"},children:"Poll History"}),c.jsx("p",{style:{color:"var(--muted)",marginBottom:"1.5rem",fontSize:"0.9rem"},children:"Enter the instructor password to view history and attendance."}),c.jsxs("form",{onSubmit:q,style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[c.jsx("input",{className:"input",type:"password",placeholder:"Instructor password",value:r,onChange:y=>{i(y.target.value),o("")},autoFocus:!0,style:{textAlign:"center"}}),s&&c.jsx("span",{style:F.err,children:s}),c.jsx("button",{type:"submit",className:"btn btn-primary",style:{justifyContent:"center",padding:"0.75rem"},children:"View History →"})]}),c.jsx("button",{style:F.backLink,onClick:()=>t("/"),children:"← Back"})]})});const U=R(l);return c.jsxs("div",{style:F.page,children:[c.jsxs("header",{style:F.header,children:[c.jsx("button",{style:F.back,onClick:()=>t("/"),children:"← Back"}),c.jsx("span",{style:F.title,children:"Poll History"}),c.jsxs("div",{style:F.tabs,children:[c.jsx("button",{style:{...F.tab,...d==="polls"?F.tabActive:{}},onClick:()=>f("polls"),children:"Polls"}),c.jsx("button",{style:{...F.tab,...d==="attendance"?F.tabActive:{}},onClick:()=>f("attendance"),children:"Attendance"})]})]}),c.jsxs("main",{style:F.main,children:[d==="polls"&&c.jsxs("div",{className:"fade-up",children:[U.length===0&&c.jsx("div",{style:F.empty,children:"No polls yet. Run your first one in class!"}),U.map(y=>{if(y.type==="set"){const x=_.has(y.key),T=y.polls.reduce((O,K)=>O+Object.keys(K.responses||{}).length,0);return c.jsxs("div",{style:F.setGroup,children:[c.jsxs("div",{style:F.setGroupHeaderRow,children:[c.jsxs("button",{style:F.setGroupHeaderBtn,onClick:()=>Y(y.key),children:[c.jsx("span",{style:F.triangle,children:x?"▼":"▶"}),c.jsxs("div",{style:{flex:1},children:[c.jsxs("div",{style:F.setGroupName,children:["📚 ",y.setName]}),c.jsxs("div",{style:F.setGroupMeta,children:[y.date," · ",y.polls.length," polls · ",T," total responses"]})]})]}),c.jsxs("div",{style:{display:"flex",gap:"0.4rem",alignItems:"center"},children:[c.jsx("button",{style:{...F.exportBtn,...b[y.key]?F.exportBtnSuccess:{}},onClick:()=>{Be(y.setName,y.polls),et(y.key)},children:b[y.key]?"✓ Downloading":"⬇ Session CSV"}),m!==y.key?c.jsx("button",{style:F.deleteBtn,onClick:()=>S(y.key),title:"Delete this session",children:"🗑"}):c.jsxs("div",{style:F.confirmRow,children:[c.jsxs("span",{style:F.confirmText,children:["Delete all ",y.polls.length," polls?"]}),c.jsx("button",{className:"btn btn-primary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem",background:"#dc2626"},onClick:()=>pe(y.key,y.polls),children:"Yes"}),c.jsx("button",{className:"btn btn-secondary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem"},onClick:()=>S(null),children:"Cancel"})]})]})]}),x&&c.jsx("div",{style:F.setGroupPolls,children:y.polls.map(O=>c.jsx(qp,{poll:O,expanded:v.has(O.id),viewMode:I[O.id]||"summary",confirmDelete:g,copyFeedback:b[O.id],onToggle:()=>D(O.id),onDelete:()=>z(O.id),onConfirmDelete:()=>p(O.id),onCancelDelete:()=>p(null),onSetView:K=>X(O.id,K),onDownload:()=>Ee(O),onDownloadFeedback:()=>et(O.id),positionLabel:`${(O.setPosition??0)+1}.`},O.id))})]},y.key)}return c.jsx(qp,{poll:y,expanded:v.has(y.id),viewMode:I[y.id]||"summary",confirmDelete:g,copyFeedback:b[y.id],onToggle:()=>D(y.id),onDelete:()=>z(y.id),onConfirmDelete:()=>p(y.id),onCancelDelete:()=>p(null),onSetView:x=>X(y.id,x),onDownload:()=>Ee(y),onDownloadFeedback:()=>et(y.id)},y.id)})]}),d==="attendance"&&c.jsxs("div",{className:"fade-up",children:[Object.keys(u).length===0&&c.jsx("div",{style:F.empty,children:"No attendance records yet."}),Object.entries(u).sort(([y],[x])=>x.localeCompare(y)).map(([y,x])=>c.jsxs("div",{style:F.pollCard,children:[c.jsx("div",{style:F.pollHeaderRow,children:c.jsxs("div",{style:{padding:"0.25rem 0"},children:[c.jsx("div",{style:F.pollQ,children:y}),c.jsxs("div",{style:F.pollMeta,children:[x.length," student",x.length!==1?"s":""]})]})}),c.jsx("div",{style:{padding:"0 1rem 1rem",display:"flex",flexWrap:"wrap",gap:"0.4rem"},children:x.map(T=>c.jsx("span",{style:F.chip,children:T},T))})]},y))]})]})]})}function qp({poll:t,expanded:e,viewMode:n,confirmDelete:r,copyFeedback:i,onToggle:s,onDelete:o,onConfirmDelete:l,onCancelDelete:a,onSetView:u,onDownload:h,onDownloadFeedback:d,positionLabel:f}){const v=t.responses||{},w=Object.keys(v).length,_=r===t.id,E=t.correctIndex!=null,g={};return t.options.forEach((p,m)=>{g[m]=[]}),Object.entries(v).forEach(([p,m])=>{g[m]!==void 0?g[m].push(p):g[m]=[p]}),c.jsxs("div",{style:F.pollCard,children:[c.jsxs("div",{style:F.pollHeaderRow,children:[c.jsxs("button",{style:F.pollHeaderBtn,onClick:s,children:[c.jsx("span",{style:F.triangle,children:e?"▼":"▶"}),c.jsxs("div",{children:[c.jsxs("div",{style:F.pollQ,children:[f&&c.jsxs("span",{style:F.posLabel,children:[f," "]}),t.question]}),c.jsxs("div",{style:F.pollMeta,children:[new Date(t.startedAt).toLocaleString()," · ",w," response",w!==1?"s":""]})]})]}),c.jsxs("div",{style:{display:"flex",gap:"0.4rem",alignItems:"center"},children:[!_&&c.jsx("button",{style:{...F.exportBtn,...i?F.exportBtnSuccess:{}},onClick:()=>{h(),d()},children:i?"✓ Downloading":"⬇ CSV"}),_?c.jsxs("div",{style:F.confirmRow,children:[c.jsx("span",{style:F.confirmText,children:"Delete?"}),c.jsx("button",{className:"btn btn-primary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem",background:"#dc2626"},onClick:o,children:"Yes"}),c.jsx("button",{className:"btn btn-secondary",style:{fontSize:"0.78rem",padding:"0.3rem 0.7rem"},onClick:a,children:"Cancel"})]}):c.jsx("button",{style:F.deleteBtn,onClick:l,title:"Delete",children:"🗑"})]})]}),e&&c.jsxs("div",{style:F.pollDetails,children:[c.jsxs("div",{style:F.viewTabs,children:[c.jsx("button",{style:{...F.viewTab,...n==="summary"?F.viewTabActive:{}},onClick:()=>u("summary"),children:"Summary"}),c.jsx("button",{style:{...F.viewTab,...n==="students"?F.viewTabActive:{}},onClick:()=>u("students"),children:"By student"})]}),n==="summary"&&c.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.6rem"},children:t.options.map((p,m)=>{const S=Object.values(v).filter(b=>b===m).length,I=w>0?Math.round(S/w*100):0,P=E&&t.correctIndex===m;return c.jsxs("div",{style:F.histOpt,children:[c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:4},children:[c.jsxs("span",{style:{fontWeight:P?600:400,color:P?"var(--success)":"inherit"},children:[String.fromCharCode(65+m),". ",p," ",P&&"✓"]}),c.jsxs("span",{style:{color:"var(--muted)",fontSize:"0.85rem"},children:[S," (",I,"%)"]})]}),c.jsx("div",{style:F.barBg,children:c.jsx("div",{style:{...F.barFill,width:`${I}%`,background:P?"var(--success)":"var(--accent2)"}})})]},m)})}),n==="students"&&c.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:[t.options.map((p,m)=>{const S=g[m]||[],I=E&&t.correctIndex===m;return S.length===0?null:c.jsxs("div",{style:F.answerGroup,children:[c.jsxs("div",{style:{...F.answerGroupHeader,...I?F.answerGroupCorrect:{}},children:[c.jsxs("span",{style:{fontWeight:600},children:[String.fromCharCode(65+m),". ",p]}),I&&c.jsx("span",{style:F.correctTag,children:"✓ correct"}),c.jsxs("span",{style:F.answerCount,children:[S.length," student",S.length!==1?"s":""]})]}),c.jsx("div",{style:F.studentNames,children:S.sort().map(P=>c.jsx("span",{style:F.chip,children:P},P))})]},m)}),w===0&&c.jsx("div",{style:{color:"var(--muted)",fontSize:"0.9rem"},children:"No responses."})]})]})]})}const F={center:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:"1rem",background:"var(--paper)"},loginCard:{background:"white",borderRadius:16,border:"1px solid var(--border)",padding:"2.5rem 2rem",maxWidth:380,width:"100%",textAlign:"center",boxShadow:"var(--shadow)"},loginLogo:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"1.1rem",marginBottom:"1.5rem",display:"block"},err:{color:"var(--accent)",fontSize:"0.85rem"},backLink:{background:"none",border:"none",color:"var(--muted)",cursor:"pointer",marginTop:"1rem",fontSize:"0.85rem",display:"block",textAlign:"center"},page:{minHeight:"100vh",background:"var(--paper)"},header:{padding:"1rem 1.5rem",borderBottom:"1px solid var(--border)",background:"white",display:"flex",alignItems:"center",gap:"1rem",flexWrap:"wrap"},back:{background:"none",border:"none",color:"var(--accent2)",cursor:"pointer",fontSize:"0.9rem"},title:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"1.2rem",flex:1},tabs:{display:"flex",gap:"0.25rem",background:"var(--cream)",borderRadius:8,padding:"0.25rem"},tab:{background:"none",border:"none",padding:"0.35rem 0.85rem",borderRadius:6,cursor:"pointer",fontSize:"0.9rem",color:"var(--muted)",transition:"all 0.15s"},tabActive:{background:"white",color:"var(--ink)",fontWeight:600,boxShadow:"0 1px 3px rgba(0,0,0,0.1)"},main:{maxWidth:760,margin:"0 auto",padding:"1.5rem 1rem"},empty:{textAlign:"center",color:"var(--muted)",padding:"3rem",fontSize:"0.95rem"},setGroup:{background:"white",borderRadius:12,border:"1.5px solid var(--accent2)",marginBottom:"0.75rem",overflow:"hidden"},setGroupHeaderRow:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.85rem 1rem",borderBottom:"1px solid var(--cream)"},setGroupHeaderBtn:{display:"flex",alignItems:"center",gap:"0.75rem",background:"none",border:"none",cursor:"pointer",textAlign:"left",flex:1},setGroupName:{fontFamily:"var(--font-display)",fontWeight:700,fontSize:"0.95rem"},setGroupMeta:{color:"var(--muted)",fontSize:"0.8rem",marginTop:"0.2rem"},setGroupPolls:{padding:"0.5rem 0.75rem",display:"flex",flexDirection:"column",gap:"0.4rem"},triangle:{fontSize:"0.7rem",color:"var(--muted)",flexShrink:0},exportBtn:{background:"var(--cream)",border:"1px solid var(--border)",borderRadius:6,padding:"0.3rem 0.65rem",fontSize:"0.78rem",cursor:"pointer",color:"var(--ink)",whiteSpace:"nowrap",transition:"all 0.15s",flexShrink:0},exportBtnSuccess:{background:"#dcfce7",borderColor:"var(--success)",color:"var(--success)"},pollCard:{background:"white",borderRadius:12,border:"1px solid var(--border)",marginBottom:"0.75rem",overflow:"hidden"},pollHeaderRow:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.75rem 1rem"},pollHeaderBtn:{display:"flex",alignItems:"center",gap:"0.6rem",background:"none",border:"none",cursor:"pointer",textAlign:"left",flex:1,padding:"0.25rem 0"},posLabel:{color:"var(--muted)",fontWeight:400},pollQ:{fontFamily:"var(--font-display)",fontWeight:600,fontSize:"0.95rem"},pollMeta:{color:"var(--muted)",fontSize:"0.8rem",marginTop:"0.2rem"},deleteBtn:{background:"none",border:"none",cursor:"pointer",fontSize:"1.1rem",padding:"0.25rem 0.4rem",borderRadius:6,opacity:.5},confirmRow:{display:"flex",alignItems:"center",gap:"0.4rem"},confirmText:{fontSize:"0.82rem",color:"var(--muted)",whiteSpace:"nowrap"},pollDetails:{padding:"0.75rem 1rem 1rem",borderTop:"1px solid var(--border)"},viewTabs:{display:"flex",gap:"0.25rem",background:"var(--cream)",borderRadius:6,padding:"0.2rem",marginBottom:"0.75rem",width:"fit-content"},viewTab:{background:"none",border:"none",padding:"0.25rem 0.65rem",borderRadius:4,cursor:"pointer",fontSize:"0.82rem",color:"var(--muted)"},viewTabActive:{background:"white",color:"var(--ink)",fontWeight:600,boxShadow:"0 1px 2px rgba(0,0,0,0.08)"},histOpt:{marginBottom:"0.6rem"},barBg:{height:6,borderRadius:3,background:"var(--cream)",overflow:"hidden"},barFill:{height:"100%",borderRadius:3,transition:"width 0.3s"},answerGroup:{borderRadius:8,border:"1px solid var(--border)",overflow:"hidden"},answerGroupHeader:{display:"flex",alignItems:"center",gap:"0.5rem",padding:"0.5rem 0.75rem",background:"var(--cream)",flexWrap:"wrap"},answerGroupCorrect:{background:"#dcfce7"},correctTag:{fontSize:"0.75rem",color:"var(--success)",fontWeight:600,background:"#bbf7d0",borderRadius:4,padding:"0.1rem 0.4rem"},answerCount:{marginLeft:"auto",fontSize:"0.78rem",color:"var(--muted)"},studentNames:{padding:"0.5rem 0.75rem",display:"flex",flexWrap:"wrap",gap:"0.35rem"},chip:{background:"var(--cream)",borderRadius:4,padding:"0.2rem 0.5rem",fontSize:"0.78rem",color:"var(--ink)"}};function Pb(){return c.jsx(dC,{basename:"/classroom-polling",children:c.jsxs(aC,{children:[c.jsx(fn,{path:"/",element:c.jsx(fC,{})}),c.jsx(fn,{path:"/instructor",element:c.jsx(mb,{})}),c.jsx(fn,{path:"/student",element:c.jsx(vb,{})}),c.jsx(fn,{path:"/pollsets/:id",element:c.jsx(Sb,{})}),c.jsx(fn,{path:"/pollsets",element:c.jsx(Cb,{})}),c.jsx(fn,{path:"/history",element:c.jsx(bb,{})}),c.jsx(fn,{path:"*",element:c.jsx(oC,{to:"/"})})]})})}Za.createRoot(document.getElementById("root")).render(c.jsx(im.StrictMode,{children:c.jsx(Pb,{})})); diff --git a/dist/index.html b/dist/index.html index ea9ae57..dc625f8 100644 --- a/dist/index.html +++ b/dist/index.html @@ -8,7 +8,7 @@ - + diff --git a/node_modules/.vite/deps/_metadata.json b/node_modules/.vite/deps/_metadata.json index 4495baf..3c979f8 100644 --- a/node_modules/.vite/deps/_metadata.json +++ b/node_modules/.vite/deps/_metadata.json @@ -7,55 +7,55 @@ "react": { "src": "../../react/index.js", "file": "react.js", - "fileHash": "4c5b97b1", + "fileHash": "62626146", "needsInterop": true }, "react-dom": { "src": "../../react-dom/index.js", "file": "react-dom.js", - "fileHash": "a800d98c", + "fileHash": "e205e623", "needsInterop": true }, "react/jsx-dev-runtime": { "src": "../../react/jsx-dev-runtime.js", "file": "react_jsx-dev-runtime.js", - "fileHash": "49403d8d", + "fileHash": "cd7f1551", "needsInterop": true }, "react/jsx-runtime": { "src": "../../react/jsx-runtime.js", "file": "react_jsx-runtime.js", - "fileHash": "8319c78f", + "fileHash": "d524e7c0", "needsInterop": true }, "firebase/app": { "src": "../../firebase/app/dist/esm/index.esm.js", "file": "firebase_app.js", - "fileHash": "06daed78", + "fileHash": "263b99ae", "needsInterop": false }, "firebase/auth": { "src": "../../firebase/auth/dist/esm/index.esm.js", "file": "firebase_auth.js", - "fileHash": "bb5fb4ae", + "fileHash": "4fed8dd8", "needsInterop": false }, "firebase/database": { "src": "../../firebase/database/dist/esm/index.esm.js", "file": "firebase_database.js", - "fileHash": "ba620094", + "fileHash": "9dbf7323", "needsInterop": false }, "react-dom/client": { "src": "../../react-dom/client.js", "file": "react-dom_client.js", - "fileHash": "e33ee8df", + "fileHash": "50817ba9", "needsInterop": true }, "react-router-dom": { "src": "../../react-router-dom/dist/index.js", "file": "react-router-dom.js", - "fileHash": "1273c6ff", + "fileHash": "f2af17c3", "needsInterop": false } }, diff --git a/src/App.jsx b/src/App.jsx index 2ccf6c3..afdcb5b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -10,7 +10,7 @@ */ import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; import RoleSelector from './pages/RoleSelector'; -import TeacherPage from './pages/TeacherPage'; +import InstructorPage from './pages/InstructorPage'; import StudentPage from './pages/StudentPage'; import PollSetDetail from './pages/PollSetDetail'; import PollSets from './pages/PollSets'; @@ -21,7 +21,7 @@ export default function App() { } /> - } /> + } /> } /> } /> } /> diff --git a/src/pages/TeacherPage.jsx b/src/pages/InstructorPage.jsx similarity index 99% rename from src/pages/TeacherPage.jsx rename to src/pages/InstructorPage.jsx index 8c66680..43a9d5f 100644 --- a/src/pages/TeacherPage.jsx +++ b/src/pages/InstructorPage.jsx @@ -28,7 +28,7 @@ const CORRECT_OPTIONS = [ { value: 'never', label: 'Never' }, ]; -export default function TeacherPage() { +export default function InstructorPage() { const navigate = useNavigate(); const [students, setStudents] = useState([]); const [activePoll, setActivePoll] = useState(null); @@ -48,7 +48,7 @@ export default function TeacherPage() { const [correctPolicy, setCorrectPolicy] = useState('with_results'); useEffect(() => { - if (localStorage.getItem("role") !== 'teacher') navigate('/'); + if (localStorage.getItem("role") !== 'instructor') navigate('/'); }, []); useEffect(() => { diff --git a/src/pages/PollHistory.jsx b/src/pages/PollHistory.jsx index a73e791..ec4c38a 100644 --- a/src/pages/PollHistory.jsx +++ b/src/pages/PollHistory.jsx @@ -15,7 +15,7 @@ import { db } from '../firebase'; import { ref, onValue, remove } from 'firebase/database'; import { pollToCsv, sessionToCsv, downloadCsv } from '../utils/csvExport'; -const HISTORY_PASSWORD = import.meta.env.VITE_TEACHER_PASSWORD || 'changeme'; +const HISTORY_PASSWORD = import.meta.env.VITE_INSTRUCTOR_PASSWORD || 'changeme'; export default function PollHistory() { const navigate = useNavigate(); @@ -33,7 +33,7 @@ export default function PollHistory() { const [copyFeedback, setCopyFeedback] = useState({}); // key -> true useEffect(() => { - if (localStorage.getItem("historyAuth") === 'true' || localStorage.getItem("role") === 'teacher') setAuth(true); + if (localStorage.getItem("historyAuth") === 'true' || localStorage.getItem("role") === 'instructor') setAuth(true); }, []); useEffect(() => { @@ -153,11 +153,11 @@ export default function PollHistory() {

Poll History

- Enter the teacher password to view history and attendance. + Enter the instructor password to view history and attendance.

- { setPw(e.target.value); setErr(''); }} autoFocus style={{textAlign:'center'}} /> {err && {err}} diff --git a/src/pages/PollSetDetail.jsx b/src/pages/PollSetDetail.jsx index 67b939b..1559f3e 100644 --- a/src/pages/PollSetDetail.jsx +++ b/src/pages/PollSetDetail.jsx @@ -39,7 +39,7 @@ export default function PollSetDetail() { const [nameValue, setNameValue] = useState(''); useEffect(() => { - if (localStorage.getItem('role') !== 'teacher') navigate('/'); + if (localStorage.getItem('role') !== 'instructor') navigate('/'); return watchPollSet(id, s => { if (!s) return; setPollSet(s); @@ -155,7 +155,7 @@ export default function PollSetDetail() { resultPolicy: first.resultPolicy ?? d.resultPolicy ?? 'on_submit', correctPolicy: first.correctPolicy ?? d.correctPolicy ?? 'with_results', }); - navigate('/teacher'); + navigate('/instructor'); } if (!pollSet) return ( diff --git a/src/pages/PollSets.jsx b/src/pages/PollSets.jsx index b17de83..925ec7a 100644 --- a/src/pages/PollSets.jsx +++ b/src/pages/PollSets.jsx @@ -49,7 +49,7 @@ export default function PollSets() { const [parseErr, setParseErr] = useState(''); useEffect(() => { - if (localStorage.getItem('role') !== 'teacher') navigate('/'); + if (localStorage.getItem('role') !== 'instructor') navigate('/'); return watchPollSets(setSets); }, []); @@ -113,7 +113,7 @@ export default function PollSets() { return (
- + Poll Sets {view === 'list' && ( - {!showTeacherLogin ? ( - ) : ( - + 🔑 - Teacher Password + Instructor Password diff --git a/src/pages/StudentPage.jsx b/src/pages/StudentPage.jsx index a6a8e8d..3179b01 100644 --- a/src/pages/StudentPage.jsx +++ b/src/pages/StudentPage.jsx @@ -87,10 +87,10 @@ export default function StudentPage() { const responseCount = activePoll ? Object.keys(activePoll.responses || {}).length : 0; const pollStopped = activePoll?.ended || timeLeft === 0; - // Determine what to show based on teacher policy + manual overrides + // Determine what to show based on instructor policy + manual overrides function shouldShowResults() { if (!activePoll) return false; - if (activePoll.revealResults) return true; // teacher manually revealed + if (activePoll.revealResults) return true; // instructor manually revealed if (activePoll.resultPolicy === 'never') return false; if (activePoll.resultPolicy === 'manual') return false; if (activePoll.resultPolicy === 'on_submit') return submitted || alreadyAnswered; @@ -100,7 +100,7 @@ export default function StudentPage() { function shouldShowCorrect() { if (!activePoll) return false; if (activePoll.correctIndex == null) return false; - if (activePoll.revealCorrect) return true; // teacher manually revealed + if (activePoll.revealCorrect) return true; // instructor manually revealed if (activePoll.correctPolicy === 'never') return false; if (activePoll.correctPolicy === 'manual') return false; if (activePoll.correctPolicy === 'with_results') return shouldShowResults(); @@ -135,7 +135,7 @@ export default function StudentPage() {

Hi, {name}! 👋

-

Waiting for the teacher to start a poll…

+

Waiting for the instructor to start a poll…

@@ -186,7 +186,7 @@ export default function StudentPage() { )} {activePoll.ended && (
- ⏰ Time's up — waiting for teacher + ⏰ Time's up — waiting for instructor
)} @@ -241,7 +241,7 @@ export default function StudentPage() {
)} {pollStopped && (alreadyAnswered || submitted) && ( -
✓ Answer submitted — waiting for teacher
+
✓ Answer submitted — waiting for instructor
)}