1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1854],{7712:function(e,t,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/app/sync-test",function(){return n(4906)}])},4906:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return x}});var i=n(5893),r=n(7294),s=n(1163),o=n(9008),l=n.n(o),a=n(4431),d=n(5569),c=n(4315),u=n(1006);let m={minHeight:"100vh",background:"var(--bg)",padding:"2rem",fontFamily:"monospace"},h={background:"white",border:"1px solid var(--border)",borderRadius:12,padding:"1.25rem",marginBottom:"1rem"},f={background:"var(--blue)",color:"white",fontWeight:700,fontSize:"0.85rem",borderRadius:8,padding:"0.6rem 1rem",border:"none",cursor:"pointer",marginRight:"0.5rem",marginBottom:"0.5rem"},y={...f,background:"#c0392b"},g=(e,t)=>({display:"inline-block",background:e,color:t,fontSize:"0.7rem",fontWeight:700,borderRadius:4,padding:"0.15rem 0.5rem",marginLeft:"0.5rem"});function x(){let e=(0,s.useRouter)(),{session:t,loading:n,user:o}=(0,a.a)(),{isOnline:x,syncStatus:p,lastSyncedAt:w,triggerSync:j}=(0,d._)(o),[b,k]=(0,r.useState)([]),[v,_]=(0,r.useState)({}),[S,T]=(0,r.useState)(!1),D=(0,r.useCallback)(async()=>{if(!o)return;T(!0);let e=await (0,u.s2)(o.id);k(e);let t={};for(let n of e)t[n.client_id]=await (0,u.hT)(n.client_id);_(t),T(!1)},[o]);async function C(){await (0,u.xQ)(o.id,{name:`Test workout ${new Date().toLocaleTimeString()}`}),await D()}async function B(e){let t=v[e]||[];await (0,u.$F)(e,o.id,{exerciseId:"test-exercise-id",setNumber:t.length+1,reps:10,load:20,loadUnit:"kg"}),await D()}async function E(e){await (0,u.XI)(e),await D()}async function N(e){await (0,u.ne)(e),await D()}async function z(){confirm("This clears all local IndexedDB data on this device only. Server data is untouched. Continue?")&&(await c.db.workouts.clear(),await c.db.workout_sets.clear(),await c.db.workout_templates.clear(),await c.db.template_exercises.clear(),await c.db.sync_meta.clear(),await D())}return((0,r.useEffect)(()=>{n||t||e.replace("/app/login")},[n,t,e]),(0,r.useEffect)(()=>{D()},[D]),(0,r.useEffect)(()=>{"idle"===p&&D()},[p,w]),n||!t)?(0,i.jsx)("main",{style:m,children:(0,i.jsx)("p",{children:"Loadingâ¦"})}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(l(),{children:(0,i.jsx)("title",{children:"Sync Test | Move Physiotherapy"})}),(0,i.jsxs)("main",{style:m,children:[(0,i.jsx)("h1",{style:{fontFamily:"'DM Serif Display', serif",fontSize:"1.8rem",marginBottom:"0.25rem"},children:"Offline Sync Test"}),(0,i.jsx)("p",{style:{color:"var(--muted)",fontSize:"0.85rem",marginBottom:"1.5rem"},children:"Not for real workout data â this is scaffolding to validate the offline sync layer."}),(0,i.jsxs)("div",{style:h,children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("strong",{children:"Network:"})," ",x?"\uD83D\uDFE2 online":"\uD83D\uDD34 offline"]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("strong",{children:"Sync status:"})," ",p,"syncing"===p&&(0,i.jsx)("span",{style:g("#fff3cd","#856404"),children:"workingâ¦"}),"error"===p&&(0,i.jsx)("span",{style:g("#f8d7da","#721c24"),children:"error â check console"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("strong",{children:"Last synced:"})," ",w?w.toLocaleTimeString():"never"]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("strong",{children:"Logged in as:"})," ",null==o?void 0:o.email]}),(0,i.jsx)("button",{style:{...f,marginTop:"0.75rem"},onClick:j,children:"Force sync now"}),(0,i.jsx)("button",{style:{...y,marginTop:"0.75rem"},onClick:z,children:"Wipe local DB (this device only)"})]}),(0,i.jsxs)("div",{style:h,children:[(0,i.jsx)("button",{style:f,onClick:C,children:"+ Create test workout"}),(0,i.jsx)("button",{style:f,onClick:D,disabled:S,children:S?"Refreshingâ¦":"â» Refresh view"})]}),(0,i.jsxs)("h2",{style:{fontSize:"1.1rem",marginBottom:"0.75rem"},children:["Local workouts (",b.length,")"]}),0===b.length&&(0,i.jsx)("p",{style:{color:"var(--muted)"},children:"No workouts yet â create one above."}),b.map(e=>(0,i.jsxs)("div",{style:h,children:[(0,i.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"0.5rem"},children:[(0,i.jsx)("strong",{children:e.name}),(0,i.jsxs)("div",{children:[1===e.dirty&&(0,i.jsx)("span",{style:g("#fff3cd","#856404"),children:"unsynced"}),1===e.synced&&0===e.dirty&&(0,i.jsx)("span",{style:g("#d4edda","#155724"),children:"synced â"}),e.completed_at&&(0,i.jsx)("span",{style:g("#d1ecf1","#0c5460"),children:"completed"})]})]}),(0,i.jsxs)("div",{style:{fontSize:"0.75rem",color:"var(--muted)",marginBottom:"0.5rem"},children:["client_id: ",e.client_id,(0,i.jsx)("br",{}
1),"started: ",new Date(e.started_at).toLocaleString()]}),(0,i.jsx)("div",{style:{marginBottom:"0.5rem"},children:(v[e.client_id]||[]).map(e=>(0,i.jsxs)("div",{style:{fontSize:"0.8rem",color:"var(--dark)"},children:["Set ",e.set_number,": ",e.reps," reps @ ",e.load,e.load_unit,1===e.dirty&&(0,i.jsx)("span",{style:g("#fff3cd","#856404"),children:"unsynced"})]},e.client_id))}),(0,i.jsx)("button",{style:f,onClick:()=>B(e.client_id),children:"+ Add test set"}),!e.completed_at&&(0,i.jsx)("button",{style:f,onClick:()=>E(e.client_id),children:"Mark complete"}),(0,i.jsx)("button",{style:y,onClick:()=>N(e.client_id),children:"Delete"})]},e.client_id)),(0,i.jsx)("p",{style:{fontSize:"0.75rem",color:"var(--muted)",marginTop:"2rem"},children:'Test protocol: create a workout + set while online, confirm it turns green ("synced"). Then go offline (airplane mode or DevTools â Network â Offline), create another workout â it should still work instantly and show "unsynced". Go back online and confirm it turns green without you doing anything. Then check the same rows exist in Supabase\'s Table Editor.'})]})]})}}},function(e){e.O(0,[1023,2702,1611,5488,2888,9774,179],function(){return e(e.s=7712)}),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.