Files
tfm_ainventory/frontend/public/sw.js
Daniel Bedeleanu 710806bb14 feat(frontend): add accessible confirmation modal for destructive actions
Replace native window.confirm() dialogs with branded ConfirmationModal component
for all delete operations (users, categories). Implements progressive disclosure
for high-risk operations and requires confirmation text input for deletions with
100+ affected items.

Features:
- ConfirmationModal component with dynamic risk levels (low/medium/high)
- High-risk operations (100+ affected items) require 'DELETE' text confirmation
- Clear consequence messaging with affected item counts
- Loading state during deletion with visual feedback
- Full keyboard accessibility (Esc to cancel, Enter to confirm)
- Proper focus management and ARIA labels

Affected:
- AdminOverlay: Delete user and category now use ConfirmationModal
- New: ConfirmationModal.tsx component

Design: Matches CreateUserModal aesthetic (clean, minimal) with rose-500
accent for danger context. Progressive disclosure shows additional warnings
only for high-risk operations.

Build: Passes with zero errors.
2026-04-17 10:37:56 +03:00

2 lines
6.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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} didnt 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 o=e=>n(e,t),r={module:{uri:t},exports:i,require:o};s[t]=Promise.all(a.map(e=>r[e]||o(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:"5bb0569aa674e6d3e36d86e793462b4d"},{url:"/_next/static/Zc-ofcvXWoVDsUqNYbn2T/_buildManifest.js",revision:"31eba5c94d685fe15b2d866310094bce"},{url:"/_next/static/Zc-ofcvXWoVDsUqNYbn2T/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/255-4f212684648fcab9.js",revision:"4f212684648fcab9"},{url:"/_next/static/chunks/310-133da0a7e784e153.js",revision:"133da0a7e784e153"},{url:"/_next/static/chunks/374-a4ed2a0d861d9cab.js",revision:"a4ed2a0d861d9cab"},{url:"/_next/static/chunks/4bd1b696-c023c6e3521b1417.js",revision:"c023c6e3521b1417"},{url:"/_next/static/chunks/734-e24e71e2ffc7aee6.js",revision:"e24e71e2ffc7aee6"},{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-f51f0bf19601ca65.js",revision:"f51f0bf19601ca65"},{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-b8053775f0703fc1.js",revision:"b8053775f0703fc1"},{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-3844d017889aa547.js",revision:"3844d017889aa547"},{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")});