From ab43256aa0debd83d9e3a9dad0967007860cdbf9 Mon Sep 17 00:00:00 2001 From: Daniel Bedeleanu Date: Fri, 17 Apr 2026 10:49:15 +0300 Subject: [PATCH] refactor: distill AdminOverlay complexity and inject color boldness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace window.prompt() for category creation with dedicated CategoryCreationModal component - Increase visual hierarchy: section headings slate-500 → slate-400 (bolder, more confident) - Standardize Add User/Category button styling with consistent hover states and focus indicators - Remove browser prompt friction; all forms now use accessible modal dialogs - Technical, precise aesthetic: reduced visual clutter, increased contrast and decision clarity --- .impeccable.md | 48 +++++++ frontend/components/AdminOverlay.tsx | 33 ++--- frontend/components/CategoryCreationModal.tsx | 135 ++++++++++++++++++ frontend/public/sw.js | 2 +- 4 files changed, 201 insertions(+), 17 deletions(-) create mode 100644 .impeccable.md create mode 100644 frontend/components/CategoryCreationModal.tsx diff --git a/.impeccable.md b/.impeccable.md new file mode 100644 index 00000000..4db60003 --- /dev/null +++ b/.impeccable.md @@ -0,0 +1,48 @@ +# Design Context: TFM aInventory + +## Users + +**Primary Users:** Field operators AND administrative staff (hybrid usage) +- **Field Operators:** Using on-site/in-warehouse on mobile devices for real-time scanning, inventory check-in/out, offline data collection +- **Admin Staff:** Using on desktop for user management, category management, audit logs, system settings +- **Context:** High-stakes environment; accuracy critical; both speed (field) and comprehension (admin) matter equally + +## Brand Personality + +**3-Word Profile:** Technical. Precise. Decisive. + +- **Voice:** Direct, no-nonsense, authoritative. Every element serves a clear function. +- **Tone:** Business-focused, reliable, confident. Users trust this system with their inventory. +- **Emotional Goal:** Confidence in accuracy; reassurance that nothing will be lost or mistyped; decisiveness in destructive actions. + +## Aesthetic Direction + +**Theme:** Dark mode (current), but bolder and more distinctive + +**Why Dark:** Field operators often use devices in varying lighting (warehouse basements, outdoors). Dark mode reduces eye strain and works across contexts. + +**Current State:** Minimal slate/blue palette. Recently removed glassmorphism (backdrop-blur). Clean but understated. + +**Opportunity:** Inject personality and visual weight while maintaining technical precision. The current aesthetic is correct in *restraint* but lacks *boldness*. Dark mode should feel confident and intentional, not just "safe default." + +**Aesthetic Inspiration:** Industrial + Technical +- Precision instruments (clean lines, exact details) +- Command center interfaces (high contrast, clear hierarchy) +- Lab equipment (honest materials, no decoration) +- NOT: Glassmorphism, gradients, glows, or decoration without function + +## Design Principles + +1. **Clarity Through Contrast:** High visual hierarchy. Field operators need to scan + act in seconds. Admins need to parse complex data quickly. Use color, size, and weight strategically. + +2. **Technical Precision:** Every element has intention. No decoration. Use whitespace and alignment to create rhythm, not visual effects. + +3. **Dual-Context Adaptation:** Field view (mobile, fast, action-focused) vs. Admin view (desktop, data-rich, decision-focused). Same visual language, different complexity. + +4. **Dark Mode Confidence:** Dark shouldn't mean "timid." Use bold primary colors, high-contrast text, purposeful accents. Make the dark feel deliberate. + +5. **Offline-First Reliability:** Suggest stability and trust. No animations that suggest pending network requests. Solid, grounded UI. + +--- + +**Next Step:** Use these principles to guide `/distill` — systematically remove unnecessary complexity and inject bold, technical personality into the interface. diff --git a/frontend/components/AdminOverlay.tsx b/frontend/components/AdminOverlay.tsx index 42f32a03..8fb3b4da 100644 --- a/frontend/components/AdminOverlay.tsx +++ b/frontend/components/AdminOverlay.tsx @@ -6,6 +6,7 @@ import { inventoryApi } from '@/lib/api'; import { toast } from 'react-hot-toast'; import CreateUserModal from './CreateUserModal'; import ConfirmationModal from './ConfirmationModal'; +import CategoryCreationModal from './CategoryCreationModal'; interface AdminOverlayProps { show: boolean; @@ -25,6 +26,7 @@ export default function AdminOverlay({ onUpdateCategories }: AdminOverlayProps) { const [showCreateUserModal, setShowCreateUserModal] = useState(false); + const [showCreateCategoryModal, setShowCreateCategoryModal] = useState(false); const [confirmState, setConfirmState] = useState<{ show: boolean; type: 'user' | 'category' | null; @@ -44,6 +46,10 @@ export default function AdminOverlay({ inventoryApi.getUsers().then(onUpdateUsers); }; + const handleCategoryCreated = () => { + inventoryApi.getCategories().then(onUpdateCategories); + }; + const handleDeleteUser = async () => { if (!confirmState.itemId) return; setConfirmState(prev => ({ ...prev, loading: true })); @@ -79,6 +85,11 @@ export default function AdminOverlay({ onClose={() => setShowCreateUserModal(false)} onUserCreated={handleUserCreated} /> + setShowCreateCategoryModal(false)} + onCategoryCreated={handleCategoryCreated} + />
-

