felt/frontend/build/_app/immutable/nodes/4.Ct0ahWmg.js
Mikkel Georgsen 7f91301efa feat(01-13): layout shell with header, tabs, FAB, toast, data table
- Persistent header: clock countdown, level, blinds, player count (red pulse <10s, PAUSED/BREAK badges)
- Bottom tab bar (mobile): Overview, Players, Tables, Financials, More with 48px touch targets
- Desktop sidebar (>=768px): vertical nav replacing bottom tabs
- FAB: expandable quick actions (Bust, Buy In, Rebuy, Add-On, Pause/Resume) with backdrop
- Toast notification system: success/info/warning/error with auto-dismiss and stacking
- DataTable: sortable columns, sticky header, search/filter, mobile swipe actions, skeleton loading
- Multi-tournament tabs: horizontal scrollable selector when 2+ tournaments active
- Loading components: spinner (sm/md/lg), skeleton rows, full-page overlay
- Root layout: auth guard, responsive shell (mobile bottom tabs / desktop sidebar)
- Route pages: overview, players, tables, financials, more with placeholder content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 04:13:17 +01:00

1 line
4 KiB
JavaScript

import{a as f,f as y,t as M}from"../chunks/Q5CB4WY5.js";import{o as V}from"../chunks/nIaoZoCo.js";import{p as W,t as _,a as Y,a0 as Z,c as p,s as u,r as d,g as r,b as A,d as o}from"../chunks/C4An0dnW.js";import{d as tt,e as et,a as g,s as U}from"../chunks/CQQh_IlD.js";import{i as G}from"../chunks/D__6P984.js";import{e as O,i as R,s as q,a as at}from"../chunks/BeLKMLqR.js";import{a as k}from"../chunks/D3f6eoxz.js";import{g as D}from"../chunks/DQNCp18R.js";class C extends Error{constructor(s,a,i){const n=typeof i=="object"&&i!==null&&"error"in i?i.error:a;super(n),this.status=s,this.statusText=a,this.body=i,this.name="ApiError"}}function rt(){return`${window.location.origin}/api/v1`}function st(e){const s={Accept:"application/json"};e&&(s["Content-Type"]="application/json");const a=k.token;return a&&(s.Authorization=`Bearer ${a}`),s}async function it(e){if(e.status===401)throw k.logout(),await D("/login"),new C(401,"Unauthorized",{error:"Session expired"});if(!e.ok){let s;try{s=await e.json()}catch{s={error:e.statusText}}throw new C(e.status,e.statusText,s)}if(e.status!==204)return e.json()}async function m(e,s,a){const i=`${rt()}${s}`,n={method:e,headers:st(a!==void 0),credentials:"same-origin"};a!==void 0&&(n.body=JSON.stringify(a));const v=await fetch(i,n);return it(v)}const nt={get(e){return m("GET",e)},post(e,s){return m("POST",e,s)},put(e,s){return m("PUT",e,s)},patch(e,s){return m("PATCH",e,s)},delete(e){return m("DELETE",e)}};var ot=y("<div></div>"),lt=y('<div class="error-message svelte-1x05zx6" role="alert"> </div>'),ct=y('<button class="numpad-btn touch-target svelte-1x05zx6"> </button>'),ut=y('<main class="login-container svelte-1x05zx6"><div class="login-card svelte-1x05zx6"><div class="logo svelte-1x05zx6"><h1 class="svelte-1x05zx6">Felt</h1> <p class="subtitle svelte-1x05zx6">Tournament Manager</p></div> <div class="pin-display svelte-1x05zx6" role="status"></div> <!> <div class="numpad svelte-1x05zx6"><!> <button class="numpad-btn numpad-fn touch-target svelte-1x05zx6" aria-label="Clear PIN">CLR</button> <button class="numpad-btn touch-target svelte-1x05zx6" aria-label="Digit 0">0</button> <button class="numpad-btn numpad-fn touch-target svelte-1x05zx6" aria-label="Delete last digit">DEL</button></div> <button class="submit-btn touch-target svelte-1x05zx6"><!></button></div></main>');function bt(e,s){W(s,!0);let a=A(""),i=A(""),n=A(!1);const v=6;V(()=>{k.isAuthenticated&&D("/")});function w(t){r(a).length>=v||(o(a,r(a)+t),o(i,""))}function I(){o(a,r(a).slice(0,-1),!0),o(i,"")}function N(){o(a,""),o(i,"")}async function j(){if(!(r(a).length<4||r(n))){o(n,!0),o(i,"");try{const t=await nt.post("/auth/login",{pin:r(a)});k.login(t.token,{id:t.operator.id,name:t.operator.name,role:t.operator.role}),await D("/")}catch(t){t instanceof C?t.status===429?o(i,"Too many attempts. Please wait."):t.status===401?o(i,"Invalid PIN. Try again."):o(i,t.message,!0):o(i,"Connection error. Check your network."),o(a,"")}finally{o(n,!1)}}}function F(t){t.key>="0"&&t.key<="9"?w(t.key):t.key==="Backspace"?I():t.key==="Enter"?j():t.key==="Escape"&&N()}var z=ut();et("keydown",Z,F);var S=p(z),x=u(p(S),2);O(x,21,()=>Array(v),R,(t,l,c)=>{var b=ot();let H;_(()=>H=at(b,1,"pin-dot svelte-1x05zx6",null,H,{filled:c<r(a).length})),f(t,b)}),d(x);var $=u(x,2);{var J=t=>{var l=lt(),c=p(l,!0);d(l),_(()=>U(c,r(i))),f(t,l)};G($,t=>{r(i)&&t(J)})}var T=u($,2),L=p(T);O(L,16,()=>["1","2","3","4","5","6","7","8","9"],R,(t,l)=>{var c=ct(),b=p(c,!0);d(c),_(()=>{c.disabled=r(n)||r(a).length>=v,q(c,"aria-label",`Digit ${l??""}`),U(b,l)}),g("click",c,()=>w(l)),f(t,c)});var E=u(L,2),P=u(E,2),B=u(P,2);d(T);var h=u(T,2),K=p(h);{var X=t=>{var l=M("Signing in...");f(t,l)},Q=t=>{var l=M("Sign In");f(t,l)};G(K,t=>{r(n)?t(X):t(Q,!1)})}d(h),d(S),d(z),_(()=>{q(x,"aria-label",`PIN entered: ${r(a).length??""} digits`),E.disabled=r(n),P.disabled=r(n)||r(a).length>=v,B.disabled=r(n)||r(a).length===0,h.disabled=r(a).length<4||r(n)}),g("click",E,N),g("click",P,()=>w("0")),g("click",B,I),g("click",h,j),f(e,z),Y()}tt(["click"]);export{bt as component};