1/*! For license information please see 7346.36cfac39.chunk.js.LICENSE.txt */ 2"use strict";(globalThis.webpackChunkfrontend=globalThis.webpackChunkfrontend||[]).push([[7346],{91140(e,s,a){a.d(s,{BT:()=>i,Wu:()=>c,ZB:()=>d,Zp:()=>n,aR:()=>o,wL:()=>u});var r=a(65043),t=a(99766),l=a(70579);const n=r.forwardRef((e,s)=>{let{className:a,...r}=e;return(0,l.jsx)("div",{ref:s,className:(0,t.cn)("rounded-xl border bg-card text-card-foreground shadow",a),...r})});n.displayName="Card";const o=r.forwardRef((e,s)=>{let{className:a,...r}=e;return(0,l.jsx)("div",{ref:s,className:(0,t.cn)("flex flex-col space-y-1.5 p-6",a),...r})});o.displayName="CardHeader";const d=r.forwardRef((e,s)=>{let{className:a,...r}=e;return(0,l.jsx)("div",{ref:s,className:(0,t.cn)("font-semibold leading-none tracking-tight",a),...r})});d.displayName="CardTitle";const i=r.forwardRef((e,s)=>{let{className:a,...r}=e;return(0,l.jsx)("div",{ref:s,className:(0,t.cn)("text-sm text-muted-foreground",a),...r})});i.displayName="CardDescription";const c=r.forwardRef((e,s)=>{let{className:a,...r}=e;return(0,l.jsx)("div",{ref:s,className:(0,t.cn)("p-6 pt-0",a),...r})});c.displayName="CardContent";const u=r.forwardRef((e,s)=>{let{className:a,...r}=e;return(0,l.jsx)("div",{ref:s,className:(0,t.cn)("flex items-center p-6 pt-0",a),...r})});u.displayName="CardFooter"},92264(e,s,a){a.d(s,{p:()=>n});var r=a(65043),t=a(99766),l=a(70579);const n=r.forwardRef((e,s)=>{let{className:a,type:r,...n}=e;return(0,l.jsx)("input",{type:r,className:(0,t.cn)("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",a),ref:s,...n})});n.displayName="Input"},75395(e,s,a){a.d(s,{k:()=>o});var r=a(65043),t=a(7989),l=a(99766),n=a(70579);const o=r.forwardRef((e,s)=>{let{className:a,value:r,...o}=e;return(0,n.jsx)(t.bL,{ref:s,className:(0,l.cn)("relative h-2 w-full overflow-hidden rounded-full bg-primary/20",a),...o,children:(0,n.jsx)(t.C1,{className:"h-full w-full flex-1 bg-primary transition-all",style:{transform:`translateX(-${100-(r||0)}%)`}})})});o.displayName=t.bL.displayName},37346(e,s,a){a.r(s),a.d(s,{default:()=>j});var r=a(65043),t=a(73824),l=a(4980),n=a(56328),o=a(13390),d=a(91140),i=a(5949),c=a(75395),u=a(46258),m=a(7104),f=a(41680),p=a(73002),x=a(94965),h=a(70067),v=a(39292),g=a(9855),b=a(50797),N=a(92264),y=a(70579);const j=()=>{var e;const{user:s}=(0,t.As)(),[a,j]=(0,r.useState)([]),[w,$]=(0,r.useState)(null),[_,C]=(0,r.useState)(!0),[A,k]=(0,r.useState)(!1),[R,L]=(0,r.useState)(null),[M,F]=(0,r.useState)("");(0,r.useEffect)(()=>{P()},[]);const P=async()=>{try{const[e,s]=await Promise.all([l.A.get(`${t.nC}/resources`),l.A.get(`${t.nC}/subscription`)]);j(e.data),$(s.data)}catch(e){n.oR.error("Failed to load resources")}finally{C(!1)}},S=async e=>{const s=e.target.files;if(s.length){k(!0);for(const e of s){const s=new FormData;s.append("file",e);try{await l.A.post(`${t.nC}/resources`,s,{headers:{"Content-Type":"multipart/form-data"}}),n.oR.success(`Uploaded ${e.name}`)}catch(r){var a;403===(null===(a=r.response)||void 0===a?void 0:a.status)?n.oR.error(r.response.data.detail):n.oR.error(`Failed to upload ${e.name}`)}}k(!1),P(),e.target.value=""}},U=e=>e.includes("pdf")?(0,y.jsx)(f.A,{className:"w-5 h-5"}):e.includes("image")?(0,y.jsx)(h.A,{className:"w-5 h-5"}):(0,y.jsx)(p.A,{className:"w-5 h-5"}),T=a.filter(e=>e.filename.toLowerCase().includes(M.toLowerCase())),B=-1===(null===w||void 0===w?void 0:w.storage_limit_mb)?5:Math.min((null===w||void 0===w?void 0:w.storage_used_mb)/(null===w||void 0===w?void 0:w.storage_limit_mb)*100,100);return _?(0,y.jsx)(u.A,{children:(0,y.jsx)("div",{className:"flex items-center justify-center h-96",children:(0,y.jsx)("div",{className:"spinner w-12 h-12"})})}):(0,y.jsx)(u.A,{children:(0,y.jsxs)("div",{"data-testid":"resources-page",children:[(0,y.jsxs)("div",{className:"flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-8",children:[(0,y.jsxs)("div",{className:"flex items-center gap-3",children:[(0,y.jsx)("div",{className:"w-12 h-12 rounded-xl bg-gradient-to-br from-slate-500 to-gray-600 flex items-center justify-center text-white",children:(0,y.jsx)(x.A,{className:"w-6 h-6"})}),(0,y.jsxs)("div",{className:"min-w-0",children:[(0,y.jsx)("h1",{className:"text-3xl font-bold text-foreground",children:"Resources"}),(0,y.jsx)("p",{className:"text-muted-foreground mt-1",children:"Manage your teaching resources and attachments"})]})]}),(0,y.jsxs)("label",{children:[(0,y.jsx)("input",{type:"file",multiple:!0,className:"hidden",onChange:S,disabled:A,"data-testid":"file-upload-input"}),(0,y.jsx)(o.$,{className:"bg-primary text-primary-foreground hover:bg-primary/90 rounded-full cursor-pointer",disabled:A,asChild:!0,children:(0,y.jsxs)("span",{children:[(0,y.jsx)(b.A,{className:"w-4 h-4 mr-2"}),A?"Uploading...":"Upload Files"]})})]})]}),(0,y.jsx)(d.Zp,{className:"border-border/50 mb-8","data-testid":"storage-info-card",children:(0,y.jsxs)(d.Wu,{className:"p-6",children:[(0,y.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,y.jsxs)("div",{children:[(0,y.jsx)("h3",{className:"font-semibold text-foreground",children:"Storage Used"}),(0,y.jsxs)("p",{className:"text-sm text-muted-foreground",children:[null===w||void 0===w||null===(e=w.storage_used_mb)||void 0===e?void 0:e.toFixed(2)," MB of"," ",-1===(null===w||void 0===w?void 0:w.storage_limit_mb)?"unlimited":`${null===w||void 0===w?void 0:w.storage_limit_mb} MB`]})]}),(0,y.jsxs)(i.E,{variant:"outline",children:[a.length," files"]})]}),(0,y.jsx)(c.k,{value:B,className:"h-2"})]})}),(0,y.jsxs)("div",{className:"relative mb-6",children:[(0,y.jsx)(v.A,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-muted-foreground"}),(0,y.jsx)(N.p,{placeholder:"Search resources...",value:M,onChange:e=>F(e.target.value),className:"pl-10 form-input","data-testid":"search-input"})]}),T.length>0?(0,y.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:T.map(e=>{return(0,y.jsx)(d.Zp,{className:"border-border/50 hover:shadow-md transition-shadow","data-testid":`resource-card-${e.resource_id}`,children:(0,y.jsxs)(d.Wu,{className:"p-4",children:[(0,y.jsxs)("div",{className:"flex items-start gap-4",children:[(0,y.jsx)("div",{className:`w-12 h-12 rounded-lg ${a=e.file_type,a.includes("pdf")?"bg-red-500":a.includes("image")?"bg-green-500":a.includes("word")||a.includes("document")?"bg-blue-500":"bg-gray-500"} flex items-center justify-center text-white`,children:U(e.file_type)}),(0,y.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,y.jsx)("h4",{className:"font-medium text-foreground truncate",title:e.filename,children:e.filename}),(0,y.jsx)("p",{className:"text-sm text-muted-foreground",children:(s=e.file_size,s<1024?`${s} B`:s<1048576?`${(s/1024).toFixed(1)} KB`:`${(s/1048576).toFixed(1)} MB`)}),e.plan_id&&(0,y.jsx)(i.E,{variant:"secondary",className:"mt-2 text-xs",children:"Linked to plan"})]})]}),(0,y.jsxs)("div",{className:"flex gap-2 mt-4",children:[(0,y.jsxs)(o.$,{variant:"outline",size:"sm",className:"flex-1",onClick:()=>(async(e,s)=>{L(e);try{const a=await l.A.get(`${t.nC}/resources/${e}/download`,{responseType:"blob"}),r=window.URL.createObjectURL(new Blob([a.data])),n=document.createElement("a");n.href=r,n.setAttribute("download",s),document.body.appendChild(n),n.click(),n.remove(),window.URL.revokeObjectURL(r)}catch(a){n.oR.error("Failed to download file")}finally{L(null)}})(e.resource_id,e.filename),disabled:R===e.resource_id,"data-testid":`download-btn-${e.resource_id}`,children:[(0,y.jsx)(m.A,{className:"w-4 h-4 mr-1"}),R===e.resource_id?"Downloading...":"Download"]}),(0,y.jsx)(o.$,{variant:"outline",size:"sm",onClick:()=>(async(e,s)=>{try{await l.A.delete(`${t.nC}/resources/${e}`),n.oR.success(`Deleted ${s}`),P()}catch(a){n.oR.error("Failed to delete resource")}})(e.resource_id,e.filename),className:"text-destructive border-destructive/30 hover:bg-destructive/10","data-testid":`delete-btn-${e.resource_id}`,children:(0,y.jsx)(g.A,{className:"w-4 h-4"})})]})]})},e.resource_id);var s,a})}):(0,y.jsx)(d.Zp,{className:"border-dashed border-2 border-border","data-testid":"empty-resources-card",children:(0,y.jsxs)(d.Wu,{className:"p-12 text-center",children:[(0,y.jsx)(x.A,{className:"w-16 h-16 text-muted-foreground
2/50 mx-auto mb-4"}),(0,y.jsx)("h3",{className:"text-xl font-semibold text-foreground mb-2",children:M?"No resources found":"No resources yet"}),(0,y.jsx)("p",{className:"text-muted-foreground mb-6",children:M?"Try a different search term":"Upload files to store worksheets, images, and teaching materials."}),!M&&(0,y.jsxs)("label",{children:[(0,y.jsx)("input",{type:"file",multiple:!0,className:"hidden",onChange:S,"data-testid":"empty-state-upload"}),(0,y.jsx)(o.$,{className:"bg-primary text-primary-foreground hover:bg-primary/90 rounded-full cursor-pointer",asChild:!0,children:(0,y.jsxs)("span",{children:[(0,y.jsx)(b.A,{className:"w-4 h-4 mr-2"}),"Upload Your First File"]})})]})]})})]})})}},7104(e,s,a){a.d(s,{A:()=>r});const r=(0,a(77784).A)("download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]])},73002(e,s,a){a.d(s,{A:()=>r});const r=(0,a(77784).A)("file",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}]])},39292(e,s,a){a.d(s,{A:()=>r});const r=(0,a(77784).A)("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]])},50797(e,s,a){a.d(s,{A:()=>r});const r=(0,a(77784).A)("upload",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"17 8 12 3 7 8",key:"t8dd8p"}],["line",{x1:"12",x2:"12",y1:"3",y2:"15",key:"widbto"}]])},7989(e,s,a){a.d(s,{C1:()=>w,bL:()=>j});var r=a(65043),t=a(70579);function l(){for(var e=arguments.length,s=new Array(e),a=0;a<e;a++)s[a]=arguments[a];const t=s[0];if(1===s.length)return t;const l=()=>{const e=s.map(e=>({useScope:e(),scopeName:e.scopeName}));return function(s){const a=e.reduce((e,a)=>{let{useScope:r,scopeName:t}=a;return{...e,...r(s)[`__scope${t}`]}},{});return r.useMemo(()=>({[`__scope${t.scopeName}`]:a}),[a])}};return l.scopeName=t.scopeName,l}a(97950);var n=a(16851),o=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"].reduce((e,s)=>{const a=(0,n.TL)(`Primitive.${s}`),l=r.forwardRef((e,r)=>{const{asChild:l,...n}=e,o=l?a:s;return"undefined"!==typeof window&&(window[Symbol.for("radix-ui")]=!0),(0,t.jsx)(o,{...n,ref:r})});return l.displayName=`Primitive.${s}`,{...e,[s]:l}},{});var d="Progress",i=100,[c,u]=function(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],a=[];const n=()=>{const s=a.map(e=>r.createContext(e));return function(a){const t=a?.[e]||s;return r.useMemo(()=>({[`__scope${e}`]:{...a,[e]:t}}),[a,t])}};return n.scopeName=e,[function(s,l){const n=r.createContext(l);n.displayName=s+"Context";const o=a.length;a=[...a,l];const d=s=>{const{scope:a,children:l,...d}=s,i=a?.[e]?.[o]||n,c=r.useMemo(()=>d,Object.values(d));return(0,t.jsx)(i.Provider,{value:c,children:l})};return d.displayName=s+"Provider",[d,function(a,t){const d=t?.[e]?.[o]||n,i=r.useContext(d);if(i)return i;if(void 0!==l)return l;throw new Error(`\`${a}\` must be used within \`${s}\``)}]},l(n,...s)]}(d),[m,f]=c(d),p=r.forwardRef((e,s)=>{const{__scopeProgress:a,value:r=null,max:l,getValueLabel:n=v,...d}=e;!l&&0!==l||N(l)||console.error(`Invalid prop \`max\` of value \`${`${l}`}\` supplied to \`${"Progress"}\`. Only numbers greater than 0 are valid max values. Defaulting to \`100\`.`);const c=N(l)?l:i;null===r||y(r,c)||console.error(function(e,s){return`Invalid prop \`value\` of value \`${e}\` supplied to \`${s}\`. The \`value\` prop must be:\n - a positive number\n - less than the value passed to \`max\` (or 100 if no \`max\` prop is set)\n - \`null\` or \`undefined\` if the progress is indeterminate.\n\nDefaulting to \`null\`.`}(`${r}`,"Progress"));const u=y(r,c)?r:null,f=b(u)?n(u,c):void 0;return(0,t.jsx)(m,{scope:a,value:u,max:c,children:(0,t.jsx)(o.div,{"aria-valuemax":c,"aria-valuemin":0,"aria-valuenow":b(u)?u:void 0,"aria-valuetext":f,role:"progressbar","data-state":g(u,c),"data-value":u??void 0,"data-max":c,...d,ref:s})})});p.displayName=d;var x="ProgressIndicator",h=r.forwardRef((e,s)=>{const{__scopeProgress:a,...r}=e,l=f(x,a);return(0,t.jsx)(o.div,{"data-state":g(l.value,l.max),"data-value":l.value??void 0,"data-max":l.max,...r,ref:s})});function v(e,s){return`${Math.round(e/s*100)}%`}function g(e,s){return null==e?"indeterminate":e===s?"complete":"loading"}function b(e){return"number"===typeof e}function N(e){return b(e)&&!isNaN(e)&&e>0}function y(e,s){return b(e)&&!isNaN(e)&&e<=s&&e>=0}h.displayName=x;var j=p,w=h}}]); 3//# sourceMappingURL=7346.36cfac39.chunk.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.