User Management

+

User Management

@@ -169,20 +180,10 @@ export default function AdminOverlay({
-

Category Groups

- diff --git a/frontend/components/CategoryCreationModal.tsx b/frontend/components/CategoryCreationModal.tsx new file mode 100644 index 00000000..135f4460 --- /dev/null +++ b/frontend/components/CategoryCreationModal.tsx @@ -0,0 +1,135 @@ +'use client'; + +import { useState } from 'react'; +import { X, Loader2, Tag } from 'lucide-react'; +import { inventoryApi } from '@/lib/api'; +import { toast } from 'react-hot-toast'; + +interface CategoryCreationModalProps { + show: boolean; + onClose: () => void; + onCategoryCreated: () => void; +} + +export default function CategoryCreationModal({ + show, + onClose, + onCategoryCreated +}: CategoryCreationModalProps) { + const [name, setName] = useState(''); + const [description, setDescription] = useState(''); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + if (!show) return null; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!name.trim()) { + setError('Category name is required'); + return; + } + + setLoading(true); + setError(null); + try { + await inventoryApi.createCategory({ + name: name.trim(), + description: description.trim() || undefined + }); + toast.success('Category added'); + setName(''); + setDescription(''); + onCategoryCreated(); + onClose(); + } catch (err: any) { + setError(err?.response?.data?.detail || 'Failed to create category'); + } finally { + setLoading(false); + } + }; + + return ( +
+
+
+
+
+ +
+

New Category

+
+ +
+ +
+
+ + { + setName(e.target.value); + setError(null); + }} + placeholder="e.g., Electronics" + className="w-full mt-2 px-3 py-2.5 bg-slate-800 border border-slate-700 rounded text-white placeholder-slate-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary" + disabled={loading} + autoFocus + /> +
+ +
+ + setDescription(e.target.value)} + placeholder="Brief category description" + className="w-full mt-2 px-3 py-2.5 bg-slate-800 border border-slate-700 rounded text-white placeholder-slate-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary" + disabled={loading} + /> +
+ + {error && ( +
+

{error}

+
+ )} + +
+ + +
+
+
+
+ ); +} diff --git a/frontend/public/sw.js b/frontend/public/sw.js index cf4c0a86..54835c28 100644 --- a/frontend/public/sw.js +++ b/frontend/public/sw.js @@ -1 +1 @@ -if(!self.define){let e,s={};const n=(n,a)=>(n=new URL(n+".js",a).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(a,c)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let i={};const r=e=>n(e,t),o={module:{uri:t},exports:i,require:r};s[t]=Promise.all(a.map(e=>o[e]||r(e))).then(e=>(c(...e),i))}}define(["./workbox-4754cb34"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/app-build-manifest.json",revision:"29c75904d14744f54c5cd9d0a6428af4"},{url:"/_next/static/DNCRUeOeT7qM4m_PYNuTF/_buildManifest.js",revision:"31eba5c94d685fe15b2d866310094bce"},{url:"/_next/static/DNCRUeOeT7qM4m_PYNuTF/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/13.ae2fd9645430ed90.js",revision:"ae2fd9645430ed90"},{url:"/_next/static/chunks/255-4f212684648fcab9.js",revision:"4f212684648fcab9"},{url:"/_next/static/chunks/374-a4ed2a0d861d9cab.js",revision:"a4ed2a0d861d9cab"},{url:"/_next/static/chunks/4bd1b696-c023c6e3521b1417.js",revision:"c023c6e3521b1417"},{url:"/_next/static/chunks/512-ce90bee899e5ddb3.js",revision:"ce90bee899e5ddb3"},{url:"/_next/static/chunks/734-72a8cb724bac0848.js",revision:"72a8cb724bac0848"},{url:"/_next/static/chunks/7cb1fa1f-32fc9056ac653916.js",revision:"32fc9056ac653916"},{url:"/_next/static/chunks/802-838213ff73429b14.js",revision:"838213ff73429b14"},{url:"/_next/static/chunks/814-d4585cd22c8d1c30.js",revision:"d4585cd22c8d1c30"},{url:"/_next/static/chunks/app/_not-found/page-32814a613bf1bbe9.js",revision:"32814a613bf1bbe9"},{url:"/_next/static/chunks/app/admin/page-a4e3a351f300e812.js",revision:"a4e3a351f300e812"},{url:"/_next/static/chunks/app/inventory/page-124809fba18361dd.js",revision:"124809fba18361dd"},{url:"/_next/static/chunks/app/layout-61972fdaeb813508.js",revision:"61972fdaeb813508"},{url:"/_next/static/chunks/app/login/page-02dc65ae8ac5ac4d.js",revision:"02dc65ae8ac5ac4d"},{url:"/_next/static/chunks/app/logs/page-92b68bd71d7039c5.js",revision:"92b68bd71d7039c5"},{url:"/_next/static/chunks/app/page-8bd066e60807cecd.js",revision:"8bd066e60807cecd"},{url:"/_next/static/chunks/framework-050c1f32293f7182.js",revision:"050c1f32293f7182"},{url:"/_next/static/chunks/main-aa573100fdde0547.js",revision:"aa573100fdde0547"},{url:"/_next/static/chunks/main-app-290572149fe5c423.js",revision:"290572149fe5c423"},{url:"/_next/static/chunks/pages/_app-7d307437aca18ad4.js",revision:"7d307437aca18ad4"},{url:"/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js",revision:"cb2a52f75f2162e2"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-7a9cf6b863b8c67d.js",revision:"7a9cf6b863b8c67d"},{url:"/_next/static/css/dc224c75436c9a0e.css",revision:"dc224c75436c9a0e"},{url:"/custom-logo.png",revision:"d41d8cd98f00b204e9800998ecf8427e"},{url:"/icons/icon-192x192.png",revision:"bde7fc04fd83ed65ce0e71259f4574b5"},{url:"/icons/icon-512x512.png",revision:"0c2346ba1775af7af6ec2e346ee7c72e"},{url:"/icons/maskable-icon.png",revision:"0c2346ba1775af7af6ec2e346ee7c72e"},{url:"/logo.png",revision:"084f394cfe19b7d85abec9878a797795"},{url:"/logo_TFM.png",revision:"084f394cfe19b7d85abec9878a797795"},{url:"/manifest.json",revision:"7b6e42d577201b657b72b8698d44d0b2"},{url:"/network.json",revision:"ce173a00263b4f64c8c05fe22ef7c54f"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:s,event:n,state:a})=>s&&"opaqueredirect"===s.type?new Response(s.body,{status:200,statusText:"OK",headers:s.headers}):s}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;const s=e.pathname;return!s.startsWith("/api/auth/")&&!!s.startsWith("/api/")},new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;return!e.pathname.startsWith("/api/")},new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>!(self.origin===e.origin),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")}); +if(!self.define){let e,s={};const n=(n,a)=>(n=new URL(n+".js",a).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(a,c)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let i={};const r=e=>n(e,t),o={module:{uri:t},exports:i,require:r};s[t]=Promise.all(a.map(e=>o[e]||r(e))).then(e=>(c(...e),i))}}define(["./workbox-4754cb34"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/app-build-manifest.json",revision:"280dba0ac671c5cba4ab8b21f9a1550f"},{url:"/_next/static/chunks/13.ae2fd9645430ed90.js",revision:"ae2fd9645430ed90"},{url:"/_next/static/chunks/255-4f212684648fcab9.js",revision:"4f212684648fcab9"},{url:"/_next/static/chunks/374-a4ed2a0d861d9cab.js",revision:"a4ed2a0d861d9cab"},{url:"/_next/static/chunks/4bd1b696-c023c6e3521b1417.js",revision:"c023c6e3521b1417"},{url:"/_next/static/chunks/512-ce90bee899e5ddb3.js",revision:"ce90bee899e5ddb3"},{url:"/_next/static/chunks/734-72a8cb724bac0848.js",revision:"72a8cb724bac0848"},{url:"/_next/static/chunks/7cb1fa1f-32fc9056ac653916.js",revision:"32fc9056ac653916"},{url:"/_next/static/chunks/802-838213ff73429b14.js",revision:"838213ff73429b14"},{url:"/_next/static/chunks/814-d4585cd22c8d1c30.js",revision:"d4585cd22c8d1c30"},{url:"/_next/static/chunks/app/_not-found/page-32814a613bf1bbe9.js",revision:"32814a613bf1bbe9"},{url:"/_next/static/chunks/app/admin/page-a4e3a351f300e812.js",revision:"a4e3a351f300e812"},{url:"/_next/static/chunks/app/inventory/page-124809fba18361dd.js",revision:"124809fba18361dd"},{url:"/_next/static/chunks/app/layout-61972fdaeb813508.js",revision:"61972fdaeb813508"},{url:"/_next/static/chunks/app/login/page-02dc65ae8ac5ac4d.js",revision:"02dc65ae8ac5ac4d"},{url:"/_next/static/chunks/app/logs/page-92b68bd71d7039c5.js",revision:"92b68bd71d7039c5"},{url:"/_next/static/chunks/app/page-8bd066e60807cecd.js",revision:"8bd066e60807cecd"},{url:"/_next/static/chunks/framework-050c1f32293f7182.js",revision:"050c1f32293f7182"},{url:"/_next/static/chunks/main-aa573100fdde0547.js",revision:"aa573100fdde0547"},{url:"/_next/static/chunks/main-app-290572149fe5c423.js",revision:"290572149fe5c423"},{url:"/_next/static/chunks/pages/_app-7d307437aca18ad4.js",revision:"7d307437aca18ad4"},{url:"/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js",revision:"cb2a52f75f2162e2"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-7a9cf6b863b8c67d.js",revision:"7a9cf6b863b8c67d"},{url:"/_next/static/css/b98aedde9b5e979f.css",revision:"b98aedde9b5e979f"},{url:"/_next/static/gIJfQ4Rvkz7VZOqUlVq62/_buildManifest.js",revision:"31eba5c94d685fe15b2d866310094bce"},{url:"/_next/static/gIJfQ4Rvkz7VZOqUlVq62/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/custom-logo.png",revision:"d41d8cd98f00b204e9800998ecf8427e"},{url:"/icons/icon-192x192.png",revision:"bde7fc04fd83ed65ce0e71259f4574b5"},{url:"/icons/icon-512x512.png",revision:"0c2346ba1775af7af6ec2e346ee7c72e"},{url:"/icons/maskable-icon.png",revision:"0c2346ba1775af7af6ec2e346ee7c72e"},{url:"/logo.png",revision:"084f394cfe19b7d85abec9878a797795"},{url:"/logo_TFM.png",revision:"084f394cfe19b7d85abec9878a797795"},{url:"/manifest.json",revision:"7b6e42d577201b657b72b8698d44d0b2"},{url:"/network.json",revision:"ce173a00263b4f64c8c05fe22ef7c54f"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:s,event:n,state:a})=>s&&"opaqueredirect"===s.type?new Response(s.body,{status:200,statusText:"OK",headers:s.headers}):s}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;const s=e.pathname;return!s.startsWith("/api/auth/")&&!!s.startsWith("/api/")},new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;return!e.pathname.startsWith("/api/")},new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>!(self.origin===e.origin),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")});