diff --git a/.gitignore b/.gitignore index a5c029cc..08ef01aa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,3 @@ backend/razorpay.env backend/src/main/resources/application-local.properties counter-frontend/.env -ordering-site/* -ordering_site/ diff --git a/counter-frontend/dist/assets/AnimatePresence-CcsC7tO8.js b/counter-frontend/dist/assets/AnimatePresence-CcsC7tO8.js new file mode 100644 index 00000000..dbef0c2d --- /dev/null +++ b/counter-frontend/dist/assets/AnimatePresence-CcsC7tO8.js @@ -0,0 +1,9 @@ +import{a as e,i as t,n,o as r,r as i}from"./proxy-cLldRXEc.js";import{g as a,h as o,m as s,p as c,u as l}from"./index-B-Yfb7Zz.js";var u=s(),d=a(o(),1);function f(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function p(...e){return t=>{let n=!1,r=e.map(e=>{let r=f(e,t);return!n&&typeof r==`function`&&(n=!0),r});if(n)return()=>{for(let t=0;t{let{width:e,height:l,top:u,left:d,right:p,bottom:m}=c.current;if(t||a===!1||!s.current||!e||!l)return;let h=n===`left`?`left: ${d}`:`right: ${p}`,g=r===`bottom`?`bottom: ${m}`:`top: ${u}`;s.current.dataset.motionPopId=o;let _=document.createElement(`style`);f&&(_.nonce=f);let v=i??document.head;return v.appendChild(_),_.sheet&&_.sheet.insertRule(` + [data-motion-pop-id="${o}"] { + position: absolute !important; + width: ${e}px !important; + height: ${l}px !important; + ${h}px !important; + ${g}px !important; + } + `),()=>{s.current?.removeAttribute(`data-motion-pop-id`),v.contains(_)&&v.removeChild(_)}},[t]),(0,u.jsx)(h,{isPresent:t,childRef:s,sizeRef:c,pop:a,children:a===!1?e:d.cloneElement(e,{ref:p})})}var _=({children:e,initial:n,isPresent:r,onExitComplete:i,custom:a,presenceAffectsLayout:o,mode:s,anchorX:l,anchorY:f,root:p})=>{let m=c(v),h=(0,d.useId)(),_=!0,y=(0,d.useMemo)(()=>(_=!1,{id:h,initial:n,isPresent:r,custom:a,onExitComplete:e=>{m.set(e,!0);for(let e of m.values())if(!e)return;i&&i()},register:e=>(m.set(e,!1),()=>m.delete(e))}),[r,m,i]);return o&&_&&(y={...y}),(0,d.useMemo)(()=>{m.forEach((e,t)=>m.set(t,!1))},[r]),d.useEffect(()=>{!r&&!m.size&&i&&i()},[r]),e=(0,u.jsx)(g,{pop:s===`popLayout`,isPresent:r,anchorX:l,anchorY:f,root:p,children:e}),(0,u.jsx)(t.Provider,{value:y,children:e})};function v(){return new Map}var y=e=>e.key||``;function b(e){let t=[];return d.Children.forEach(e,e=>{(0,d.isValidElement)(e)&&t.push(e)}),t}var x=({children:t,custom:i,initial:a=!0,onExitComplete:o,presenceAffectsLayout:s=!0,mode:l=`sync`,propagate:f=!1,anchorX:p=`left`,anchorY:m=`top`,root:h})=>{let[g,v]=n(f),x=(0,d.useMemo)(()=>b(t),[t]),S=f&&!g?[]:x.map(y),C=(0,d.useRef)(!0),w=(0,d.useRef)(x),T=c(()=>new Map),E=(0,d.useRef)(new Set),[D,O]=(0,d.useState)(x),[k,A]=(0,d.useState)(x);e(()=>{C.current=!1,w.current=x;for(let e=0;e{let t=y(e),n=f&&!g?!1:x===k||S.includes(t);return(0,u.jsx)(_,{isPresent:n,initial:!C.current||a?void 0:!1,custom:i,presenceAffectsLayout:s,mode:l,root:h,onExitComplete:n?void 0:()=>{if(E.current.has(t))return;if(T.has(t))E.current.add(t),T.set(t,!0);else return;let e=!0;T.forEach(t=>{t||(e=!1)}),e&&(M?.(),A(w.current),f&&v?.(),o&&o())},anchorX:p,anchorY:m,children:e},t)})})};export{x as t}; \ No newline at end of file diff --git a/counter-frontend/dist/assets/AnimatePresence-K0yVRmqs.js b/counter-frontend/dist/assets/AnimatePresence-K0yVRmqs.js deleted file mode 100644 index aa63645e..00000000 --- a/counter-frontend/dist/assets/AnimatePresence-K0yVRmqs.js +++ /dev/null @@ -1,9 +0,0 @@ -import{m as e,t,u as n}from"./index-Cw6Vy2ED.js";import{a as r,c as i,i as a,n as o,o as s,r as c,s as l}from"./proxy-D2DvKtgS.js";var u=t(),d=e(n(),1);function f(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function p(...e){return t=>{let n=!1,r=e.map(e=>{let r=f(e,t);return!n&&typeof r==`function`&&(n=!0),r});if(n)return()=>{for(let t=0;t{let{width:e,height:c,top:u,left:d,right:p,bottom:m}=l.current;if(t||a===!1||!s.current||!e||!c)return;let h=n===`left`?`left: ${d}`:`right: ${p}`,g=r===`bottom`?`bottom: ${m}`:`top: ${u}`;s.current.dataset.motionPopId=o;let _=document.createElement(`style`);f&&(_.nonce=f);let v=i??document.head;return v.appendChild(_),_.sheet&&_.sheet.insertRule(` - [data-motion-pop-id="${o}"] { - position: absolute !important; - width: ${e}px !important; - height: ${c}px !important; - ${h}px !important; - ${g}px !important; - } - `),()=>{s.current?.removeAttribute(`data-motion-pop-id`),v.contains(_)&&v.removeChild(_)}},[t]),(0,u.jsx)(h,{isPresent:t,childRef:s,sizeRef:l,pop:a,children:a===!1?e:d.cloneElement(e,{ref:p})})}var _=({children:e,initial:t,isPresent:n,onExitComplete:i,custom:a,presenceAffectsLayout:o,mode:s,anchorX:c,anchorY:f,root:p})=>{let m=l(v),h=(0,d.useId)(),_=!0,y=(0,d.useMemo)(()=>(_=!1,{id:h,initial:t,isPresent:n,custom:a,onExitComplete:e=>{m.set(e,!0);for(let e of m.values())if(!e)return;i&&i()},register:e=>(m.set(e,!1),()=>m.delete(e))}),[n,m,i]);return o&&_&&(y={...y}),(0,d.useMemo)(()=>{m.forEach((e,t)=>m.set(t,!1))},[n]),d.useEffect(()=>{!n&&!m.size&&i&&i()},[n]),e=(0,u.jsx)(g,{pop:s===`popLayout`,isPresent:n,anchorX:c,anchorY:f,root:p,children:e}),(0,u.jsx)(r.Provider,{value:y,children:e})};function v(){return new Map}var y=e=>e.key||``;function b(e){let t=[];return d.Children.forEach(e,e=>{(0,d.isValidElement)(e)&&t.push(e)}),t}var x=({children:e,custom:t,initial:n=!0,onExitComplete:r,presenceAffectsLayout:a=!0,mode:c=`sync`,propagate:f=!1,anchorX:p=`left`,anchorY:m=`top`,root:h})=>{let[g,v]=o(f),x=(0,d.useMemo)(()=>b(e),[e]),S=f&&!g?[]:x.map(y),C=(0,d.useRef)(!0),w=(0,d.useRef)(x),T=l(()=>new Map),E=(0,d.useRef)(new Set),[D,O]=(0,d.useState)(x),[k,A]=(0,d.useState)(x);s(()=>{C.current=!1,w.current=x;for(let e=0;e{let i=y(e),o=f&&!g?!1:x===k||S.includes(i);return(0,u.jsx)(_,{isPresent:o,initial:!C.current||n?void 0:!1,custom:t,presenceAffectsLayout:a,mode:c,root:h,onExitComplete:o?void 0:()=>{if(E.current.has(i))return;if(T.has(i))E.current.add(i),T.set(i,!0);else return;let e=!0;T.forEach(t=>{t||(e=!1)}),e&&(M?.(),A(w.current),f&&v?.(),r&&r())},anchorX:p,anchorY:m,children:e},i)})})};export{x as t}; \ No newline at end of file diff --git a/counter-frontend/dist/assets/Categories-BOfc5dFx.js b/counter-frontend/dist/assets/Categories-BOfc5dFx.js deleted file mode 100644 index f97de522..00000000 --- a/counter-frontend/dist/assets/Categories-BOfc5dFx.js +++ /dev/null @@ -1 +0,0 @@ -import{n as e,r as t,t as n}from"./x-BDEl80Ev.js";import{t as r}from"./plus-8GVzNLn4.js";import{a as i,m as a,o,s,t as c,u as l}from"./index-Cw6Vy2ED.js";import{t as u}from"./proxy-D2DvKtgS.js";import{t as d}from"./AnimatePresence-K0yVRmqs.js";var f=a(l(),1),p=c(),m=async(e,t={})=>{let n=sessionStorage.getItem(`counterToken`),r={"Content-Type":`application/json`,...t.headers||{},...n?{Authorization:`Bearer ${n}`}:{}},i=e.replace(/^http:\/\/[^:/]+:8080\/api/,`https://cmsapi.rit-services.in/api`),a=await fetch(i,{...t,headers:r});return(a.status===401||a.status===403)&&(sessionStorage.removeItem(`isCounterLoggedIn`),sessionStorage.removeItem(`counterToken`),window.location.href=`/login`),a},h=()=>{let[a,c]=(0,f.useState)([]),[l,h]=(0,f.useState)(!0),[_,v]=(0,f.useState)(``),[y,b]=(0,f.useState)(!1),[x,S]=(0,f.useState)(null),C=async()=>{h(!0);try{let e=window.location.hostname,t=await(await m(`http://${e}:8080/api/base-items`)).json();c(Array.isArray(t)?t:t.content||[])}catch(e){console.error(`Error fetching categories:`,e)}finally{h(!1)}};(0,f.useEffect)(()=>{C()},[]);let w=async e=>{e.preventDefault();let t=window.location.hostname,n=x?.id?`http://${t}:8080/api/base-items/${x.id}`:`http://${t}:8080/api/base-items`,r=x?.id?`PUT`:`POST`;try{(await m(n,{method:r,headers:{"Content-Type":`application/json`},body:JSON.stringify(x)})).ok&&(b(!1),C())}catch(e){console.error(`Error saving category:`,e)}},T=a.filter(e=>e.name.toLowerCase().includes(_.toLowerCase()));return(0,p.jsxs)(`div`,{className:`p-8 space-y-8 h-full overflow-y-auto custom-scrollbar bg-slate-50`,children:[(0,p.jsxs)(`div`,{className:`flex flex-col md:flex-row md:items-center justify-between gap-4`,children:[(0,p.jsxs)(`div`,{children:[(0,p.jsx)(`h1`,{className:`text-4xl font-black text-slate-900 tracking-tight`,children:`Food Categories`}),(0,p.jsx)(`p`,{className:`text-slate-400 text-xs font-bold uppercase tracking-[0.2em] mt-2`,children:`Manage your menu structure`})]}),(0,p.jsxs)(`button`,{onClick:()=>{S({name:``,description:``,active:!0}),b(!0)},className:`bg-primary text-white px-10 py-4 rounded-2xl font-black text-xs uppercase tracking-widest flex items-center gap-3 shadow-2xl shadow-primary/30 hover:scale-[1.02] active:scale-95 transition-all`,children:[(0,p.jsx)(r,{size:18}),` Add Category`]})]}),(0,p.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8`,children:[(0,p.jsx)(g,{icon:s,label:`Active Categories`,value:a.filter(e=>e.active).length,color:`bg-primary/5 text-primary`}),(0,p.jsx)(g,{icon:o,label:`Total Structure`,value:a.length,color:`bg-emerald-50 text-emerald-500`})]}),(0,p.jsxs)(`div`,{className:`bg-white p-4 rounded-[3rem] shadow-xl shadow-slate-200/50 border border-slate-100 overflow-hidden`,children:[(0,p.jsxs)(`div`,{className:`p-6 relative group`,children:[(0,p.jsx)(i,{className:`absolute left-12 top-1/2 -translate-y-1/2 text-slate-400 group-focus-within:text-primary transition-colors`,size:24}),(0,p.jsx)(`input`,{type:`text`,placeholder:`Search categories by name...`,value:_,onChange:e=>v(e.target.value),className:`w-full bg-slate-50 border border-slate-100/50 rounded-2xl py-6 pl-16 pr-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all shadow-inner`})]}),(0,p.jsx)(`div`,{className:`p-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8`,children:(0,p.jsx)(d,{children:l?(0,p.jsx)(`div`,{className:`col-span-full h-40 flex items-center justify-center`,children:(0,p.jsx)(`div`,{className:`w-10 h-10 border-4 border-primary/20 border-t-primary rounded-full animate-spin`})}):T.map(t=>(0,p.jsxs)(u.div,{layout:!0,initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.9},className:`bg-white p-8 rounded-[2.8rem] border border-slate-100 shadow-sm hover:shadow-2xl transition-all group flex flex-col gap-8 relative overflow-hidden`,children:[(0,p.jsx)(`div`,{className:`absolute top-0 right-0 w-32 h-32 -mr-16 -mt-16 rounded-full opacity-[0.03] transition-transform duration-700 group-hover:scale-150 ${t.active?`bg-emerald-500`:`bg-slate-500`}`}),(0,p.jsxs)(`div`,{className:`flex items-center justify-between relative z-10`,children:[(0,p.jsx)(`div`,{className:`w-16 h-16 rounded-2xl flex items-center justify-center transition-all ${t.active?`bg-primary/5 text-primary`:`bg-slate-100 text-slate-400`} group-hover:bg-primary group-hover:text-white`,children:(0,p.jsx)(s,{size:32})}),(0,p.jsxs)(`div`,{className:`flex gap-2 opacity-0 group-hover:opacity-100 transition-all transform translate-x-4 group-hover:translate-x-0`,children:[(0,p.jsx)(`button`,{onClick:()=>window.location.href=`/products?category=${t.name}`,className:`w-10 h-10 bg-white border border-slate-100 rounded-xl flex items-center justify-center text-slate-400 hover:text-emerald-500 hover:border-emerald-500/30 shadow-sm transition-all`,title:`View Products`,children:(0,p.jsx)(o,{size:16})}),(0,p.jsx)(`button`,{onClick:()=>{S(t),b(!0)},className:`w-10 h-10 bg-white border border-slate-100 rounded-xl flex items-center justify-center text-slate-400 hover:text-primary hover:border-primary/30 shadow-sm transition-all`,title:`Edit Category`,children:(0,p.jsx)(e,{size:16})})]})]}),(0,p.jsxs)(`div`,{className:`relative z-10`,children:[(0,p.jsx)(`h3`,{className:`text-xl font-black text-slate-800 uppercase tracking-tight leading-none mb-3`,children:t.name}),(0,p.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,p.jsx)(`span`,{className:`w-2 h-2 rounded-full ${t.active?`bg-emerald-500 animate-pulse`:`bg-slate-300`}`}),(0,p.jsx)(`p`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em]`,children:t.active?`Active`:`Inactive`})]})]})]},t.id))})})]}),y&&(0,p.jsxs)(`div`,{className:`fixed inset-0 z-[100] flex items-center justify-center p-4`,children:[(0,p.jsx)(u.div,{initial:{opacity:0},animate:{opacity:1},onClick:()=>b(!1),className:`absolute inset-0 bg-slate-900/60 backdrop-blur-md`}),(0,p.jsxs)(u.div,{initial:{opacity:0,scale:.9,y:20},animate:{opacity:1,scale:1,y:0},className:`relative bg-white w-full max-w-lg rounded-[3rem] shadow-2xl overflow-hidden`,children:[(0,p.jsxs)(`div`,{className:`p-10 border-b border-slate-100 flex items-center justify-between bg-white`,children:[(0,p.jsxs)(`div`,{children:[(0,p.jsx)(`h2`,{className:`text-2xl font-black text-slate-900`,children:x?.id?`Edit Category`:`New Category`}),(0,p.jsx)(`p`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-widest mt-1`,children:`Configure category properties`})]}),(0,p.jsx)(`button`,{onClick:()=>b(!1),className:`w-12 h-12 bg-slate-50 rounded-2xl flex items-center justify-center text-slate-400 hover:text-rose-500 transition-all`,children:(0,p.jsx)(n,{size:24})})]}),(0,p.jsxs)(`form`,{onSubmit:w,className:`p-10 space-y-8`,children:[(0,p.jsxs)(`div`,{className:`space-y-4`,children:[(0,p.jsx)(`label`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em] ml-2`,children:`Category Name`}),(0,p.jsx)(`input`,{autoFocus:!0,required:!0,type:`text`,value:x?.name||``,onChange:e=>S({...x,name:e.target.value}),className:`w-full bg-slate-50 border border-slate-100 rounded-2xl py-5 px-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all`,placeholder:`e.g. FAST FOOD`})]}),(0,p.jsxs)(`div`,{className:`space-y-4`,children:[(0,p.jsx)(`label`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em] ml-2`,children:`Description`}),(0,p.jsx)(`textarea`,{value:x?.description||``,onChange:e=>S({...x,description:e.target.value}),className:`w-full bg-slate-50 border border-slate-100 rounded-2xl py-5 px-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all h-32 resize-none`,placeholder:`Tell us more about this category...`})]}),(0,p.jsxs)(`div`,{className:`flex items-center gap-4 bg-slate-50 p-6 rounded-3xl border border-slate-100`,children:[(0,p.jsxs)(`div`,{className:`flex-1`,children:[(0,p.jsx)(`p`,{className:`text-sm font-black text-slate-800`,children:`Status`}),(0,p.jsx)(`p`,{className:`text-[10px] font-bold text-slate-400 uppercase tracking-widest`,children:`Enable or disable category visibility`})]}),(0,p.jsx)(`button`,{type:`button`,onClick:()=>S({...x,active:!x.active}),className:`w-16 h-8 rounded-full transition-all relative ${x?.active?`bg-primary`:`bg-slate-300`}`,children:(0,p.jsx)(`div`,{className:`absolute top-1 w-6 h-6 bg-white rounded-full transition-all ${x?.active?`right-1`:`left-1`}`})})]}),(0,p.jsxs)(`div`,{className:`flex gap-4 pt-4`,children:[(0,p.jsx)(`button`,{type:`button`,onClick:()=>b(!1),className:`flex-1 py-5 rounded-2xl font-black text-xs uppercase tracking-widest text-slate-400 hover:bg-slate-50 transition-all border border-transparent hover:border-slate-100`,children:`Cancel`}),(0,p.jsxs)(`button`,{type:`submit`,className:`flex-1 bg-primary text-white py-5 rounded-2xl font-black text-xs uppercase tracking-widest shadow-xl shadow-primary/20 hover:scale-[1.02] active:scale-95 transition-all flex items-center justify-center gap-2`,children:[(0,p.jsx)(t,{size:18}),` `,x?.id?`Update Category`:`Save Category`]})]})]})]})]})]})},g=({icon:e,label:t,value:n,color:r})=>(0,p.jsxs)(`div`,{className:`bg-white p-8 rounded-[2.8rem] border border-slate-100 shadow-sm flex items-center gap-8 group hover:shadow-2xl transition-all`,children:[(0,p.jsx)(`div`,{className:`w-16 h-16 rounded-[1.5rem] flex items-center justify-center group-hover:bg-primary group-hover:text-white transition-all ${r.split(` `)[0]} ${r.split(` `)[1]}`,children:(0,p.jsx)(e,{size:32})}),(0,p.jsxs)(`div`,{children:[(0,p.jsx)(`p`,{className:`text-3xl font-black text-slate-900 tracking-tighter`,children:n}),(0,p.jsx)(`p`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em]`,children:t})]})]});export{h as default}; \ No newline at end of file diff --git a/counter-frontend/dist/assets/Categories-DzWzJLW4.js b/counter-frontend/dist/assets/Categories-DzWzJLW4.js new file mode 100644 index 00000000..d29edda8 --- /dev/null +++ b/counter-frontend/dist/assets/Categories-DzWzJLW4.js @@ -0,0 +1 @@ +import{t as e}from"./proxy-cLldRXEc.js";import{t}from"./AnimatePresence-CcsC7tO8.js";import{n,r,t as i}from"./x-CnVgnJPD.js";import{t as a}from"./plus-CtPxjhzP.js";import{a as o,g as s,h as c,i as l,m as u,o as d}from"./index-B-Yfb7Zz.js";var f=s(c(),1),p=u(),m=async(e,t={})=>{let n=sessionStorage.getItem(`counterToken`),r={"Content-Type":`application/json`,...t.headers||{},...n?{Authorization:`Bearer ${n}`}:{}},i=e.replace(/^http:\/\/[^:/]+:8080\/api/,`https://cmsapi.rit-services.in/api`),a=await fetch(i,{...t,headers:r});return(a.status===401||a.status===403)&&(sessionStorage.removeItem(`isCounterLoggedIn`),sessionStorage.removeItem(`counterToken`),window.location.href=`/login`),a},h=()=>{let[s,c]=(0,f.useState)([]),[u,h]=(0,f.useState)(!0),[_,v]=(0,f.useState)(``),[y,b]=(0,f.useState)(!1),[x,S]=(0,f.useState)(null),C=async()=>{h(!0);try{let e=window.location.hostname,t=await(await m(`http://${e}:8080/api/base-items`)).json();c(Array.isArray(t)?t:t.content||[])}catch(e){console.error(`Error fetching categories:`,e)}finally{h(!1)}};(0,f.useEffect)(()=>{C()},[]);let w=async e=>{e.preventDefault();let t=window.location.hostname,n=x?.id?`http://${t}:8080/api/base-items/${x.id}`:`http://${t}:8080/api/base-items`,r=x?.id?`PUT`:`POST`;try{(await m(n,{method:r,headers:{"Content-Type":`application/json`},body:JSON.stringify(x)})).ok&&(b(!1),C())}catch(e){console.error(`Error saving category:`,e)}},T=s.filter(e=>e.name.toLowerCase().includes(_.toLowerCase()));return(0,p.jsxs)(`div`,{className:`p-8 space-y-8 h-full overflow-y-auto custom-scrollbar bg-slate-50`,children:[(0,p.jsxs)(`div`,{className:`flex flex-col md:flex-row md:items-center justify-between gap-4`,children:[(0,p.jsxs)(`div`,{children:[(0,p.jsx)(`h1`,{className:`text-4xl font-black text-slate-900 tracking-tight`,children:`Food Categories`}),(0,p.jsx)(`p`,{className:`text-slate-400 text-xs font-bold uppercase tracking-[0.2em] mt-2`,children:`Manage your menu structure`})]}),(0,p.jsxs)(`button`,{onClick:()=>{S({name:``,description:``,active:!0}),b(!0)},className:`bg-primary text-white px-10 py-4 rounded-2xl font-black text-xs uppercase tracking-widest flex items-center gap-3 shadow-2xl shadow-primary/30 hover:scale-[1.02] active:scale-95 transition-all`,children:[(0,p.jsx)(a,{size:18}),` Add Category`]})]}),(0,p.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8`,children:[(0,p.jsx)(g,{icon:d,label:`Active Categories`,value:s.filter(e=>e.active).length,color:`bg-primary/5 text-primary`}),(0,p.jsx)(g,{icon:o,label:`Total Structure`,value:s.length,color:`bg-emerald-50 text-emerald-500`})]}),(0,p.jsxs)(`div`,{className:`bg-white p-4 rounded-[3rem] shadow-xl shadow-slate-200/50 border border-slate-100 overflow-hidden`,children:[(0,p.jsxs)(`div`,{className:`p-6 relative group`,children:[(0,p.jsx)(l,{className:`absolute left-12 top-1/2 -translate-y-1/2 text-slate-400 group-focus-within:text-primary transition-colors`,size:24}),(0,p.jsx)(`input`,{type:`text`,placeholder:`Search categories by name...`,value:_,onChange:e=>v(e.target.value),className:`w-full bg-slate-50 border border-slate-100/50 rounded-2xl py-6 pl-16 pr-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all shadow-inner`})]}),(0,p.jsx)(`div`,{className:`p-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8`,children:(0,p.jsx)(t,{children:u?(0,p.jsx)(`div`,{className:`col-span-full h-40 flex items-center justify-center`,children:(0,p.jsx)(`div`,{className:`w-10 h-10 border-4 border-primary/20 border-t-primary rounded-full animate-spin`})}):T.map(t=>(0,p.jsxs)(e.div,{layout:!0,initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.9},className:`bg-white p-8 rounded-[2.8rem] border border-slate-100 shadow-sm hover:shadow-2xl transition-all group flex flex-col gap-8 relative overflow-hidden`,children:[(0,p.jsx)(`div`,{className:`absolute top-0 right-0 w-32 h-32 -mr-16 -mt-16 rounded-full opacity-[0.03] transition-transform duration-700 group-hover:scale-150 ${t.active?`bg-emerald-500`:`bg-slate-500`}`}),(0,p.jsxs)(`div`,{className:`flex items-center justify-between relative z-10`,children:[(0,p.jsx)(`div`,{className:`w-16 h-16 rounded-2xl flex items-center justify-center transition-all ${t.active?`bg-primary/5 text-primary`:`bg-slate-100 text-slate-400`} group-hover:bg-primary group-hover:text-white`,children:(0,p.jsx)(d,{size:32})}),(0,p.jsxs)(`div`,{className:`flex gap-2 opacity-0 group-hover:opacity-100 transition-all transform translate-x-4 group-hover:translate-x-0`,children:[(0,p.jsx)(`button`,{onClick:()=>window.location.href=`/products?category=${t.name}`,className:`w-10 h-10 bg-white border border-slate-100 rounded-xl flex items-center justify-center text-slate-400 hover:text-emerald-500 hover:border-emerald-500/30 shadow-sm transition-all`,title:`View Products`,children:(0,p.jsx)(o,{size:16})}),(0,p.jsx)(`button`,{onClick:()=>{S(t),b(!0)},className:`w-10 h-10 bg-white border border-slate-100 rounded-xl flex items-center justify-center text-slate-400 hover:text-primary hover:border-primary/30 shadow-sm transition-all`,title:`Edit Category`,children:(0,p.jsx)(n,{size:16})})]})]}),(0,p.jsxs)(`div`,{className:`relative z-10`,children:[(0,p.jsx)(`h3`,{className:`text-xl font-black text-slate-800 uppercase tracking-tight leading-none mb-3`,children:t.name}),(0,p.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,p.jsx)(`span`,{className:`w-2 h-2 rounded-full ${t.active?`bg-emerald-500 animate-pulse`:`bg-slate-300`}`}),(0,p.jsx)(`p`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em]`,children:t.active?`Active`:`Inactive`})]})]})]},t.id))})})]}),y&&(0,p.jsxs)(`div`,{className:`fixed inset-0 z-[100] flex items-center justify-center p-4`,children:[(0,p.jsx)(e.div,{initial:{opacity:0},animate:{opacity:1},onClick:()=>b(!1),className:`absolute inset-0 bg-slate-900/60 backdrop-blur-md`}),(0,p.jsxs)(e.div,{initial:{opacity:0,scale:.9,y:20},animate:{opacity:1,scale:1,y:0},className:`relative bg-white w-full max-w-lg rounded-[3rem] shadow-2xl overflow-hidden`,children:[(0,p.jsxs)(`div`,{className:`p-10 border-b border-slate-100 flex items-center justify-between bg-white`,children:[(0,p.jsxs)(`div`,{children:[(0,p.jsx)(`h2`,{className:`text-2xl font-black text-slate-900`,children:x?.id?`Edit Category`:`New Category`}),(0,p.jsx)(`p`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-widest mt-1`,children:`Configure category properties`})]}),(0,p.jsx)(`button`,{onClick:()=>b(!1),className:`w-12 h-12 bg-slate-50 rounded-2xl flex items-center justify-center text-slate-400 hover:text-rose-500 transition-all`,children:(0,p.jsx)(i,{size:24})})]}),(0,p.jsxs)(`form`,{onSubmit:w,className:`p-10 space-y-8`,children:[(0,p.jsxs)(`div`,{className:`space-y-4`,children:[(0,p.jsx)(`label`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em] ml-2`,children:`Category Name`}),(0,p.jsx)(`input`,{autoFocus:!0,required:!0,type:`text`,value:x?.name||``,onChange:e=>S({...x,name:e.target.value}),className:`w-full bg-slate-50 border border-slate-100 rounded-2xl py-5 px-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all`,placeholder:`e.g. FAST FOOD`})]}),(0,p.jsxs)(`div`,{className:`space-y-4`,children:[(0,p.jsx)(`label`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em] ml-2`,children:`Description`}),(0,p.jsx)(`textarea`,{value:x?.description||``,onChange:e=>S({...x,description:e.target.value}),className:`w-full bg-slate-50 border border-slate-100 rounded-2xl py-5 px-8 text-sm font-semibold outline-none focus:bg-white focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all h-32 resize-none`,placeholder:`Tell us more about this category...`})]}),(0,p.jsxs)(`div`,{className:`flex items-center gap-4 bg-slate-50 p-6 rounded-3xl border border-slate-100`,children:[(0,p.jsxs)(`div`,{className:`flex-1`,children:[(0,p.jsx)(`p`,{className:`text-sm font-black text-slate-800`,children:`Status`}),(0,p.jsx)(`p`,{className:`text-[10px] font-bold text-slate-400 uppercase tracking-widest`,children:`Enable or disable category visibility`})]}),(0,p.jsx)(`button`,{type:`button`,onClick:()=>S({...x,active:!x.active}),className:`w-16 h-8 rounded-full transition-all relative ${x?.active?`bg-primary`:`bg-slate-300`}`,children:(0,p.jsx)(`div`,{className:`absolute top-1 w-6 h-6 bg-white rounded-full transition-all ${x?.active?`right-1`:`left-1`}`})})]}),(0,p.jsxs)(`div`,{className:`flex gap-4 pt-4`,children:[(0,p.jsx)(`button`,{type:`button`,onClick:()=>b(!1),className:`flex-1 py-5 rounded-2xl font-black text-xs uppercase tracking-widest text-slate-400 hover:bg-slate-50 transition-all border border-transparent hover:border-slate-100`,children:`Cancel`}),(0,p.jsxs)(`button`,{type:`submit`,className:`flex-1 bg-primary text-white py-5 rounded-2xl font-black text-xs uppercase tracking-widest shadow-xl shadow-primary/20 hover:scale-[1.02] active:scale-95 transition-all flex items-center justify-center gap-2`,children:[(0,p.jsx)(r,{size:18}),` `,x?.id?`Update Category`:`Save Category`]})]})]})]})]})]})},g=({icon:e,label:t,value:n,color:r})=>(0,p.jsxs)(`div`,{className:`bg-white p-8 rounded-[2.8rem] border border-slate-100 shadow-sm flex items-center gap-8 group hover:shadow-2xl transition-all`,children:[(0,p.jsx)(`div`,{className:`w-16 h-16 rounded-[1.5rem] flex items-center justify-center group-hover:bg-primary group-hover:text-white transition-all ${r.split(` `)[0]} ${r.split(` `)[1]}`,children:(0,p.jsx)(e,{size:32})}),(0,p.jsxs)(`div`,{children:[(0,p.jsx)(`p`,{className:`text-3xl font-black text-slate-900 tracking-tighter`,children:n}),(0,p.jsx)(`p`,{className:`text-[10px] font-black text-slate-400 uppercase tracking-[0.2em]`,children:t})]})]});export{h as default}; \ No newline at end of file diff --git a/counter-frontend/dist/assets/Login-BRQ0DsVn.js b/counter-frontend/dist/assets/Login-D9pMAuPm.js similarity index 80% rename from counter-frontend/dist/assets/Login-BRQ0DsVn.js rename to counter-frontend/dist/assets/Login-D9pMAuPm.js index 82915a6b..6e965d25 100644 --- a/counter-frontend/dist/assets/Login-BRQ0DsVn.js +++ b/counter-frontend/dist/assets/Login-D9pMAuPm.js @@ -1 +1 @@ -import{c as e,l as t,m as n,n as r,r as i,t as a,u as o}from"./index-Cw6Vy2ED.js";import{t as s}from"./proxy-D2DvKtgS.js";var c=e(`arrow-right`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]),l=e(`eye-off`,[[`path`,{d:`M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49`,key:`ct8e1f`}],[`path`,{d:`M14.084 14.158a3 3 0 0 1-4.242-4.242`,key:`151rxh`}],[`path`,{d:`M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143`,key:`13bj9a`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),u=e(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),d=e(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),f=n(o(),1),p=`/assets/ritchennai-Cj5SDFG-.webp`,m=a(),h=()=>{let[e,n]=(0,f.useState)(!1),[a,o]=(0,f.useState)(``),[h,g]=(0,f.useState)(``),_=t();return(0,f.useEffect)(()=>{sessionStorage.removeItem(`isCounterLoggedIn`),sessionStorage.removeItem(`counterUserName`)},[]),(0,m.jsxs)(`div`,{className:`min-h-screen bg-[#f8fafc] flex flex-col md:flex-row overflow-hidden font-inter`,children:[(0,m.jsxs)(`div`,{className:`w-full md:w-[45%] lg:w-[40%] flex flex-col p-8 md:p-12 lg:p-16 relative z-10 bg-white shadow-2xl`,children:[(0,m.jsxs)(s.div,{initial:{opacity:0,y:-20},animate:{opacity:1,y:0},className:`mb-10 flex flex-col items-center justify-center`,children:[(0,m.jsx)(`img`,{src:r,alt:`College Logo`,className:`h-16 md:h-20 object-contain`}),(0,m.jsx)(`span`,{className:`text-[10px] font-semibold text-slate-400 mt-2 italic tracking-wide font-sans`,children:`Till yo tummy is full...`})]}),(0,m.jsxs)(s.div,{initial:{opacity:0,x:-30},animate:{opacity:1,x:0},transition:{delay:.2},className:`flex-1 flex flex-col justify-center max-w-sm mx-auto w-full`,children:[(0,m.jsxs)(`div`,{className:`text-center mb-10`,children:[(0,m.jsx)(`h2`,{className:`text-[10px] font-black tracking-[0.3em] text-[#1e293b] uppercase mb-2`,children:`Counter Management System`}),(0,m.jsx)(`div`,{className:`w-12 h-1 bg-primary mx-auto rounded-full`})]}),(0,m.jsxs)(`form`,{onSubmit:async e=>{e.preventDefault();try{let e=await fetch(`https://cmsapi.rit-services.in/api/system/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({email:a,password:h})}),t=await e.json();e.ok&&t.token&&(t.role===`MANAGER`||t.role===`MASTER`)?(sessionStorage.setItem(`isCounterLoggedIn`,`true`),sessionStorage.setItem(`counterUserName`,t.name),sessionStorage.setItem(`counterToken`,t.token),_(`/pos`)):a===`krishna`&&h===`12345678`?(sessionStorage.setItem(`isCounterLoggedIn`,`true`),sessionStorage.setItem(`counterUserName`,`Krishna`),_(`/pos`)):alert(t.error||`Invalid credentials or access denied`)}catch(e){a===`krishna`&&h===`12345678`?(sessionStorage.setItem(`isCounterLoggedIn`,`true`),sessionStorage.setItem(`counterUserName`,`Krishna`),_(`/pos`)):(console.error(e),alert(`Connection error or invalid credentials`))}},className:`space-y-6`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{className:`text-[10px] font-black text-[#94a3b8] uppercase tracking-widest pl-1`,children:`Operator ID`}),(0,m.jsxs)(`div`,{className:`relative group`,children:[(0,m.jsx)(`div`,{className:`absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none text-[#94a3b8] group-focus-within:text-primary transition-colors`,children:(0,m.jsx)(i,{size:18})}),(0,m.jsx)(`input`,{type:`text`,value:a,onChange:e=>o(e.target.value),placeholder:`Username`,className:`w-full bg-white border-2 border-[#e2e8f0] focus:border-primary rounded-2xl py-4 pl-12 pr-4 text-sm font-semibold outline-none transition-all placeholder:text-[#cbd5e1]`})]})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsxs)(`div`,{className:`flex justify-between items-center pl-1`,children:[(0,m.jsx)(`label`,{className:`text-[10px] font-black text-[#94a3b8] uppercase tracking-widest`,children:`Passcode`}),(0,m.jsx)(`button`,{type:`button`,className:`text-[10px] font-black text-primary uppercase hover:underline`,children:`Forgot?`})]}),(0,m.jsxs)(`div`,{className:`relative group`,children:[(0,m.jsx)(`div`,{className:`absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none text-[#94a3b8] group-focus-within:text-primary transition-colors`,children:(0,m.jsx)(d,{size:18})}),(0,m.jsx)(`input`,{type:e?`text`:`password`,value:h,onChange:e=>g(e.target.value),placeholder:`••••••••`,className:`w-full bg-white border-2 border-[#e2e8f0] focus:border-primary rounded-2xl py-4 pl-12 pr-12 text-sm font-semibold outline-none transition-all placeholder:text-[#cbd5e1]`}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>n(!e),className:`absolute inset-y-0 right-0 pr-4 flex items-center text-[#94a3b8] hover:text-[#64748b] transition-colors`,children:e?(0,m.jsx)(l,{size:18}):(0,m.jsx)(u,{size:18})})]})]}),(0,m.jsxs)(`button`,{type:`submit`,className:`w-full bg-primary text-white rounded-2xl py-4 font-black text-sm flex items-center justify-center gap-3 shadow-xl shadow-primary/20 hover:scale-[1.02] active:scale-[0.98] transition-all overflow-hidden group relative`,children:[(0,m.jsx)(`span`,{className:`relative z-10`,children:`CONNECT TO POS`}),(0,m.jsx)(c,{size:18,className:`relative z-10 group-hover:translate-x-1 transition-transform`}),(0,m.jsx)(s.div,{className:`absolute inset-0 bg-white/10`,initial:{x:`-100%`},whileHover:{x:`100%`},transition:{duration:.6}})]})]})]}),(0,m.jsx)(`div`,{className:`mt-auto text-center`,children:(0,m.jsx)(`p`,{className:`text-[10px] font-black text-[#cbd5e1] uppercase tracking-[0.2em]`,children:`© 2026 TILLO • COUNTER SYSTEM`})})]}),(0,m.jsxs)(`div`,{className:`hidden md:flex flex-1 relative bg-[#f8fafc] items-center justify-center p-8 overflow-hidden`,children:[(0,m.jsx)(`div`,{className:`absolute top-20 right-20 w-64 h-64 bg-primary/5 rounded-full blur-3xl`}),(0,m.jsx)(`div`,{className:`absolute bottom-20 left-40 w-96 h-96 bg-primary/5 rounded-full blur-3xl`}),(0,m.jsx)(s.div,{initial:{opacity:0,scale:.95,x:50},animate:{opacity:1,scale:1,x:0},transition:{duration:.8},className:`w-full h-full relative z-10`,children:(0,m.jsxs)(`div`,{className:`w-full h-full overflow-hidden shadow-2xl border-[12px] border-white bg-white`,children:[(0,m.jsx)(`img`,{src:p,alt:`Tillo Building`,className:`w-full h-full object-cover`}),(0,m.jsx)(`div`,{className:`absolute inset-0 bg-gradient-to-tr from-primary/20 to-transparent`})]})})]})]})};export{h as default}; \ No newline at end of file +import{t as e}from"./proxy-cLldRXEc.js";import{c as t,g as n,h as r,m as i,n as a,s as o,t as s}from"./index-B-Yfb7Zz.js";var c=o(`arrow-right`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]),l=o(`eye-off`,[[`path`,{d:`M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49`,key:`ct8e1f`}],[`path`,{d:`M14.084 14.158a3 3 0 0 1-4.242-4.242`,key:`151rxh`}],[`path`,{d:`M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143`,key:`13bj9a`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),u=o(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),d=o(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),f=n(r(),1),p=`/assets/ritchennai-Cj5SDFG-.webp`,m=i(),h=()=>{let[n,r]=(0,f.useState)(!1),[i,o]=(0,f.useState)(``),[h,g]=(0,f.useState)(``),_=t();return(0,f.useEffect)(()=>{sessionStorage.removeItem(`isCounterLoggedIn`),sessionStorage.removeItem(`counterUserName`)},[]),(0,m.jsxs)(`div`,{className:`min-h-screen bg-[#f8fafc] flex flex-col md:flex-row overflow-hidden font-inter`,children:[(0,m.jsxs)(`div`,{className:`w-full md:w-[45%] lg:w-[40%] flex flex-col p-8 md:p-12 lg:p-16 relative z-10 bg-white shadow-2xl`,children:[(0,m.jsxs)(e.div,{initial:{opacity:0,y:-20},animate:{opacity:1,y:0},className:`mb-10 flex flex-col items-center justify-center`,children:[(0,m.jsx)(`img`,{src:s,alt:`College Logo`,className:`h-16 md:h-20 object-contain`}),(0,m.jsx)(`span`,{className:`text-[10px] font-semibold text-slate-400 mt-2 italic tracking-wide font-sans`,children:`Till yo tummy is full...`})]}),(0,m.jsxs)(e.div,{initial:{opacity:0,x:-30},animate:{opacity:1,x:0},transition:{delay:.2},className:`flex-1 flex flex-col justify-center max-w-sm mx-auto w-full`,children:[(0,m.jsxs)(`div`,{className:`text-center mb-10`,children:[(0,m.jsx)(`h2`,{className:`text-[10px] font-black tracking-[0.3em] text-[#1e293b] uppercase mb-2`,children:`Counter Management System`}),(0,m.jsx)(`div`,{className:`w-12 h-1 bg-primary mx-auto rounded-full`})]}),(0,m.jsxs)(`form`,{onSubmit:async e=>{e.preventDefault();try{let e=await fetch(`https://cmsapi.rit-services.in/api/system/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({email:i,password:h})}),t=await e.json();e.ok&&t.token&&(t.role===`MANAGER`||t.role===`MASTER`)?(sessionStorage.setItem(`isCounterLoggedIn`,`true`),sessionStorage.setItem(`counterUserName`,t.name),sessionStorage.setItem(`counterToken`,t.token),_(`/pos`)):i===`krishna`&&h===`12345678`?(sessionStorage.setItem(`isCounterLoggedIn`,`true`),sessionStorage.setItem(`counterUserName`,`Krishna`),_(`/pos`)):alert(t.error||`Invalid credentials or access denied`)}catch(e){i===`krishna`&&h===`12345678`?(sessionStorage.setItem(`isCounterLoggedIn`,`true`),sessionStorage.setItem(`counterUserName`,`Krishna`),_(`/pos`)):(console.error(e),alert(`Connection error or invalid credentials`))}},className:`space-y-6`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{className:`text-[10px] font-black text-[#94a3b8] uppercase tracking-widest pl-1`,children:`Operator ID`}),(0,m.jsxs)(`div`,{className:`relative group`,children:[(0,m.jsx)(`div`,{className:`absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none text-[#94a3b8] group-focus-within:text-primary transition-colors`,children:(0,m.jsx)(a,{size:18})}),(0,m.jsx)(`input`,{type:`text`,value:i,onChange:e=>o(e.target.value),placeholder:`Username`,className:`w-full bg-white border-2 border-[#e2e8f0] focus:border-primary rounded-2xl py-4 pl-12 pr-4 text-sm font-semibold outline-none transition-all placeholder:text-[#cbd5e1]`})]})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsxs)(`div`,{className:`flex justify-between items-center pl-1`,children:[(0,m.jsx)(`label`,{className:`text-[10px] font-black text-[#94a3b8] uppercase tracking-widest`,children:`Passcode`}),(0,m.jsx)(`button`,{type:`button`,className:`text-[10px] font-black text-primary uppercase hover:underline`,children:`Forgot?`})]}),(0,m.jsxs)(`div`,{className:`relative group`,children:[(0,m.jsx)(`div`,{className:`absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none text-[#94a3b8] group-focus-within:text-primary transition-colors`,children:(0,m.jsx)(d,{size:18})}),(0,m.jsx)(`input`,{type:n?`text`:`password`,value:h,onChange:e=>g(e.target.value),placeholder:`••••••••`,className:`w-full bg-white border-2 border-[#e2e8f0] focus:border-primary rounded-2xl py-4 pl-12 pr-12 text-sm font-semibold outline-none transition-all placeholder:text-[#cbd5e1]`}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>r(!n),className:`absolute inset-y-0 right-0 pr-4 flex items-center text-[#94a3b8] hover:text-[#64748b] transition-colors`,children:n?(0,m.jsx)(l,{size:18}):(0,m.jsx)(u,{size:18})})]})]}),(0,m.jsxs)(`button`,{type:`submit`,className:`w-full bg-primary text-white rounded-2xl py-4 font-black text-sm flex items-center justify-center gap-3 shadow-xl shadow-primary/20 hover:scale-[1.02] active:scale-[0.98] transition-all overflow-hidden group relative`,children:[(0,m.jsx)(`span`,{className:`relative z-10`,children:`CONNECT TO POS`}),(0,m.jsx)(c,{size:18,className:`relative z-10 group-hover:translate-x-1 transition-transform`}),(0,m.jsx)(e.div,{className:`absolute inset-0 bg-white/10`,initial:{x:`-100%`},whileHover:{x:`100%`},transition:{duration:.6}})]})]})]}),(0,m.jsx)(`div`,{className:`mt-auto text-center`,children:(0,m.jsx)(`p`,{className:`text-[10px] font-black text-[#cbd5e1] uppercase tracking-[0.2em]`,children:`© 2026 TILLO • COUNTER SYSTEM`})})]}),(0,m.jsxs)(`div`,{className:`hidden md:flex flex-1 relative bg-[#f8fafc] items-center justify-center p-8 overflow-hidden`,children:[(0,m.jsx)(`div`,{className:`absolute top-20 right-20 w-64 h-64 bg-primary/5 rounded-full blur-3xl`}),(0,m.jsx)(`div`,{className:`absolute bottom-20 left-40 w-96 h-96 bg-primary/5 rounded-full blur-3xl`}),(0,m.jsx)(e.div,{initial:{opacity:0,scale:.95,x:50},animate:{opacity:1,scale:1,x:0},transition:{duration:.8},className:`w-full h-full relative z-10`,children:(0,m.jsxs)(`div`,{className:`w-full h-full overflow-hidden shadow-2xl border-[12px] border-white bg-white`,children:[(0,m.jsx)(`img`,{src:p,alt:`Tillo Building`,className:`w-full h-full object-cover`}),(0,m.jsx)(`div`,{className:`absolute inset-0 bg-gradient-to-tr from-primary/20 to-transparent`})]})})]})]})};export{h as default}; \ No newline at end of file diff --git a/counter-frontend/dist/assets/Orders-BqkxCVX3.js b/counter-frontend/dist/assets/Orders-BqkxCVX3.js new file mode 100644 index 00000000..121c11d7 --- /dev/null +++ b/counter-frontend/dist/assets/Orders-BqkxCVX3.js @@ -0,0 +1,71 @@ +import{n as e,r as t,t as n}from"./x-CnVgnJPD.js";import{t as r}from"./Pagination-BYvNtzJC.js";import{t as i}from"./minus-wD8f4ZO0.js";import{t as a}from"./plus-CtPxjhzP.js";import{t as o}from"./trash-2-B3saCmcm.js";import{g as s,h as c,i as l,m as u,n as d,r as f,s as p}from"./index-B-Yfb7Zz.js";var m=p(`calendar`,[[`path`,{d:`M8 2v4`,key:`1cmpym`}],[`path`,{d:`M16 2v4`,key:`4m81vk`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`4`,rx:`2`,key:`1hopcy`}],[`path`,{d:`M3 10h18`,key:`8toen8`}]]),h=p(`credit-card`,[[`rect`,{width:`20`,height:`14`,x:`2`,y:`5`,rx:`2`,key:`ynyp8z`}],[`line`,{x1:`2`,x2:`22`,y1:`10`,y2:`10`,key:`1b3vmo`}]]),g=p(`ellipsis-vertical`,[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`12`,cy:`5`,r:`1`,key:`gxeob9`}],[`circle`,{cx:`12`,cy:`19`,r:`1`,key:`lyex9k`}]]),_=p(`funnel`,[[`path`,{d:`M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z`,key:`sc7q7i`}]]),v=p(`printer`,[[`path`,{d:`M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2`,key:`143wyd`}],[`path`,{d:`M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6`,key:`1itne7`}],[`rect`,{x:`6`,y:`14`,width:`12`,height:`8`,rx:`1`,key:`1ue0tg`}]]),y=p(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),ee=p(`rotate-ccw`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]]),b=365.2425,x=6048e5,S=864e5,C=3600*24;C*7,C*b/12*3;var w=Symbol.for(`constructDateFrom`);function T(e,t){return typeof e==`function`?e(t):e&&typeof e==`object`&&w in e?e[w](t):e instanceof Date?new e.constructor(t):new Date(t)}function E(e,t){return T(t||e,e)}var te={};function D(){return te}function O(e,t){let n=D(),r=t?.weekStartsOn??t?.locale?.options?.weekStartsOn??n.weekStartsOn??n.locale?.options?.weekStartsOn??0,i=E(e,t?.in),a=i.getDay(),o=(a=a.getTime()?r+1:n.getTime()>=s.getTime()?r:r-1}function j(e){let t=E(e),n=new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getMilliseconds()));return n.setUTCFullYear(t.getFullYear()),e-+n}function ne(e,...t){let n=T.bind(null,e||t.find(e=>typeof e==`object`));return t.map(n)}function M(e,t){let n=E(e,t?.in);return n.setHours(0,0,0,0),n}function re(e,t,n){let[r,i]=ne(n?.in,e,t),a=M(r),o=M(i),s=+a-j(a),c=+o-j(o);return Math.round((s-c)/S)}function ie(e,t){let n=A(e,t),r=T(t?.in||e,0);return r.setFullYear(n,0,4),r.setHours(0,0,0,0),k(r)}function ae(e){return e instanceof Date||typeof e==`object`&&Object.prototype.toString.call(e)===`[object Date]`}function N(e){return!(!ae(e)&&typeof e!=`number`||isNaN(+E(e)))}function oe(e,t){let n=E(e,t?.in);return n.setFullYear(n.getFullYear(),0,1),n.setHours(0,0,0,0),n}var se={lessThanXSeconds:{one:`less than a second`,other:`less than {{count}} seconds`},xSeconds:{one:`1 second`,other:`{{count}} seconds`},halfAMinute:`half a minute`,lessThanXMinutes:{one:`less than a minute`,other:`less than {{count}} minutes`},xMinutes:{one:`1 minute`,other:`{{count}} minutes`},aboutXHours:{one:`about 1 hour`,other:`about {{count}} hours`},xHours:{one:`1 hour`,other:`{{count}} hours`},xDays:{one:`1 day`,other:`{{count}} days`},aboutXWeeks:{one:`about 1 week`,other:`about {{count}} weeks`},xWeeks:{one:`1 week`,other:`{{count}} weeks`},aboutXMonths:{one:`about 1 month`,other:`about {{count}} months`},xMonths:{one:`1 month`,other:`{{count}} months`},aboutXYears:{one:`about 1 year`,other:`about {{count}} years`},xYears:{one:`1 year`,other:`{{count}} years`},overXYears:{one:`over 1 year`,other:`over {{count}} years`},almostXYears:{one:`almost 1 year`,other:`almost {{count}} years`}},P=(e,t,n)=>{let r,i=se[e];return r=typeof i==`string`?i:t===1?i.one:i.other.replace(`{{count}}`,t.toString()),n?.addSuffix?n.comparison&&n.comparison>0?`in `+r:r+` ago`:r};function F(e){return(t={})=>{let n=t.width?String(t.width):e.defaultWidth;return e.formats[n]||e.formats[e.defaultWidth]}}var I={date:F({formats:{full:`EEEE, MMMM do, y`,long:`MMMM do, y`,medium:`MMM d, y`,short:`MM/dd/yyyy`},defaultWidth:`full`}),time:F({formats:{full:`h:mm:ss a zzzz`,long:`h:mm:ss a z`,medium:`h:mm:ss a`,short:`h:mm a`},defaultWidth:`full`}),dateTime:F({formats:{full:`{{date}} 'at' {{time}}`,long:`{{date}} 'at' {{time}}`,medium:`{{date}}, {{time}}`,short:`{{date}}, {{time}}`},defaultWidth:`full`})},ce={lastWeek:`'last' eeee 'at' p`,yesterday:`'yesterday at' p`,today:`'today at' p`,tomorrow:`'tomorrow at' p`,nextWeek:`eeee 'at' p`,other:`P`},le=(e,t,n,r)=>ce[e];function L(e){return(t,n)=>{let r=n?.context?String(n.context):`standalone`,i;if(r===`formatting`&&e.formattingValues){let t=e.defaultFormattingWidth||e.defaultWidth,r=n?.width?String(n.width):t;i=e.formattingValues[r]||e.formattingValues[t]}else{let t=e.defaultWidth,r=n?.width?String(n.width):e.defaultWidth;i=e.values[r]||e.values[t]}let a=e.argumentCallback?e.argumentCallback(t):t;return i[a]}}var ue={ordinalNumber:(e,t)=>{let n=Number(e),r=n%100;if(r>20||r<10)switch(r%10){case 1:return n+`st`;case 2:return n+`nd`;case 3:return n+`rd`}return n+`th`},era:L({values:{narrow:[`B`,`A`],abbreviated:[`BC`,`AD`],wide:[`Before Christ`,`Anno Domini`]},defaultWidth:`wide`}),quarter:L({values:{narrow:[`1`,`2`,`3`,`4`],abbreviated:[`Q1`,`Q2`,`Q3`,`Q4`],wide:[`1st quarter`,`2nd quarter`,`3rd quarter`,`4th quarter`]},defaultWidth:`wide`,argumentCallback:e=>e-1}),month:L({values:{narrow:[`J`,`F`,`M`,`A`,`M`,`J`,`J`,`A`,`S`,`O`,`N`,`D`],abbreviated:[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],wide:[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`]},defaultWidth:`wide`}),day:L({values:{narrow:[`S`,`M`,`T`,`W`,`T`,`F`,`S`],short:[`Su`,`Mo`,`Tu`,`We`,`Th`,`Fr`,`Sa`],abbreviated:[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],wide:[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`]},defaultWidth:`wide`}),dayPeriod:L({values:{narrow:{am:`a`,pm:`p`,midnight:`mi`,noon:`n`,morning:`morning`,afternoon:`afternoon`,evening:`evening`,night:`night`},abbreviated:{am:`AM`,pm:`PM`,midnight:`midnight`,noon:`noon`,morning:`morning`,afternoon:`afternoon`,evening:`evening`,night:`night`},wide:{am:`a.m.`,pm:`p.m.`,midnight:`midnight`,noon:`noon`,morning:`morning`,afternoon:`afternoon`,evening:`evening`,night:`night`}},defaultWidth:`wide`,formattingValues:{narrow:{am:`a`,pm:`p`,midnight:`mi`,noon:`n`,morning:`in the morning`,afternoon:`in the afternoon`,evening:`in the evening`,night:`at night`},abbreviated:{am:`AM`,pm:`PM`,midnight:`midnight`,noon:`noon`,morning:`in the morning`,afternoon:`in the afternoon`,evening:`in the evening`,night:`at night`},wide:{am:`a.m.`,pm:`p.m.`,midnight:`midnight`,noon:`noon`,morning:`in the morning`,afternoon:`in the afternoon`,evening:`in the evening`,night:`at night`}},defaultFormattingWidth:`wide`})};function R(e){return(t,n={})=>{let r=n.width,i=r&&e.matchPatterns[r]||e.matchPatterns[e.defaultMatchWidth],a=t.match(i);if(!a)return null;let o=a[0],s=r&&e.parsePatterns[r]||e.parsePatterns[e.defaultParseWidth],c=Array.isArray(s)?B(s,e=>e.test(o)):z(s,e=>e.test(o)),l;l=e.valueCallback?e.valueCallback(c):c,l=n.valueCallback?n.valueCallback(l):l;let u=t.slice(o.length);return{value:l,rest:u}}}function z(e,t){for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&t(e[n]))return n}function B(e,t){for(let n=0;n{let r=t.match(e.matchPattern);if(!r)return null;let i=r[0],a=t.match(e.parsePattern);if(!a)return null;let o=e.valueCallback?e.valueCallback(a[0]):a[0];o=n.valueCallback?n.valueCallback(o):o;let s=t.slice(i.length);return{value:o,rest:s}}}var fe={code:`en-US`,formatDistance:P,formatLong:I,formatRelative:le,localize:ue,match:{ordinalNumber:de({matchPattern:/^(\d+)(th|st|nd|rd)?/i,parsePattern:/\d+/i,valueCallback:e=>parseInt(e,10)}),era:R({matchPatterns:{narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},defaultMatchWidth:`wide`,parsePatterns:{any:[/^b/i,/^(a|c)/i]},defaultParseWidth:`any`}),quarter:R({matchPatterns:{narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},defaultMatchWidth:`wide`,parsePatterns:{any:[/1/i,/2/i,/3/i,/4/i]},defaultParseWidth:`any`,valueCallback:e=>e+1}),month:R({matchPatterns:{narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},defaultMatchWidth:`wide`,parsePatterns:{narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},defaultParseWidth:`any`}),day:R({matchPatterns:{narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},defaultMatchWidth:`wide`,parsePatterns:{narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},defaultParseWidth:`any`}),dayPeriod:R({matchPatterns:{narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},defaultMatchWidth:`any`,parsePatterns:{any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},defaultParseWidth:`any`})},options:{weekStartsOn:0,firstWeekContainsDate:1}};function pe(e,t){let n=E(e,t?.in);return re(n,oe(n))+1}function V(e,t){let n=E(e,t?.in),r=k(n)-+ie(n);return Math.round(r/x)+1}function H(e,t){let n=E(e,t?.in),r=n.getFullYear(),i=D(),a=t?.firstWeekContainsDate??t?.locale?.options?.firstWeekContainsDate??i.firstWeekContainsDate??i.locale?.options?.firstWeekContainsDate??1,o=T(t?.in||e,0);o.setFullYear(r+1,0,a),o.setHours(0,0,0,0);let s=O(o,t),c=T(t?.in||e,0);c.setFullYear(r,0,a),c.setHours(0,0,0,0);let l=O(c,t);return+n>=+s?r+1:+n>=+l?r:r-1}function me(e,t){let n=D(),r=t?.firstWeekContainsDate??t?.locale?.options?.firstWeekContainsDate??n.firstWeekContainsDate??n.locale?.options?.firstWeekContainsDate??1,i=H(e,t),a=T(t?.in||e,0);return a.setFullYear(i,0,r),a.setHours(0,0,0,0),O(a,t)}function U(e,t){let n=E(e,t?.in),r=O(n,t)-+me(n,t);return Math.round(r/x)+1}function W(e,t){return(e<0?`-`:``)+Math.abs(e).toString().padStart(t,`0`)}var G={y(e,t){let n=e.getFullYear(),r=n>0?n:1-n;return W(t===`yy`?r%100:r,t.length)},M(e,t){let n=e.getMonth();return t===`M`?String(n+1):W(n+1,2)},d(e,t){return W(e.getDate(),t.length)},a(e,t){let n=e.getHours()/12>=1?`pm`:`am`;switch(t){case`a`:case`aa`:return n.toUpperCase();case`aaa`:return n;case`aaaaa`:return n[0];default:return n===`am`?`a.m.`:`p.m.`}},h(e,t){return W(e.getHours()%12||12,t.length)},H(e,t){return W(e.getHours(),t.length)},m(e,t){return W(e.getMinutes(),t.length)},s(e,t){return W(e.getSeconds(),t.length)},S(e,t){let n=t.length,r=e.getMilliseconds();return W(Math.trunc(r*10**(n-3)),t.length)}},K={am:`am`,pm:`pm`,midnight:`midnight`,noon:`noon`,morning:`morning`,afternoon:`afternoon`,evening:`evening`,night:`night`},he={G:function(e,t,n){let r=+(e.getFullYear()>0);switch(t){case`G`:case`GG`:case`GGG`:return n.era(r,{width:`abbreviated`});case`GGGGG`:return n.era(r,{width:`narrow`});default:return n.era(r,{width:`wide`})}},y:function(e,t,n){if(t===`yo`){let t=e.getFullYear(),r=t>0?t:1-t;return n.ordinalNumber(r,{unit:`year`})}return G.y(e,t)},Y:function(e,t,n,r){let i=H(e,r),a=i>0?i:1-i;return t===`YY`?W(a%100,2):t===`Yo`?n.ordinalNumber(a,{unit:`year`}):W(a,t.length)},R:function(e,t){return W(A(e),t.length)},u:function(e,t){return W(e.getFullYear(),t.length)},Q:function(e,t,n){let r=Math.ceil((e.getMonth()+1)/3);switch(t){case`Q`:return String(r);case`QQ`:return W(r,2);case`Qo`:return n.ordinalNumber(r,{unit:`quarter`});case`QQQ`:return n.quarter(r,{width:`abbreviated`,context:`formatting`});case`QQQQQ`:return n.quarter(r,{width:`narrow`,context:`formatting`});default:return n.quarter(r,{width:`wide`,context:`formatting`})}},q:function(e,t,n){let r=Math.ceil((e.getMonth()+1)/3);switch(t){case`q`:return String(r);case`qq`:return W(r,2);case`qo`:return n.ordinalNumber(r,{unit:`quarter`});case`qqq`:return n.quarter(r,{width:`abbreviated`,context:`standalone`});case`qqqqq`:return n.quarter(r,{width:`narrow`,context:`standalone`});default:return n.quarter(r,{width:`wide`,context:`standalone`})}},M:function(e,t,n){let r=e.getMonth();switch(t){case`M`:case`MM`:return G.M(e,t);case`Mo`:return n.ordinalNumber(r+1,{unit:`month`});case`MMM`:return n.month(r,{width:`abbreviated`,context:`formatting`});case`MMMMM`:return n.month(r,{width:`narrow`,context:`formatting`});default:return n.month(r,{width:`wide`,context:`formatting`})}},L:function(e,t,n){let r=e.getMonth();switch(t){case`L`:return String(r+1);case`LL`:return W(r+1,2);case`Lo`:return n.ordinalNumber(r+1,{unit:`month`});case`LLL`:return n.month(r,{width:`abbreviated`,context:`standalone`});case`LLLLL`:return n.month(r,{width:`narrow`,context:`standalone`});default:return n.month(r,{width:`wide`,context:`standalone`})}},w:function(e,t,n,r){let i=U(e,r);return t===`wo`?n.ordinalNumber(i,{unit:`week`}):W(i,t.length)},I:function(e,t,n){let r=V(e);return t===`Io`?n.ordinalNumber(r,{unit:`week`}):W(r,t.length)},d:function(e,t,n){return t===`do`?n.ordinalNumber(e.getDate(),{unit:`date`}):G.d(e,t)},D:function(e,t,n){let r=pe(e);return t===`Do`?n.ordinalNumber(r,{unit:`dayOfYear`}):W(r,t.length)},E:function(e,t,n){let r=e.getDay();switch(t){case`E`:case`EE`:case`EEE`:return n.day(r,{width:`abbreviated`,context:`formatting`});case`EEEEE`:return n.day(r,{width:`narrow`,context:`formatting`});case`EEEEEE`:return n.day(r,{width:`short`,context:`formatting`});default:return n.day(r,{width:`wide`,context:`formatting`})}},e:function(e,t,n,r){let i=e.getDay(),a=(i-r.weekStartsOn+8)%7||7;switch(t){case`e`:return String(a);case`ee`:return W(a,2);case`eo`:return n.ordinalNumber(a,{unit:`day`});case`eee`:return n.day(i,{width:`abbreviated`,context:`formatting`});case`eeeee`:return n.day(i,{width:`narrow`,context:`formatting`});case`eeeeee`:return n.day(i,{width:`short`,context:`formatting`});default:return n.day(i,{width:`wide`,context:`formatting`})}},c:function(e,t,n,r){let i=e.getDay(),a=(i-r.weekStartsOn+8)%7||7;switch(t){case`c`:return String(a);case`cc`:return W(a,t.length);case`co`:return n.ordinalNumber(a,{unit:`day`});case`ccc`:return n.day(i,{width:`abbreviated`,context:`standalone`});case`ccccc`:return n.day(i,{width:`narrow`,context:`standalone`});case`cccccc`:return n.day(i,{width:`short`,context:`standalone`});default:return n.day(i,{width:`wide`,context:`standalone`})}},i:function(e,t,n){let r=e.getDay(),i=r===0?7:r;switch(t){case`i`:return String(i);case`ii`:return W(i,t.length);case`io`:return n.ordinalNumber(i,{unit:`day`});case`iii`:return n.day(r,{width:`abbreviated`,context:`formatting`});case`iiiii`:return n.day(r,{width:`narrow`,context:`formatting`});case`iiiiii`:return n.day(r,{width:`short`,context:`formatting`});default:return n.day(r,{width:`wide`,context:`formatting`})}},a:function(e,t,n){let r=e.getHours()/12>=1?`pm`:`am`;switch(t){case`a`:case`aa`:return n.dayPeriod(r,{width:`abbreviated`,context:`formatting`});case`aaa`:return n.dayPeriod(r,{width:`abbreviated`,context:`formatting`}).toLowerCase();case`aaaaa`:return n.dayPeriod(r,{width:`narrow`,context:`formatting`});default:return n.dayPeriod(r,{width:`wide`,context:`formatting`})}},b:function(e,t,n){let r=e.getHours(),i;switch(i=r===12?K.noon:r===0?K.midnight:r/12>=1?`pm`:`am`,t){case`b`:case`bb`:return n.dayPeriod(i,{width:`abbreviated`,context:`formatting`});case`bbb`:return n.dayPeriod(i,{width:`abbreviated`,context:`formatting`}).toLowerCase();case`bbbbb`:return n.dayPeriod(i,{width:`narrow`,context:`formatting`});default:return n.dayPeriod(i,{width:`wide`,context:`formatting`})}},B:function(e,t,n){let r=e.getHours(),i;switch(i=r>=17?K.evening:r>=12?K.afternoon:r>=4?K.morning:K.night,t){case`B`:case`BB`:case`BBB`:return n.dayPeriod(i,{width:`abbreviated`,context:`formatting`});case`BBBBB`:return n.dayPeriod(i,{width:`narrow`,context:`formatting`});default:return n.dayPeriod(i,{width:`wide`,context:`formatting`})}},h:function(e,t,n){if(t===`ho`){let t=e.getHours()%12;return t===0&&(t=12),n.ordinalNumber(t,{unit:`hour`})}return G.h(e,t)},H:function(e,t,n){return t===`Ho`?n.ordinalNumber(e.getHours(),{unit:`hour`}):G.H(e,t)},K:function(e,t,n){let r=e.getHours()%12;return t===`Ko`?n.ordinalNumber(r,{unit:`hour`}):W(r,t.length)},k:function(e,t,n){let r=e.getHours();return r===0&&(r=24),t===`ko`?n.ordinalNumber(r,{unit:`hour`}):W(r,t.length)},m:function(e,t,n){return t===`mo`?n.ordinalNumber(e.getMinutes(),{unit:`minute`}):G.m(e,t)},s:function(e,t,n){return t===`so`?n.ordinalNumber(e.getSeconds(),{unit:`second`}):G.s(e,t)},S:function(e,t){return G.S(e,t)},X:function(e,t,n){let r=e.getTimezoneOffset();if(r===0)return`Z`;switch(t){case`X`:return ge(r);case`XXXX`:case`XX`:return J(r);default:return J(r,`:`)}},x:function(e,t,n){let r=e.getTimezoneOffset();switch(t){case`x`:return ge(r);case`xxxx`:case`xx`:return J(r);default:return J(r,`:`)}},O:function(e,t,n){let r=e.getTimezoneOffset();switch(t){case`O`:case`OO`:case`OOO`:return`GMT`+q(r,`:`);default:return`GMT`+J(r,`:`)}},z:function(e,t,n){let r=e.getTimezoneOffset();switch(t){case`z`:case`zz`:case`zzz`:return`GMT`+q(r,`:`);default:return`GMT`+J(r,`:`)}},t:function(e,t,n){return W(Math.trunc(e/1e3),t.length)},T:function(e,t,n){return W(+e,t.length)}};function q(e,t=``){let n=e>0?`-`:`+`,r=Math.abs(e),i=Math.trunc(r/60),a=r%60;return a===0?n+String(i):n+String(i)+t+W(a,2)}function ge(e,t){return e%60==0?(e>0?`-`:`+`)+W(Math.abs(e)/60,2):J(e,t)}function J(e,t=``){let n=e>0?`-`:`+`,r=Math.abs(e),i=W(Math.trunc(r/60),2),a=W(r%60,2);return n+i+t+a}var _e=(e,t)=>{switch(e){case`P`:return t.date({width:`short`});case`PP`:return t.date({width:`medium`});case`PPP`:return t.date({width:`long`});default:return t.date({width:`full`})}},ve=(e,t)=>{switch(e){case`p`:return t.time({width:`short`});case`pp`:return t.time({width:`medium`});case`ppp`:return t.time({width:`long`});default:return t.time({width:`full`})}},ye={p:ve,P:(e,t)=>{let n=e.match(/(P+)(p+)?/)||[],r=n[1],i=n[2];if(!i)return _e(e,t);let a;switch(r){case`P`:a=t.dateTime({width:`short`});break;case`PP`:a=t.dateTime({width:`medium`});break;case`PPP`:a=t.dateTime({width:`long`});break;default:a=t.dateTime({width:`full`});break}return a.replace(`{{date}}`,_e(r,t)).replace(`{{time}}`,ve(i,t))}},be=/^D+$/,xe=/^Y+$/,Se=[`D`,`DD`,`YY`,`YYYY`];function Ce(e){return be.test(e)}function we(e){return xe.test(e)}function Te(e,t,n){let r=Ee(e,t,n);if(console.warn(r),Se.includes(e))throw RangeError(r)}function Ee(e,t,n){let r=e[0]===`Y`?`years`:`days of the month`;return`Use \`${e.toLowerCase()}\` instead of \`${e}\` (in \`${t}\`) for formatting ${r} to the input \`${n}\`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md`}var De=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,Oe=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,ke=/^'([^]*?)'?$/,Ae=/''/g,je=/[a-zA-Z]/;function Y(e,t,n){let r=D(),i=n?.locale??r.locale??fe,a=n?.firstWeekContainsDate??n?.locale?.options?.firstWeekContainsDate??r.firstWeekContainsDate??r.locale?.options?.firstWeekContainsDate??1,o=n?.weekStartsOn??n?.locale?.options?.weekStartsOn??r.weekStartsOn??r.locale?.options?.weekStartsOn??0,s=E(e,n?.in);if(!N(s))throw RangeError(`Invalid time value`);let c=t.match(Oe).map(e=>{let t=e[0];if(t===`p`||t===`P`){let n=ye[t];return n(e,i.formatLong)}return e}).join(``).match(De).map(e=>{if(e===`''`)return{isToken:!1,value:`'`};let t=e[0];if(t===`'`)return{isToken:!1,value:Me(e)};if(he[t])return{isToken:!0,value:e};if(t.match(je))throw RangeError("Format string contains an unescaped latin alphabet character `"+t+"`");return{isToken:!1,value:e}});i.localize.preprocessor&&(c=i.localize.preprocessor(s,c));let l={firstWeekContainsDate:a,weekStartsOn:o,locale:i};return c.map(r=>{if(!r.isToken)return r.value;let a=r.value;(!n?.useAdditionalWeekYearTokens&&we(a)||!n?.useAdditionalDayOfYearTokens&&Ce(a))&&Te(a,t,String(e));let o=he[a[0]];return o(s,a,i.localize,l)}).join(``)}function Me(e){let t=e.match(ke);return t?t[1].replace(Ae,`'`):e}var X=s(c()),Ne=Object.defineProperty,Pe=Object.getOwnPropertySymbols,Fe=Object.prototype.hasOwnProperty,Ie=Object.prototype.propertyIsEnumerable,Le=(e,t,n)=>t in e?Ne(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Re=(e,t)=>{for(var n in t||={})Fe.call(t,n)&&Le(e,n,t[n]);if(Pe)for(var n of Pe(t))Ie.call(t,n)&&Le(e,n,t[n]);return e},ze=(e,t)=>{var n={};for(var r in e)Fe.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&Pe)for(var r of Pe(e))t.indexOf(r)<0&&Ie.call(e,r)&&(n[r]=e[r]);return n},Be;(e=>{let t=class t{constructor(e,n,r,a){if(this.version=e,this.errorCorrectionLevel=n,this.modules=[],this.isFunction=[],et.MAX_VERSION)throw RangeError(`Version value out of range`);if(a<-1||a>7)throw RangeError(`Mask value out of range`);this.size=e*4+17;let o=[];for(let e=0;e7)throw RangeError(`Invalid value`);let u,d;for(u=a;;u++){let n=t.getNumDataCodewords(u,r)*8,i=o.getTotalBits(e,u);if(i<=n){d=i;break}if(u>=s)throw RangeError(`Data too long`)}for(let e of[t.Ecc.MEDIUM,t.Ecc.QUARTILE,t.Ecc.HIGH])l&&d<=t.getNumDataCodewords(u,e)*8&&(r=e);let f=[];for(let t of e){n(t.mode.modeBits,4,f),n(t.numChars,t.mode.numCharCountBits(u),f);for(let e of t.getData())f.push(e)}i(f.length==d);let p=t.getNumDataCodewords(u,r)*8;i(f.length<=p),n(0,Math.min(4,p-f.length),f),n(0,(8-f.length%8)%8,f),i(f.length%8==0);for(let e=236;f.lengthm[t>>>3]|=e<<7-(t&7)),new t(u,r,m,c)}getModule(e,t){return 0<=e&&e>>9)*1335;let a=(t<<10|n)^21522;i(a>>>15==0);for(let e=0;e<=5;e++)this.setFunctionModule(8,e,r(a,e));this.setFunctionModule(8,7,r(a,6)),this.setFunctionModule(8,8,r(a,7)),this.setFunctionModule(7,8,r(a,8));for(let e=9;e<15;e++)this.setFunctionModule(14-e,8,r(a,e));for(let e=0;e<8;e++)this.setFunctionModule(this.size-1-e,8,r(a,e));for(let e=8;e<15;e++)this.setFunctionModule(8,this.size-15+e,r(a,e));this.setFunctionModule(8,this.size-8,!0)}drawVersion(){if(this.version<7)return;let e=this.version;for(let t=0;t<12;t++)e=e<<1^(e>>>11)*7973;let t=this.version<<12|e;i(t>>>18==0);for(let e=0;e<18;e++){let n=r(t,e),i=this.size-11+e%3,a=Math.floor(e/3);this.setFunctionModule(i,a,n),this.setFunctionModule(a,i,n)}}drawFinderPattern(e,t){for(let n=-4;n<=4;n++)for(let r=-4;r<=4;r++){let i=Math.max(Math.abs(r),Math.abs(n)),a=e+r,o=t+n;0<=a&&a{(e!=l-o||n>=c)&&f.push(t[e])});return i(f.length==s),f}drawCodewords(e){if(e.length!=Math.floor(t.getNumRawDataModules(this.version)/8))throw RangeError(`Invalid argument`);let n=0;for(let t=this.size-1;t>=1;t-=2){t==6&&(t=5);for(let i=0;i>>3],7-(n&7)),n++)}}i(n==e.length*8)}applyMask(e){if(e<0||e>7)throw RangeError(`Mask value out of range`);for(let t=0;t5&&e++):(this.finderPenaltyAddHistory(i,a),r||(e+=this.finderPenaltyCountPatterns(a)*t.PENALTY_N3),r=this.modules[n][o],i=1);e+=this.finderPenaltyTerminateAndCount(r,i,a)*t.PENALTY_N3}for(let n=0;n5&&e++):(this.finderPenaltyAddHistory(i,a),r||(e+=this.finderPenaltyCountPatterns(a)*t.PENALTY_N3),r=this.modules[o][n],i=1);e+=this.finderPenaltyTerminateAndCount(r,i,a)*t.PENALTY_N3}for(let n=0;ne+ +!!t,n);let r=this.size*this.size,a=Math.ceil(Math.abs(n*20-r*10)/r)-1;return i(0<=a&&a<=9),e+=a*t.PENALTY_N4,i(0<=e&&e<=2568888),e}getAlignmentPatternPositions(){if(this.version==1)return[];{let e=Math.floor(this.version/7)+2,t=this.version==32?26:Math.ceil((this.version*4+4)/(e*2-2))*2,n=[6];for(let r=this.size-7;n.lengtht.MAX_VERSION)throw RangeError(`Version number out of range`);let n=(16*e+128)*e+64;if(e>=2){let t=Math.floor(e/7)+2;n-=(25*t-10)*t-55,e>=7&&(n-=36)}return i(208<=n&&n<=29648),n}static getNumDataCodewords(e,n){return Math.floor(t.getNumRawDataModules(e)/8)-t.ECC_CODEWORDS_PER_BLOCK[n.ordinal][e]*t.NUM_ERROR_CORRECTION_BLOCKS[n.ordinal][e]}static reedSolomonComputeDivisor(e){if(e<1||e>255)throw RangeError(`Degree out of range`);let n=[];for(let t=0;t0);for(let i of e){let e=i^r.shift();r.push(0),n.forEach((n,i)=>r[i]^=t.reedSolomonMultiply(n,e))}return r}static reedSolomonMultiply(e,t){if(e>>>8||t>>>8)throw RangeError(`Byte out of range`);let n=0;for(let r=7;r>=0;r--)n=n<<1^(n>>>7)*285,n^=(t>>>r&1)*e;return i(n>>>8==0),n}finderPenaltyCountPatterns(e){let t=e[1];i(t<=this.size*3);let n=t>0&&e[2]==t&&e[3]==t*3&&e[4]==t&&e[5]==t;return(n&&e[0]>=t*4&&e[6]>=t?1:0)+(n&&e[6]>=t*4&&e[0]>=t?1:0)}finderPenaltyTerminateAndCount(e,t,n){return e&&(this.finderPenaltyAddHistory(t,n),t=0),t+=this.size,this.finderPenaltyAddHistory(t,n),this.finderPenaltyCountPatterns(n)}finderPenaltyAddHistory(e,t){t[0]==0&&(e+=this.size),t.pop(),t.unshift(e)}};t.MIN_VERSION=1,t.MAX_VERSION=40,t.PENALTY_N1=3,t.PENALTY_N2=3,t.PENALTY_N3=40,t.PENALTY_N4=10,t.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],t.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],e.QrCode=t;function n(e,t,n){if(t<0||t>31||e>>>t)throw RangeError(`Value out of range`);for(let r=t-1;r>=0;r--)n.push(e>>>r&1)}function r(e,t){return(e>>>t&1)!=0}function i(e){if(!e)throw Error(`Assertion error`)}let a=class e{constructor(e,t,n){if(this.mode=e,this.numChars=t,this.bitData=n,t<0)throw RangeError(`Invalid argument`);this.bitData=n.slice()}static makeBytes(t){let r=[];for(let e of t)n(e,8,r);return new e(e.Mode.BYTE,t.length,r)}static makeNumeric(t){if(!e.isNumeric(t))throw RangeError(`String contains non-numeric characters`);let r=[];for(let e=0;e=1<{(e=>{let t=class{constructor(e,t){this.ordinal=e,this.formatBits=t}};t.LOW=new t(0,1),t.MEDIUM=new t(1,0),t.QUARTILE=new t(2,3),t.HIGH=new t(3,2),e.Ecc=t})(e.QrCode||={})})(Be||={}),(e=>{(e=>{let t=class{constructor(e,t){this.modeBits=e,this.numBitsCharCount=t}numCharCountBits(e){return this.numBitsCharCount[Math.floor((e+7)/17)]}};t.NUMERIC=new t(1,[10,12,14]),t.ALPHANUMERIC=new t(2,[9,11,13]),t.BYTE=new t(4,[8,16,16]),t.KANJI=new t(8,[8,10,12]),t.ECI=new t(7,[0,0,0]),e.Mode=t})(e.QrSegment||={})})(Be||={});var Z=Be,Ve={L:Z.QrCode.Ecc.LOW,M:Z.QrCode.Ecc.MEDIUM,Q:Z.QrCode.Ecc.QUARTILE,H:Z.QrCode.Ecc.HIGH},He=128,Ue=`L`,We=`#FFFFFF`,Ge=`#000000`,Ke=!1,qe=1,Je=4,Ye=0,Xe=.1;function Ze(e,t=0){let n=[];return e.forEach(function(e,r){let i=null;e.forEach(function(a,o){if(!a&&i!==null){n.push(`M${i+t} ${r+t}h${o-i}v1H${i+t}z`),i=null;return}if(o===e.length-1){if(!a)return;i===null?n.push(`M${o+t},${r+t} h1v1H${o+t}z`):n.push(`M${i+t},${r+t} h${o+1-i}v1H${i+t}z`);return}a&&i===null&&(i=o)})}),n.join(``)}function Qe(e,t){return e.slice().map((e,n)=>n=t.y+t.h?e:e.map((e,n)=>n=t.x+t.w?e:!1))}function $e(e,t,n,r){if(r==null)return null;let i=e.length+n*2,a=Math.floor(t*Xe),o=i/t,s=(r.width||a)*o,c=(r.height||a)*o,l=r.x==null?e.length/2-s/2:r.x*o,u=r.y==null?e.length/2-c/2:r.y*o,d=r.opacity==null?1:r.opacity,f=null;if(r.excavate){let e=Math.floor(l),t=Math.floor(u);f={x:e,y:t,w:Math.ceil(s+l-e),h:Math.ceil(c+u-t)}}let p=r.crossOrigin;return{x:l,y:u,h:c,w:s,excavation:f,opacity:d,crossOrigin:p}}function et(e,t){return t==null?e?Je:Ye:Math.max(Math.floor(t),0)}function tt({value:e,level:t,minVersion:n,includeMargin:r,marginSize:i,imageSettings:a,size:o,boostLevel:s}){let c=X.useMemo(()=>{let r=(Array.isArray(e)?e:[e]).reduce((e,t)=>(e.push(...Z.QrSegment.makeSegments(t)),e),[]);return Z.QrCode.encodeSegments(r,Ve[t],n,void 0,void 0,s)},[e,t,n,s]),{cells:l,margin:u,numCells:d,calculatedImageSettings:f}=X.useMemo(()=>{let e=c.getModules(),t=et(r,i);return{cells:e,margin:t,numCells:e.length+t*2,calculatedImageSettings:$e(e,o,t,a)}},[c,o,a,r,i]);return{qrcode:c,margin:u,cells:l,numCells:d,calculatedImageSettings:f}}var nt=function(){try{new Path2D().addPath(new Path2D)}catch{return!1}return!0}(),rt=X.forwardRef(function(e,t){let n=e,{value:r,size:i=He,level:a=Ue,bgColor:o=We,fgColor:s=Ge,includeMargin:c=Ke,minVersion:l=qe,boostLevel:u,marginSize:d,imageSettings:f}=n,p=ze(n,[`value`,`size`,`level`,`bgColor`,`fgColor`,`includeMargin`,`minVersion`,`boostLevel`,`marginSize`,`imageSettings`]),{style:m}=p,h=ze(p,[`style`]),g=f?.src,_=X.useRef(null),v=X.useRef(null),y=X.useCallback(e=>{_.current=e,typeof t==`function`?t(e):t&&(t.current=e)},[t]),[ee,b]=X.useState(!1),{margin:x,cells:S,numCells:C,calculatedImageSettings:w}=tt({value:r,level:a,minVersion:l,boostLevel:u,includeMargin:c,marginSize:d,imageSettings:f,size:i});X.useEffect(()=>{if(_.current!=null){let e=_.current,t=e.getContext(`2d`);if(!t)return;let n=S,r=v.current,a=w!=null&&r!==null&&r.complete&&r.naturalHeight!==0&&r.naturalWidth!==0;a&&w.excavation!=null&&(n=Qe(S,w.excavation));let c=window.devicePixelRatio||1;e.height=e.width=i*c;let l=i/C*c;t.scale(l,l),t.fillStyle=o,t.fillRect(0,0,C,C),t.fillStyle=s,nt?t.fill(new Path2D(Ze(n,x))):S.forEach(function(e,n){e.forEach(function(e,r){e&&t.fillRect(r+x,n+x,1,1)})}),w&&(t.globalAlpha=w.opacity),a&&t.drawImage(r,w.x+x,w.y+x,w.w,w.h)}}),X.useEffect(()=>{b(!1)},[g]);let T=Re({height:i,width:i},m),E=null;return g!=null&&(E=X.createElement(`img`,{src:g,key:g,style:{display:`none`},onLoad:()=>{b(!0)},ref:v,crossOrigin:w?.crossOrigin})),X.createElement(X.Fragment,null,X.createElement(`canvas`,Re({style:T,height:i,width:i,ref:y,role:`img`},h)),E)});rt.displayName=`QRCodeCanvas`;var it=X.forwardRef(function(e,t){let n=e,{value:r,size:i=He,level:a=Ue,bgColor:o=We,fgColor:s=Ge,includeMargin:c=Ke,minVersion:l=qe,boostLevel:u,title:d,marginSize:f,imageSettings:p}=n,m=ze(n,[`value`,`size`,`level`,`bgColor`,`fgColor`,`includeMargin`,`minVersion`,`boostLevel`,`title`,`marginSize`,`imageSettings`]),{margin:h,cells:g,numCells:_,calculatedImageSettings:v}=tt({value:r,level:a,minVersion:l,boostLevel:u,includeMargin:c,marginSize:f,imageSettings:p,size:i}),y=g,ee=null;p!=null&&v!=null&&(v.excavation!=null&&(y=Qe(g,v.excavation)),ee=X.createElement(`image`,{href:p.src,height:v.h,width:v.w,x:v.x+h,y:v.y+h,preserveAspectRatio:`none`,opacity:v.opacity,crossOrigin:v.crossOrigin}));let b=Ze(y,h);return X.createElement(`svg`,Re({height:i,width:i,viewBox:`0 0 ${_} ${_}`,ref:t,role:`img`},m),!!d&&X.createElement(`title`,null,d),X.createElement(`path`,{fill:o,d:`M0,0 h${_}v${_}H0z`,shapeRendering:`crispEdges`}),X.createElement(`path`,{fill:s,d:b,shapeRendering:`crispEdges`}),ee)});it.displayName=`QRCodeSVG`;var Q=u(),$=async(e,t={})=>{let n=sessionStorage.getItem(`counterToken`),r={"Content-Type":`application/json`,...t.headers||{},...n?{Authorization:`Bearer ${n}`}:{}},i=e.replace(/^http:\/\/[^:/]+:8080\/api/,`https://cmsapi.rit-services.in/api`),a=await fetch(i,{...t,headers:r});return(a.status===401||a.status===403)&&(sessionStorage.removeItem(`isCounterLoggedIn`),sessionStorage.removeItem(`counterToken`),window.location.href=`/login`),a},at=()=>{let[s,c]=(0,X.useState)([]),[u,p]=(0,X.useState)(null),[b,x]=(0,X.useState)(!0),[S,C]=(0,X.useState)(``),[w,T]=(0,X.useState)(``),[E,te]=(0,X.useState)(``),[D,O]=(0,X.useState)(Y(new Date,`yyyy-MM-dd`)),[k,A]=(0,X.useState)(Y(new Date,`yyyy-MM-dd`)),[j,ne]=(0,X.useState)(0),[M,re]=(0,X.useState)(10),[ie,ae]=(0,X.useState)(0),[N,oe]=(0,X.useState)(``),[se,P]=(0,X.useState)(!1),[F,I]=(0,X.useState)(!1),[ce,le]=(0,X.useState)([]),[L,ue]=(0,X.useState)(``),[R,z]=(0,X.useState)([]),[B,de]=(0,X.useState)(!1),[fe,pe]=(0,X.useState)(!1),[V,H]=(0,X.useState)(!1);(0,X.useEffect)(()=>{let e=setTimeout(()=>{oe(S)},500);return()=>clearTimeout(e)},[S]),(0,X.useEffect)(()=>{ne(0)},[N]),(0,X.useEffect)(()=>{U()},[D,k,w,E,j,M,N]),(0,X.useEffect)(()=>{me()},[]);let me=async()=>{try{let e=await $(`http://${window.location.hostname}:8080/api/products?size=1000`);if(e.ok){let t=await e.json();le(Array.isArray(t)?t:t.content||[])}}catch(e){console.error(`Error fetching products:`,e)}},U=async()=>{x(!0);try{let e=new URLSearchParams;e.append(`archived`,`false`),D&&e.append(`startDate`,`${D}T00:00:00`),k&&e.append(`endDate`,`${k}T23:59:59`),w&&e.append(`status`,w),E&&e.append(`paymentType`,E),N&&e.append(`search`,N),e.append(`page`,j.toString()),e.append(`size`,M.toString());let t=await(await $(`http://${window.location.hostname}:8080/api/orders/all?${e.toString()}`)).json();if(t&&t.content&&Array.isArray(t.content))if(c(t.content),ae(t.totalElements),u){let e=t.content.find(e=>e.id===u.id);e&&p(e)}else t.content.length>0&&p(t.content[0]);else console.error(`API did not return a valid Page object:`,t),c([]),ae(0)}catch(e){console.error(`Error fetching orders:`,e),c([]),ae(0)}finally{x(!1)}},W=async e=>{try{(await $(`http://${window.location.hostname}:8080/api/orders/${e}/status`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:`COMPLETED`})})).ok?U():alert(`Failed to update order status`)}catch(e){console.error(`Error updating order:`,e)}},G=async e=>{try{(await $(`http://${window.location.hostname}:8080/api/orders/${e}/status`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:`PAID`})})).ok&&(P(!1),U())}catch(e){console.error(`Error marking undelivered:`,e)}},K=async e=>{if(window.confirm(`Are you sure you want to cancel this order? Tokens will be refunded.`))try{(await $(`http://${window.location.hostname}:8080/api/orders/${e}/cancel`,{method:`POST`})).ok?(P(!1),U()):alert(`Failed to cancel order`)}catch(e){console.error(`Error cancelling order:`,e)}},he=()=>{u&&(z([...u.items]),I(!0),P(!1))},q=(e,t)=>{let n=[...R];n[e].quantity=Math.max(1,n[e].quantity+t),z(n)},ge=e=>{z(R.filter((t,n)=>n!==e))},J=e=>{let t=R.findIndex(t=>t.productId===e.id);t===-1?z([...R,{productId:e.id,productName:e.name,price:e.price,quantity:1}]):q(t,1),ue(``)},_e=(0,X.useMemo)(()=>R.reduce((e,t)=>e+t.price*t.quantity,0),[R]),ve=async()=>{if(u){de(!0);try{(await $(`http://${window.location.hostname}:8080/api/orders/${u.id}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({...u,items:R,totalAmount:_e})})).ok?(I(!1),U()):alert(`Failed to update order details`)}catch(e){console.error(`Error saving edits:`,e)}finally{de(!1)}}},ye=()=>{let e=document.querySelector(`.qr-canvas canvas`);if(!e||!u)return;let t=e.toDataURL(`image/png`),n=window.open(``,`_blank`);n&&(n.document.write(` + + + Print QR Code - Order #${u.displayOrderId} + + + + +
+

Order #${u.displayOrderId}

+

Scan to verify at terminal

+

Customer: ${u.user?.name||`Walk-in`}

+
+ + diff --git a/counter-frontend/src/App.tsx b/counter-frontend/src/App.tsx index 5c8a5be5..162390db 100644 --- a/counter-frontend/src/App.tsx +++ b/counter-frontend/src/App.tsx @@ -1,4 +1,5 @@ import React, { lazy, Suspense } from 'react'; +import { MotionConfig } from 'framer-motion'; import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; import Layout from './components/Layout'; @@ -24,24 +25,26 @@ const LoadingFallback = () => ( function App() { return ( - - }> - - } /> - - - - }> - } /> - } /> - } /> - } /> - } /> - - - - + + + }> + + } /> + + + + }> + } /> + } /> + } /> + } /> + } /> + + + + + ); } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 745723b7..d17bd9b3 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,5 +1,6 @@ import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; import { lazy, Suspense } from 'react'; +import { MotionConfig } from 'framer-motion'; import Layout from './components/Layout.tsx'; // Lazy load pages to decrease initial bundle size @@ -47,66 +48,68 @@ const LoadingFallback = () => ( function App() { return ( - - }> - - } /> - - - - }> - } /> - } /> - - {/* Sale */} - } /> - } /> - - {/* Customers */} - } /> - - {/* Purchases */} - } /> - } /> - } /> - } /> - } /> - } /> - - {/* Intent */} - } /> - } /> - } /> - } /> + + + }> + + } /> + + + + }> + } /> + } /> + + {/* Sale */} + } /> + } /> + + {/* Customers */} + } /> + + {/* Purchases */} + } /> + } /> + } /> + } /> + } /> + } /> + + {/* Intent */} + } /> + } /> + } /> + } /> - {/* Inventory */} - } /> - } /> - } /> - } /> - - {/* Others */} - } /> - } /> - } /> - } /> - } /> - } /> + {/* Inventory */} + } /> + } /> + } /> + } /> + + {/* Others */} + } /> + } /> + } /> + } /> + } /> + } /> - {/* Stores */} - } /> - } /> - } /> - } /> + {/* Stores */} + } /> + } /> + } /> + } /> - {/* Settings */} - } /> - - } /> - - - + {/* Settings */} + } /> + + } /> + + + + ); } diff --git a/ordering_site/src/App.tsx b/ordering_site/src/App.tsx index 574c5440..68e70dc1 100644 --- a/ordering_site/src/App.tsx +++ b/ordering_site/src/App.tsx @@ -1,5 +1,6 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { lazy, Suspense } from 'react'; +import { MotionConfig } from 'framer-motion'; import { CartProvider } from './contexts/CartContext'; import { AuthProvider } from './contexts/AuthContext'; import { FoodProvider } from './contexts/FoodContext'; @@ -38,81 +39,83 @@ function App() { - - }> - - } /> - - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - } /> - - - + + + }> + + } /> + + + + + } /> + + + + } /> + + + + } /> + + + + } /> + + + + } /> + + + + + } /> + + + + } /> + + + + } /> + + + + } /> + + + + } /> + + + + } /> + + + + } /> + + + + } /> + } /> + + + + diff --git a/ordering_site/src/assets/RIT_Logo.webp b/ordering_site/src/assets/RIT_Logo.webp new file mode 100644 index 00000000..8374c385 Binary files /dev/null and b/ordering_site/src/assets/RIT_Logo.webp differ diff --git a/ordering_site/src/assets/Tillo.png b/ordering_site/src/assets/Tillo.png new file mode 100644 index 00000000..7bdd84ca Binary files /dev/null and b/ordering_site/src/assets/Tillo.png differ diff --git a/ordering_site/src/assets/display_ritz.webp b/ordering_site/src/assets/display_ritz.webp new file mode 100644 index 00000000..1cbbe96c Binary files /dev/null and b/ordering_site/src/assets/display_ritz.webp differ diff --git a/ordering_site/src/assets/front.webp b/ordering_site/src/assets/front.webp new file mode 100644 index 00000000..964974ab Binary files /dev/null and b/ordering_site/src/assets/front.webp differ diff --git a/ordering_site/src/assets/tillo_spinner.gif b/ordering_site/src/assets/tillo_spinner.gif new file mode 100644 index 00000000..02b97039 Binary files /dev/null and b/ordering_site/src/assets/tillo_spinner.gif differ diff --git a/ordering_site/src/components/StockAlert.tsx b/ordering_site/src/components/StockAlert.tsx new file mode 100644 index 00000000..bab632e2 --- /dev/null +++ b/ordering_site/src/components/StockAlert.tsx @@ -0,0 +1,68 @@ +import React, { useEffect } from 'react'; +import { AlertCircle, X } from 'lucide-react'; +import { useCart } from '../contexts/CartContext'; +import { motion, AnimatePresence } from 'framer-motion'; + +const StockAlert: React.FC = () => { + const { stockError, clearStockError } = useCart(); + + useEffect(() => { + if (stockError) { + const timer = setTimeout(() => { + clearStockError(); + }, 3000); + return () => clearTimeout(timer); + } + }, [stockError, clearStockError]); + + return ( + + {stockError && ( + +
+ + {stockError} +
+ +
+ )} +
+ ); +}; + +export default StockAlert; diff --git a/ordering_site/src/components/StockConflictModal.tsx b/ordering_site/src/components/StockConflictModal.tsx new file mode 100644 index 00000000..037cfaab --- /dev/null +++ b/ordering_site/src/components/StockConflictModal.tsx @@ -0,0 +1,174 @@ +import React from 'react'; +import { AlertTriangle, Trash2, Edit2, X } from 'lucide-react'; +import { motion } from 'framer-motion'; + +interface StockConflict { + productId: number; + productName: string; + requestedQty: number; + availableQty: number; +} + +interface StockConflictModalProps { + conflicts: StockConflict[]; + onRemoveItem: (productId: number) => void; + onAdjustQuantity: (productId: number, newQty: number) => void; + onClose: () => void; +} + +const StockConflictModal: React.FC = ({ + conflicts, + onRemoveItem, + onAdjustQuantity, + onClose, +}) => { + return ( +
+ {/* Backdrop */} + + + {/* Modal Container */} + +
+
+ +

Stock Issues Detected

+
+ +
+ +

+ Some items in your cart do not have enough stock available to complete the order: +

+ +
+ {conflicts.map((conflict) => ( +
+
+ {conflict.productName} +
+
+ Requested: {conflict.requestedQty} + {conflict.availableQty > 0 ? 'In Stock (Limited)' : 'Out of Stock'} +
+ +
+ {conflict.availableQty > 0 ? ( + + ) : ( +
+ Out of Stock +
+ )} + + +
+
+ ))} +
+ + +
+
+ ); +}; + +export default StockConflictModal; diff --git a/ordering_site/src/contexts/ThemeContext.tsx b/ordering_site/src/contexts/ThemeContext.tsx new file mode 100644 index 00000000..db7622a2 --- /dev/null +++ b/ordering_site/src/contexts/ThemeContext.tsx @@ -0,0 +1,48 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; + +type Theme = 'light' | 'dark'; + +interface ThemeContextType { + theme: Theme; + toggleTheme: () => void; + setTheme: (theme: Theme) => void; +} + +const ThemeContext = createContext(undefined); + +export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [theme, setThemeState] = useState(() => { + const savedTheme = localStorage.getItem('theme'); + if (savedTheme === 'light' || savedTheme === 'dark') { + return savedTheme; + } + return 'light'; + }); + + useEffect(() => { + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + }, [theme]); + + const toggleTheme = () => { + setThemeState((prev) => (prev === 'light' ? 'dark' : 'light')); + }; + + const setTheme = (newTheme: Theme) => { + setThemeState(newTheme); + }; + + return ( + + {children} + + ); +}; + +export const useTheme = () => { + const context = useContext(ThemeContext); + if (context === undefined) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return context; +}; diff --git a/ordering_site/src/firebase.ts b/ordering_site/src/firebase.ts new file mode 100644 index 00000000..14f1e421 --- /dev/null +++ b/ordering_site/src/firebase.ts @@ -0,0 +1,16 @@ +import { initializeApp } from "firebase/app"; +import { getAuth, GoogleAuthProvider } from "firebase/auth"; + +const firebaseConfig = { + apiKey: "AIzaSyDOEiKtH-gs2nAx8Di45wJf8CY5nPm4xPE", + authDomain: "tillo-c8de9.firebaseapp.com", + projectId: "tillo-c8de9", + storageBucket: "tillo-c8de9.firebasestorage.app", + messagingSenderId: "200333262782", + appId: "1:200333262782:web:0d988352ee6a44d7a943ef", + measurementId: "G-YB01EQT2VW" +}; + +const app = initializeApp(firebaseConfig); +export const auth = getAuth(app); +export const googleProvider = new GoogleAuthProvider(); diff --git a/ordering_site/src/pages/NotFoundScreen.tsx b/ordering_site/src/pages/NotFoundScreen.tsx new file mode 100644 index 00000000..6c484ddf --- /dev/null +++ b/ordering_site/src/pages/NotFoundScreen.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { AlertTriangle, Home } from 'lucide-react'; + +const NotFoundScreen: React.FC = () => { + const navigate = useNavigate(); + + return ( +
+
+ +
+ +

+ Page Not Found +

+ +

+ The page you are looking for doesn't exist or has been moved to another URL. +

+ + +
+ ); +}; + +export default NotFoundScreen; diff --git a/ordering_site/src/pages/PreferencesScreen.tsx b/ordering_site/src/pages/PreferencesScreen.tsx new file mode 100644 index 00000000..6e29ced2 --- /dev/null +++ b/ordering_site/src/pages/PreferencesScreen.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import Header from '../components/Header'; +import BottomNav from '../components/BottomNav'; +import { useTheme } from '../contexts/ThemeContext'; +import { Moon, Sun, Globe, ChevronRight } from 'lucide-react'; + +const PreferencesScreen: React.FC = () => { + const { theme, toggleTheme } = useTheme(); + + return ( +
+
+
+
+
+
+ {theme === 'dark' ? : } +
+
Dark Mode
+
+ {theme === 'dark' ? 'Enabled' : 'Disabled'} +
+
+
+
+ + {theme === 'dark' ? 'On' : 'Off'} + + +
+
+ +
+
+ +
+
Language
+
Change application language
+
+
+
+ English + +
+
+
+
+ +
+ ); +}; + +export default PreferencesScreen; diff --git a/ordering_site/src/pages/TopUpScreen.css b/ordering_site/src/pages/TopUpScreen.css new file mode 100644 index 00000000..bbea94fd --- /dev/null +++ b/ordering_site/src/pages/TopUpScreen.css @@ -0,0 +1,358 @@ +/* ═══════════════════════════════════════════════ + TopUp Screen — Premium Razorpay Recharge UI + ═══════════════════════════════════════════════ */ + +.topup-page main { + padding-bottom: 40px; +} + +/* ── Back Button ─────────────────────────────── */ +.topup-back-btn { + display: flex; + align-items: center; + gap: 8px; + color: var(--text-mid); + font-weight: 600; + font-size: 0.9rem; + margin-bottom: 20px; + border: none; + background: none; + cursor: pointer; + padding: 4px 0; + transition: color 0.2s; +} + +.topup-back-btn:hover { + color: var(--text-dark); +} + +/* ── Balance Card ────────────────────────────── */ +.topup-balance-card { + background: linear-gradient(135deg, #001828 0%, #4a3e7a 100%); + color: #ffffff; + padding: 24px; + border-radius: 20px; + margin-bottom: 20px; + position: relative; + overflow: hidden; + box-shadow: 0 8px 32px rgba(35, 22, 81, 0.18); +} + +.topup-balance-card::before { + content: ''; + position: absolute; + top: -30px; + right: -30px; + width: 100px; + height: 100px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.06); +} + +.topup-balance-card::after { + content: ''; + position: absolute; + bottom: -20px; + left: -20px; + width: 80px; + height: 80px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.04); +} + +.balance-label { + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.5px; + opacity: 0.8; + margin-bottom: 8px; +} + +.balance-amount { + font-size: 2rem; + font-weight: 900; + letter-spacing: -0.5px; +} + +/* ── Razorpay Info Banner ────────────────────── */ +.razorpay-info-banner { + display: flex; + align-items: center; + gap: 12px; + padding: 14px 16px; + border-radius: 14px; + background: rgba(var(--primary-rgb), 0.08); + border: 1px solid rgba(var(--primary-rgb), 0.2); + margin-bottom: 20px; +} + +.razorpay-info-banner .banner-icon { + color: var(--primary); + flex-shrink: 0; +} + +.razorpay-info-banner .banner-text { + font-size: 0.85rem; + color: var(--text-mid); + line-height: 1.4; +} + +.razorpay-info-banner .banner-text strong { + color: var(--text-dark); + display: block; + margin-bottom: 2px; +} + +/* ── Form Styles ─────────────────────────────── */ +.topup-form { + display: flex; + flex-direction: column; + gap: 20px; +} + +.topup-form label { + font-size: 0.85rem; + font-weight: 700; + color: var(--text-mid); + margin-bottom: 8px; + display: block; +} + +.amount-input-wrapper { + position: relative; +} + +.amount-input-wrapper .currency-symbol { + position: absolute; + left: 16px; + top: 50%; + transform: translateY(-50%); + font-size: 1.5rem; + font-weight: 800; + color: var(--primary); + pointer-events: none; +} + +.amount-input-wrapper input { + width: 100%; + padding: 16px 16px 16px 40px; + font-size: 1.5rem; + font-weight: 800; + border-radius: 16px; + border: 2px solid var(--border); + background-color: var(--surface); + color: var(--text-dark); + outline: none; + transition: border-color 0.25s, box-shadow 0.25s; + font-family: inherit; +} + +.amount-input-wrapper input:focus { + border-color: var(--primary); + box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.1); +} + +.amount-input-wrapper input::placeholder { + color: var(--text-light); + font-weight: 600; +} + +/* ── Quick Presets ────────────────────────────── */ +.presets-label { + font-size: 0.85rem; + font-weight: 700; + color: var(--text-light); + margin-bottom: 10px; + display: block; +} + +.presets-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 10px; +} + +.preset-btn { + padding: 12px 6px; + border-radius: 12px; + border: 1.5px solid var(--border); + background-color: var(--surface); + color: var(--text-dark); + font-weight: 700; + font-size: 0.9rem; + cursor: pointer; + transition: all 0.2s ease; + text-align: center; + font-family: inherit; +} + +.preset-btn:hover { + border-color: var(--primary); + transform: translateY(-1px); +} + +.preset-btn.active { + background-color: var(--primary); + color: #ffffff; + border-color: var(--primary); + transform: scale(1.03); + box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.25); +} + +/* ── Error Message ───────────────────────────── */ +.topup-error { + color: #FF4D4F; + background-color: #FFF1F2; + padding: 12px 16px; + border-radius: 12px; + font-size: 0.85rem; + font-weight: 600; + border: 1px solid #fecaca; + display: flex; + align-items: center; + gap: 8px; + animation: topup-error-shake 0.35s ease; +} + +@keyframes topup-error-shake { + 0%, 100% { transform: translateX(0); } + 20% { transform: translateX(-4px); } + 40% { transform: translateX(4px); } + 60% { transform: translateX(-3px); } + 80% { transform: translateX(2px); } +} + +/* ── Pay Button ──────────────────────────────── */ +.topup-submit-btn { + background-color: var(--primary); + color: #ffffff; + padding: 16px; + border-radius: 16px; + font-weight: 800; + font-size: 1rem; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + border: none; + cursor: pointer; + transition: opacity 0.2s, transform 0.15s; + margin-top: 10px; + font-family: inherit; + position: relative; + overflow: hidden; +} + +.topup-submit-btn:not(:disabled):hover { + transform: translateY(-1px); + box-shadow: 0 6px 20px rgba(var(--primary-rgb), 0.3); +} + +.topup-submit-btn:not(:disabled):active { + transform: scale(0.98); +} + +.topup-submit-btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.topup-submit-btn.processing { + background: linear-gradient(90deg, var(--primary), color-mix(in srgb, var(--primary) 70%, #000)); +} + +/* ── Shimmer animation for processing state ── */ +.topup-submit-btn.processing::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient( + 90deg, + transparent 0%, + rgba(255, 255, 255, 0.15) 50%, + transparent 100% + ); + animation: shimmer 1.5s infinite; +} + +@keyframes shimmer { + 0% { left: -100%; } + 100% { left: 100%; } +} + +/* ── Security Footer ─────────────────────────── */ +.topup-security-footer { + display: flex; + align-items: center; + gap: 8px; + color: var(--text-light); + font-size: 0.8rem; + justify-content: center; + margin-top: 24px; +} + +/* ── Success Overlay ─────────────────────────── */ +.topup-success-overlay { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 100vh; + padding: 20px; + text-align: center; +} + +.topup-success-icon { + animation: topup-success-pop 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); + margin-bottom: 24px; +} + +@keyframes topup-success-pop { + 0% { transform: scale(0); opacity: 0; } + 60% { transform: scale(1.2); } + 100% { transform: scale(1); opacity: 1; } +} + +.topup-success-title { + font-size: 1.5rem; + font-weight: 800; + color: var(--text-dark); + margin-bottom: 12px; +} + +.topup-success-amount { + color: var(--text-light); + font-size: 0.95rem; + margin-bottom: 24px; +} + +.topup-success-redirect { + color: var(--primary); + font-weight: 600; + font-size: 0.85rem; + animation: topup-pulse 1.5s ease-in-out infinite; +} + +@keyframes topup-pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +/* ── Conversion hint ─────────────────────────── */ +.conversion-hint { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.78rem; + color: var(--text-light); + margin-top: 4px; + padding-left: 2px; +} + +.conversion-hint .equals-sign { + color: var(--primary); + font-weight: 700; +} diff --git a/ordering_site/src/pages/TopUpScreen.tsx b/ordering_site/src/pages/TopUpScreen.tsx new file mode 100644 index 00000000..7e5a6d65 --- /dev/null +++ b/ordering_site/src/pages/TopUpScreen.tsx @@ -0,0 +1,195 @@ +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { ArrowLeft, Wallet, ShieldCheck, CheckCircle, CreditCard, Zap } from 'lucide-react'; +import { useAuth } from '../contexts/AuthContext'; +import Header from '../components/Header'; +import { payAndVerify } from '../utils/razorpay'; +import './TopUpScreen.css'; + +const TopUpScreen: React.FC = () => { + const navigate = useNavigate(); + const { user, refreshUser } = useAuth(); + const [amount, setAmount] = useState(''); + const [isProcessing, setIsProcessing] = useState(false); + const [error, setError] = useState(null); + const [success, setSuccess] = useState(false); + const [creditedAmount, setCreditedAmount] = useState(0); + + const presets = [50, 100, 200, 500]; + + const handleTopUp = async (e: React.FormEvent) => { + e.preventDefault(); + if (!user) return; + + const parsedAmount = parseFloat(amount); + if (isNaN(parsedAmount) || parsedAmount < 50) { + setError('Minimum top up amount is ₹50.'); + return; + } + + if (parsedAmount > 5000) { + setError('Maximum top up limit per transaction is ₹5,000.'); + return; + } + + if (!Number.isInteger(parsedAmount)) { + setError('Please enter a whole number amount (no paise).'); + return; + } + + setIsProcessing(true); + setError(null); + + try { + const result = await payAndVerify({ + purpose: 'WALLET_TOPUP', + amount: parsedAmount + }); + + if (result.success && (result.type === 'WALLET_TOPUP' || result.purpose === 'WALLET_TOPUP')) { + setCreditedAmount(parsedAmount); + setSuccess(true); + await refreshUser(); + setTimeout(() => { + navigate('/wallet'); + }, 2200); + } else { + setError(result.message || 'Payment succeeded but wallet was not credited. Contact support with your payment ID.'); + } + } catch (err: any) { + console.error('Top up error:', err); + if (err?.message === 'Payment cancelled') { + setError('Payment was cancelled. No tokens were added.'); + } else { + setError(err?.message || 'Connection error. Please try again.'); + } + } finally { + setIsProcessing(false); + } + }; + + if (success) { + return ( +
+
+
+ +
+

+ Top Up Successful! +

+

+ 🅡{creditedAmount.toLocaleString()} Ritz tokens have been added to your wallet. +

+
+ Redirecting to your wallet... +
+
+
+ ); + } + + return ( +
+
+ +
+ + + {/* Balance Card */} +
+
+
Current Balance
+ +
+
🅡{(user?.ritzTokenBalance || 0).toLocaleString()}
+
+ + {/* Razorpay Info */} +
+ +
+ Pay securely with Razorpay + UPI, cards & netbanking. Tokens are credited only after payment succeeds. +
+
+ +
+
+ +
+ + { + setAmount(e.target.value); + setError(null); + }} + placeholder="0" + min="50" + max="5000" + step="1" + required + /> +
+ {amount && Number(amount) > 0 && ( +
+ + ₹{Number(amount).toLocaleString()} + = + 🅡{Number(amount).toLocaleString()} Ritz Tokens +
+ )} +
+ +
+ Quick Add Presets +
+ {presets.map((preset) => ( + + ))} +
+
+ + {error && ( +
+ {error} +
+ )} + + +
+ +
+ + Secured by Razorpay · 1 Ritz Token = ₹1.00 +
+
+
+ ); +}; + +export default TopUpScreen; diff --git a/ordering_site/src/pages/WalletScreen.css b/ordering_site/src/pages/WalletScreen.css new file mode 100644 index 00000000..6bbe5968 --- /dev/null +++ b/ordering_site/src/pages/WalletScreen.css @@ -0,0 +1,322 @@ +/* ═══════════════════════════════════════════════ + Wallet Screen — Premium Ritz Wallet UI + ═══════════════════════════════════════════════ */ + +.wallet-page main { + padding: 20px; + padding-bottom: 100px; +} + +/* ── Gradient Balance Card ───────────────────── */ +.wallet-balance-card { + background: linear-gradient(135deg, #001828 0%, #4a3e7a 100%); + color: #ffffff; + padding: 24px; + borderRadius: 24px; + box-shadow: 0 8px 32px rgba(35, 22, 81, 0.15); + margin-bottom: 24px; + position: relative; + overflow: hidden; + border-radius: 24px; +} + +.wallet-balance-card::before { + content: ''; + position: absolute; + top: -40px; + right: -40px; + width: 130px; + height: 130px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.05); + pointer-events: none; +} + +.wallet-balance-card::after { + content: ''; + position: absolute; + bottom: -30px; + left: 30px; + width: 90px; + height: 90px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.03); + pointer-events: none; +} + +.wallet-balance-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; +} + +.wallet-balance-label { + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 1px; + opacity: 0.8; +} + +.wallet-balance-icon { + opacity: 0.8; +} + +.wallet-balance-display { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 20px; +} + +.wallet-token-image { + width: 40px; + height: 40px; + object-fit: contain; +} + +.wallet-balance-value { + font-size: 2.5rem; + font-weight: 900; + letter-spacing: -1px; +} + +/* ── Top Up Button (inside balance card) ─────── */ +.wallet-topup-btn { + width: 100%; + background-color: #ffffff; + color: #001828; + padding: 12px; + border-radius: 12px; + font-weight: 700; + font-size: 0.95rem; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + border: none; + cursor: pointer; + transition: transform 0.2s, box-shadow 0.2s; + font-family: inherit; +} + +.wallet-topup-btn:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +.wallet-topup-btn:active { + transform: scale(0.98); +} + +/* ── Coupon Card ─────────────────────────────── */ +.wallet-coupon-card { + background-color: var(--surface); + padding: 20px; + border-radius: 24px; + box-shadow: var(--shadow); + margin-bottom: 24px; + border: 1px solid var(--border); +} + +.wallet-coupon-card h4 { + font-size: 0.95rem; + font-weight: 800; + color: var(--text-dark); + margin-bottom: 8px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.wallet-coupon-card p { + font-size: 0.8rem; + color: var(--text-light); + margin-bottom: 16px; +} + +.coupon-form { + display: flex; + flex-direction: column; + gap: 12px; +} + +.coupon-input-row { + display: flex; + gap: 8px; +} + +.coupon-input { + flex: 1; + padding: 12px 16px; + border-radius: 12px; + border: 1px solid var(--border); + background-color: var(--input-bg); + color: var(--text-dark); + font-weight: 600; + font-size: 0.9rem; + outline: none; + text-transform: uppercase; + font-family: inherit; + transition: border-color 0.2s; +} + +.coupon-input:focus { + border-color: var(--primary); +} + +.coupon-apply-btn { + background-color: var(--primary); + color: #ffffff; + padding: 0 20px; + border-radius: 12px; + font-weight: 700; + font-size: 0.9rem; + border: none; + cursor: pointer; + transition: transform 0.1s, opacity 0.2s; + font-family: inherit; +} + +.coupon-apply-btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.coupon-apply-btn:not(:disabled):active { + transform: scale(0.96); +} + +.coupon-status { + padding: 10px 14px; + border-radius: 10px; + font-size: 0.8rem; + font-weight: 600; + animation: coupon-status-slide 0.3s ease; +} + +.coupon-status.success { + background-color: #f0fdf4; + color: #166534; + border: 1px solid #bbf7d0; +} + +.coupon-status.error { + background-color: #fef2f2; + color: #991b1b; + border: 1px solid #fecaca; +} + +@keyframes coupon-status-slide { + from { + opacity: 0; + transform: translateY(-4px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* ── Transactions Section ────────────────────── */ +.wallet-transactions-header { + font-size: 1.1rem; + font-weight: 700; + color: var(--text-dark); + margin-bottom: 16px; +} + +.wallet-transactions-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.wallet-tx-card { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px; + background-color: var(--surface); + border-radius: 16px; + box-shadow: var(--shadow); + border: 1px solid var(--border); + transition: transform 0.15s; +} + +.wallet-tx-card:hover { + transform: translateY(-1px); +} + +.wallet-tx-left { + display: flex; + align-items: center; + gap: 12px; +} + +.wallet-tx-icon { + width: 40px; + height: 40px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.wallet-tx-icon.credit { + background-color: #E6FFFA; + color: #00B894; +} + +.wallet-tx-icon.debit { + background-color: #FFF1F2; + color: #FF4D4F; +} + +.wallet-tx-description { + font-weight: 700; + color: var(--text-dark); + font-size: 0.95rem; +} + +.wallet-tx-meta { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.75rem; + color: var(--text-light); + margin-top: 2px; +} + +.wallet-tx-ref { + opacity: 0.7; +} + +.wallet-tx-amount { + font-weight: 800; + font-size: 1.05rem; + white-space: nowrap; +} + +.wallet-tx-amount.credit { + color: #00B894; +} + +.wallet-tx-amount.debit { + color: #FF4D4F; +} + +.wallet-empty-state { + text-align: center; + padding: 40px 20px; + background-color: var(--surface); + border-radius: 16px; + color: var(--text-light); + box-shadow: var(--shadow); +} + +.wallet-loading-state { + text-align: center; + padding: 40px; + color: var(--text-light); +} diff --git a/ordering_site/src/pages/WalletScreen.tsx b/ordering_site/src/pages/WalletScreen.tsx new file mode 100644 index 00000000..dc65f21d --- /dev/null +++ b/ordering_site/src/pages/WalletScreen.tsx @@ -0,0 +1,221 @@ +import React, { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Wallet, PlusCircle, ArrowUpRight, ArrowDownLeft, Calendar } from 'lucide-react'; +import { useAuth } from '../contexts/AuthContext'; +import { authHeaders } from '../utils/razorpay'; +import Header from '../components/Header'; +import BottomNav from '../components/BottomNav'; +import tokenImage from '../assets/display_ritz.webp'; +import './WalletScreen.css'; + +interface Transaction { + id: number; + amount: number; + type: 'TOPUP' | 'SPEND' | 'REFUND'; + description: string; + timestamp: string; + referenceId: string; +} + +const WalletScreen: React.FC = () => { + const navigate = useNavigate(); + const { user } = useAuth(); + const [balance, setBalance] = useState(user?.ritzTokenBalance || 0); + const [transactions, setTransactions] = useState([]); + const [isLoading, setIsLoading] = useState(true); + + // Coupon States + const [couponCode, setCouponCode] = useState(''); + const [redeemStatus, setRedeemStatus] = useState<{ type: 'success' | 'error' | null; message: string }>({ type: null, message: '' }); + const [isRedeeming, setIsRedeeming] = useState(false); + + useEffect(() => { + if (user) { + fetchWalletData(); + } + }, [user]); + + const fetchWalletData = async () => { + if (!user) return; + try { + setIsLoading(true); + // Fetch balance + const balanceRes = await fetch(`http://${window.location.hostname}:8080/api/wallet/balance/${user.id}`, { + headers: authHeaders() + }); + if (balanceRes.ok) { + const balanceData = await balanceRes.json(); + setBalance(balanceData.balance || 0); + } + + // Fetch transactions + const txRes = await fetch(`http://${window.location.hostname}:8080/api/wallet/transactions/${user.id}`, { + headers: authHeaders() + }); + if (txRes.ok) { + const txData = await txRes.json(); + setTransactions(txData || []); + } + } catch (error) { + console.error('Error fetching wallet data:', error); + } finally { + setIsLoading(false); + } + }; + + const handleRedeemCoupon = async (e: React.FormEvent) => { + e.preventDefault(); + if (!couponCode.trim()) return; + + try { + setIsRedeeming(true); + setRedeemStatus({ type: null, message: '' }); + + const response = await fetch(`http://${window.location.hostname}:8080/api/coupons/redeem`, { + method: 'POST', + headers: authHeaders(), + body: JSON.stringify({ + code: couponCode.trim(), + userId: user?.id + }) + }); + + const data = await response.json(); + if (response.ok && data.success) { + setRedeemStatus({ + type: 'success', + message: data.message || `Successfully redeemed coupon code!` + }); + setCouponCode(''); + // Refresh balance and transactions + fetchWalletData(); + } else { + setRedeemStatus({ + type: 'error', + message: data.message || 'Failed to redeem coupon.' + }); + } + } catch (error) { + console.error('Error redeeming coupon:', error); + setRedeemStatus({ + type: 'error', + message: 'Something went wrong. Please try again.' + }); + } finally { + setIsRedeeming(false); + } + }; + + return ( +
+
+ +
+ {/* Balance Card */} +
+
+ Ritz Token Balance + +
+ +
+ Ritz Token + + 🅡{balance.toLocaleString()} + +
+ + +
+ + {/* Redeem Coupon Card */} +
+

Redeem Coupon Code

+

Claim promo codes or reward vouchers to instantly credit tokens to your wallet.

+ +
+
+ setCouponCode(e.target.value)} + disabled={isRedeeming} + className="coupon-input" + /> + +
+ + {redeemStatus.type && ( +
+ {redeemStatus.message} +
+ )} +
+
+ + {/* Transactions Section */} +
+

+ Transaction History +

+ + {isLoading ? ( +
+ Loading transactions... +
+ ) : transactions.length === 0 ? ( +
+ No transactions yet. Top up your wallet to get started! +
+ ) : ( +
+ {transactions.map((tx) => { + const isCredit = tx.type === 'TOPUP' || tx.type === 'REFUND'; + return ( +
+
+
+ {isCredit ? : } +
+
+
+ {tx.description || (tx.type === 'TOPUP' ? 'Wallet Top Up' : tx.type === 'REFUND' ? 'Refund' : 'Order Payment')} +
+
+ + {new Date(tx.timestamp).toLocaleString()} + {tx.referenceId && • {tx.referenceId}} +
+
+
+ +
+ {isCredit ? '+' : '-'}🅡{tx.amount.toLocaleString()} +
+
+ ); + })} +
+ )} +
+
+ + +
+ ); +}; + +export default WalletScreen; diff --git a/ordering_site/src/utils/razorpay.ts b/ordering_site/src/utils/razorpay.ts new file mode 100644 index 00000000..1b35349c --- /dev/null +++ b/ordering_site/src/utils/razorpay.ts @@ -0,0 +1,192 @@ +/** + * Razorpay Checkout helpers for the ordering site. + * Secret key never touches the browser — only key_id + order_id from the backend. + */ + +export type RazorpayPrefill = { + name?: string; + email?: string; + contact?: string; +}; + +export type CreatePaymentResponse = { + success: boolean; + paymentSessionId: number; + keyId: string; + razorpayOrderId: string; + amount: number; // paise + amountInr: number; + currency: string; + purpose: string; + name: string; + description: string; + prefill?: RazorpayPrefill; + notes?: Record; + message?: string; + errorType?: string; + conflicts?: unknown[]; +}; + +export type VerifyPaymentResponse = { + success: boolean; + type?: string; + purpose?: string; + status?: string; + orderNumber?: string; + displayOrderId?: string; + newBalance?: number; + message?: string; + creditedAmount?: number; + razorpayPaymentId?: string; +}; + +export type RazorpaySuccessResponse = { + razorpay_order_id: string; + razorpay_payment_id: string; + razorpay_signature: string; +}; + +declare global { + interface Window { + Razorpay?: new (options: Record) => { + open: () => void; + on: (event: string, handler: (response: unknown) => void) => void; + }; + } +} + +const API_HOST = () => `http://${window.location.hostname}:8080`; + +export function authHeaders(): HeadersInit { + const token = localStorage.getItem('token'); + return { + 'Content-Type': 'application/json', + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }; +} + +let razorpayScriptPromise: Promise | null = null; + +export function loadRazorpayScript(): Promise { + if (window.Razorpay) return Promise.resolve(); + if (razorpayScriptPromise) return razorpayScriptPromise; + + razorpayScriptPromise = new Promise((resolve, reject) => { + const existing = document.querySelector('script[data-razorpay="true"]'); + if (existing) { + existing.addEventListener('load', () => resolve()); + existing.addEventListener('error', () => reject(new Error('Failed to load Razorpay SDK'))); + return; + } + const script = document.createElement('script'); + script.src = 'https://checkout.razorpay.com/v1/checkout.js'; + script.async = true; + script.dataset.razorpay = 'true'; + script.onload = () => resolve(); + script.onerror = () => { + razorpayScriptPromise = null; + reject(new Error('Failed to load Razorpay Checkout. Check your network connection.')); + }; + document.body.appendChild(script); + }); + + return razorpayScriptPromise; +} + +export async function createPayment(body: Record): Promise { + const response = await fetch(`${API_HOST()}/api/payments/create`, { + method: 'POST', + headers: authHeaders(), + body: JSON.stringify(body), + }); + const data = await response.json(); + if (!response.ok && data.success !== false) { + throw new Error(data.message || 'Failed to create payment'); + } + return data; +} + +export async function verifyPayment(payload: { + razorpayOrderId: string; + razorpayPaymentId: string; + razorpaySignature: string; +}): Promise { + const response = await fetch(`${API_HOST()}/api/payments/verify`, { + method: 'POST', + headers: authHeaders(), + body: JSON.stringify(payload), + }); + const data = await response.json(); + if (!response.ok || !data.success) { + throw new Error(data.message || 'Payment verification failed'); + } + return data; +} + +/** + * Opens Razorpay Checkout and resolves only after the user completes payment. + * Does NOT place the order — caller must call verifyPayment next. + */ +export async function openRazorpayCheckout( + checkout: CreatePaymentResponse +): Promise { + await loadRazorpayScript(); + const RazorpayCtor = window.Razorpay; + if (!RazorpayCtor) { + throw new Error('Razorpay SDK is not available'); + } + + return new Promise((resolve, reject) => { + const options: Record = { + key: checkout.keyId, + amount: checkout.amount, + currency: checkout.currency || 'INR', + name: checkout.name || 'Tillo Canteen', + description: checkout.description || 'Payment', + order_id: checkout.razorpayOrderId, + prefill: checkout.prefill || {}, + notes: checkout.notes || {}, + theme: { color: '#00B894' }, + modal: { + ondismiss: () => { + reject(new Error('Payment cancelled')); + }, + }, + handler: (response: RazorpaySuccessResponse) => { + resolve(response); + }, + }; + + const rzp = new RazorpayCtor(options); + rzp.on('payment.failed', (resp: unknown) => { + const err = resp as { error?: { description?: string; reason?: string } }; + reject(new Error(err?.error?.description || err?.error?.reason || 'Payment failed')); + }); + rzp.open(); + }); +} + +/** + * Full pay → verify flow used by checkout and wallet top-up. + */ +export async function payAndVerify( + createBody: Record +): Promise { + const created = await createPayment(createBody); + if (!created.success) { + const err = new Error(created.message || 'Could not start payment') as Error & { + errorType?: string; + conflicts?: unknown[]; + }; + err.errorType = created.errorType; + err.conflicts = created.conflicts; + throw err; + } + + const payment = await openRazorpayCheckout(created); + return verifyPayment({ + razorpayOrderId: payment.razorpay_order_id, + razorpayPaymentId: payment.razorpay_payment_id, + razorpaySignature: payment.razorpay_signature, + }); +}