|
|
var R=p,_=Symbol.for("react.element"),$=Symbol.for("react.fragment"),E=Object.prototype.hasOwnProperty,O=R.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,k={key:!0,ref:!0,__self:!0,__source:!0};function S(s,a,c){var n,t={},r=null,o=null;c!==void 0&&(r=""+c),a.key!==void 0&&(r=""+a.key),a.ref!==void 0&&(o=a.ref);for(n in a)E.call(a,n)&&!k.hasOwnProperty(n)&&(t[n]=a[n]);if(s&&s.defaultProps)for(n in a=s.defaultProps,a)t[n]===void 0&&(t[n]=a[n]);return{$$typeof:_,type:s,key:r,ref:o,props:t,_owner:O.current}}z.Fragment=$;z.jsx=S;z.jsxs=S;w.exports=z;var e=w.exports,N={},b=C;N.createRoot=b.createRoot,N.hydrateRoot=b.hydrateRoot;const T=({onTopicsChange:s,availableTopics:a=[],selectedTopics:c=[]})=>{const n=t=>{const r=c.includes(t)?c.filter(o=>o!==t):[...c,t];s(r)};return e.jsxs("div",{className:"topic-selector",children:[e.jsx("h3",{children:"Select Topics"}),e.jsx("div",{className:"topic-buttons",children:a.map(t=>e.jsx("button",{className:`topic-btn ${c.includes(t.name)?"selected":""}`,onClick:()=>n(t.name),children:t.name},t.id))}),e.jsxs("p",{className:"selected-count",children:[c.length," topic",c.length!==1?"s":""," selected"]})]})},L=({grid:s,clues:a,showSolution:c,onCellChange:n})=>{const[t,r]=p.useState({}),o=(u,l,i)=>{const d=`${u}-${l}`,h={...t,[d]:i.toUpperCase()};r(h),n&&n(u,l,i)},f=(u,l)=>{if(c&&!m(u,l))return s[u][l];const i=`${u}-${l}`;return t[i]||""},m=(u,l)=>s[u][l]===".",g=(u,l)=>{if(!a)return null;const i=a.find(d=>d.position.row===u&&d.position.col===l);return i?i.number:null};if(!s||s.length===0)return e.jsx("div",{className:"puzzle-grid",children:"No puzzle loaded"});const x=s.length,y=s[0]?s[0].length:0;return e.jsx("div",{className:"puzzle-container",children:e.jsx("div",{className:"puzzle-grid",style:{gridTemplateColumns:`repeat(${y}, 35px)`,gridTemplateRows:`repeat(${x}, 35px)`},children:s.map((u,l)=>u.map((i,d)=>{const h=g(l,d);return m(l,d)?e.jsx("div",{className:"grid-cell empty-cell",style:{visibility:"hidden"}},`${l}-${d}`):e.jsxs("div",{className:"grid-cell white-cell",children:[h&&e.jsx("span",{className:"cell-number",children:h}),e.jsx("input",{type:"text",maxLength:"1",value:f(l,d),onChange:v=>o(l,d,v.target.value),className:`cell-input ${c?"solution-text":""}`,disabled:c})]},`${l}-${d}`)}))})})},A=({clues:s=[]})=>{const a=s.filter(t=>t.direction==="across"),c=s.filter(t=>t.direction==="down"),n=({title:t,clueList:r})=>e.jsxs("div",{className:"clue-section",children:[e.jsx("h4",{children:t}),e.jsx("ol",{children:r.map(o=>e.jsxs("li",{className:"clue-item",children:[e.jsx("span",{className:"clue-number",children:o.number}),e.jsx("span",{className:"clue-text",children:o.text})]},`${o.number}-${o.direction}`))})]});return e.jsxs("div",{className:"clue-list",children:[e.jsx(n,{title:"Across",clueList:a}),e.jsx(n,{title:"Down",clueList:c})]})},D=({message:s="Generating puzzle..."})=>e.jsxs("div",{className:"loading-spinner",children:[e.jsx("div",{className:"spinner"}),e.jsx("p",{className:"loading-message",children:s})]}),F=()=>{const[s,a]=p.useState(null),[c,n]=p.useState(!1),[t,r]=p.useState(null),[o,f]=p.useState([]),m="",g=p.useCallback(async()=>{try{n(!0);const l=await fetch(`${m}/api/topics`);if(!l.ok)throw new Error("Failed to fetch topics");const i=await l.json();f(i)}catch(l){r(l.message)}finally{n(!1)}},[m]),x=p.useCallback(async(l,i="medium",d=!1)=>{try{n(!0),r(null);const h=await fetch(`${m}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({topics:l,difficulty:i,useAI:d})});if(!h.ok){const v=await h.json().catch(()=>({}));throw new Error(v.message||"Failed to generate puzzle")}const j=await h.json();return a(j),j}catch(h){return r(h.message),null}finally{n(!1)}},[m]),y=p.useCallback(async l=>{try{const i=await fetch(`${m}/api/validate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({puzzle:s,answers:l})});if(!i.ok)throw new Error("Failed to validate answers");return await i.json()}catch(i){return r(i.message),null}},[m,s]),u=p.useCallback(()=>{a(null),r(null)},[]);return{puzzle:s,loading:c,error:t,topics:o,fetchTopics:g,generatePuzzle:x,validateAnswers:y,resetPuzzle:u}};function G(){const[s,a]=p.useState([]),[c,n]=p.useState("medium"),[t,r]=p.useState(!1),{puzzle:o,loading:f,error:m,topics:g,fetchTopics:x,generatePuzzle:y,resetPuzzle:u}=F();p.useEffect(()=>{x()},[x]);const l=async()=>{if(s.length===0){alert("Please select at least one topic");return}await y(s,c,!1)},i=j=>{a(j)},d=()=>{u(),a([]),r(!1),n("medium")},h=()=>{r(!0)};return e.jsxs("div",{className:"crossword-app",children:[e.jsxs("header",{className:"app-header",children:[e.jsx("h1",{className:"app-title",children:"Crossword Puzzle Generator"}),e.jsx("p",{children:"Select topics and generate your custom crossword puzzle!"})]}),e.jsx(T,{onTopicsChange:i,availableTopics:g,selectedTopics:s}),e.jsxs("div",{className:"puzzle-controls",children:[e.jsxs("select",{value:c,onChange:j=>n(j.target.value),className:"control-btn",children:[e.jsx("option",{value:"easy",children:"Easy"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"hard",children:"Hard"})]}),e.jsx("button",{onClick:l,disabled:f||s.length===0,className:"control-btn generate-btn",children:f?"Generating...":"Generate Puzzle"}),e.jsx("button",{onClick:d,className:"control-btn reset-btn",children:"Reset"}),o&&!t&&e.jsx("button",{onClick:h,className:"control-btn reveal-btn",children:"Reveal Solution"})]}),m&&e.jsxs("div",{className:"error-message",children:["Error: ",m]}),f&&e.jsx(D,{}),o&&!f&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"puzzle-info",children:e.jsxs("span",{className:"puzzle-stats",children:[o.metadata.wordCount," words • ",o.metadata.size,"×",o.metadata.size," grid"]})}),e.jsxs("div",{className:"puzzle-layout",children:[e.jsx(L,{grid:o.grid,clues:o.clues,showSolution:t}),e.jsx(A,{clues:o.clues})]})]}),!o&&!f&&!m&&e.jsx("div",{style:{textAlign:"center",padding:"40px",color:"#7f8c8d"},children:'Select topics and click "Generate Puzzle" to start!'})]})}N.createRoot(document.getElementById("root")).render(e.jsx(P.StrictMode,{children:e.jsx(G,{})})); |