Files
Fridger/public/index.html
T
me0nline 1244c2091a
Build and Push Fridger Container / Build & Push Fridger Image (push) Successful in 1m53s
fix(ui): redesign filter overlay with 4-grid pack states and full readable category cards
2026-10-11 00:04:54 +02:00

667 lines
36 KiB
HTML
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.
<!DOCTYPE html>
<html lang="en" class="h-full bg-slate-950 text-slate-100">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Fridger - Current Stock & Manager</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
brand: {
400: '#2dd4bf',
500: '#14b8a6',
600: '#0d9488',
}
}
}
}
}
</script>
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<!-- HTML5 QR Code Scanner -->
<script src="https://unpkg.com/html5-qrcode" type="text/javascript"></script>
<link rel="stylesheet" href="/styles.css">
</head>
<body class="h-full flex flex-col bg-slate-950 text-slate-100 antialiased selection:bg-teal-500 selection:text-white select-none">
<!-- TOP HEADER -->
<header class="sticky top-0 z-30 bg-slate-900/95 backdrop-blur-md border-b border-slate-800 shadow-md">
<div class="max-w-4xl mx-auto px-3 sm:px-6">
<div class="flex items-center justify-between h-16 sm:h-20 gap-3">
<!-- Logo & Title -->
<a href="/" onclick="navigateTo('/'); return false;" class="flex items-center gap-2.5 shrink-0 group">
<div class="w-10 h-10 sm:w-11 sm:h-11 rounded-2xl bg-gradient-to-tr from-teal-500 to-cyan-400 flex items-center justify-center shadow-lg shadow-teal-500/20 text-white font-black text-xl group-hover:scale-105 transition-transform">
🧊
</div>
<div>
<h1 class="font-extrabold text-lg sm:text-xl leading-none bg-gradient-to-r from-teal-300 to-cyan-300 bg-clip-text text-transparent">Fridger</h1>
<p id="page-subtitle" class="text-[11px] text-slate-400 font-medium">Current Stock</p>
</div>
</a>
<!-- TOP NAVIGATION SWITCHER -->
<div class="flex items-center bg-slate-950 p-1.5 rounded-2xl border border-slate-800 shadow-inner gap-1">
<!-- 1. Current Stock (/) -->
<button
id="nav-stock-btn"
onclick="navigateTo('/')"
class="flex items-center justify-center gap-2 px-4 sm:px-6 py-2.5 sm:py-3 rounded-xl text-xs sm:text-sm font-bold transition-all bg-teal-500 text-white shadow-md active:scale-95 touch-manipulation min-h-[44px]"
>
<i data-lucide="layout-grid" class="w-4 h-4 sm:w-5 sm:h-5"></i>
<span>Current Stock</span>
</button>
<!-- 2. Manager (/manage) -->
<button
id="nav-manage-btn"
onclick="navigateTo('/manage')"
class="flex items-center justify-center gap-2 px-4 sm:px-6 py-2.5 sm:py-3 rounded-xl text-xs sm:text-sm font-bold transition-all text-slate-300 hover:text-white hover:bg-slate-800/80 active:scale-95 touch-manipulation min-h-[44px]"
>
<i data-lucide="sliders-horizontal" class="w-4 h-4 sm:w-5 sm:h-5 text-teal-400"></i>
<span>Manager</span>
</button>
</div>
</div>
</div>
</header>
<!-- ======================================================== -->
<!-- 1. ROOT VIEW: / (CURRENT STOCK ONLY) -->
<!-- ======================================================== -->
<div id="stock-view-page" class="flex-1 flex flex-col">
<!-- Quick Stock Summary Bar -->
<section class="bg-slate-900/50 border-b border-slate-800/60 py-2 sm:py-2.5">
<div class="max-w-4xl mx-auto px-3 sm:px-6">
<div class="flex items-center justify-between text-xs sm:text-sm text-slate-400 overflow-x-auto gap-4 scrollbar-none">
<div class="flex items-center gap-2 shrink-0">
<span class="w-2.5 h-2.5 rounded-full bg-teal-400"></span>
<span>Total Stock: <strong id="stat-total" class="text-white font-black text-sm sm:text-base">0</strong> items</span>
</div>
<div class="flex items-center gap-2 shrink-0">
<span class="w-2.5 h-2.5 rounded-full bg-emerald-400"></span>
<span>Full Packs: <strong id="stat-full" class="text-emerald-300 font-bold">0</strong></span>
</div>
<div class="flex items-center gap-2 shrink-0">
<span class="w-2.5 h-2.5 rounded-full bg-indigo-400"></span>
<span>Opened / Partial: <strong id="stat-opened" class="text-indigo-300 font-bold">0</strong></span>
</div>
<div class="flex items-center gap-2 shrink-0">
<span class="w-2.5 h-2.5 rounded-full bg-amber-400"></span>
<span>Low (&le;25%): <strong id="stat-low" class="text-amber-300 font-bold">0</strong></span>
</div>
</div>
</div>
</section>
<!-- Stock Search & Filter Trigger -->
<main class="flex-1 max-w-4xl mx-auto px-3 sm:px-6 py-4 w-full space-y-3">
<div class="space-y-2">
<div class="flex gap-2.5 items-center">
<div class="relative flex-1">
<i data-lucide="search" class="w-4 h-4 text-slate-400 absolute left-3.5 top-1/2 -translate-y-1/2"></i>
<input
type="text"
id="search-input"
placeholder="Search current stock by name, brand, or barcode..."
oninput="handleSearch(this.value)"
class="w-full bg-slate-900 border border-slate-800 focus:border-teal-500 rounded-xl pl-9 pr-9 py-2.5 text-sm sm:text-base text-slate-100 placeholder-slate-500 outline-none transition"
>
<button id="clear-search" onclick="clearSearch()" class="hidden absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-white p-1">
<i data-lucide="x" class="w-4 h-4"></i>
</button>
</div>
<!-- Filter Trigger Button (Opens Filter Overlay) -->
<button
id="filter-trigger-btn"
onclick="openFilterOverlay()"
class="px-4 py-2.5 rounded-xl bg-slate-900 hover:bg-slate-800 text-slate-300 border border-slate-800 text-xs sm:text-sm font-bold flex items-center gap-2 shrink-0 min-h-[42px] touch-manipulation transition shadow-sm active:scale-95"
>
<i data-lucide="filter" class="w-4 h-4 text-teal-400"></i>
<span>Filter</span>
<span id="stock-filter-badge" class="hidden px-1.5 py-0.5 text-[10px] font-black rounded-full bg-teal-500 text-white leading-none">0</span>
</button>
</div>
<!-- Active Filter Indicator Banner -->
<div id="active-filter-indicator" class="hidden flex items-center justify-between gap-2 p-2 px-3 bg-teal-950/50 border border-teal-500/40 rounded-xl text-xs animate-scale-up">
<div class="flex items-center gap-2 min-w-0">
<i data-lucide="filter" class="w-3.5 h-3.5 text-teal-400 shrink-0"></i>
<span id="active-filter-text" class="text-teal-200 truncate font-medium">Filtered</span>
</div>
<div class="flex items-center gap-2 shrink-0">
<button onclick="openFilterOverlay()" class="text-teal-300 hover:text-white text-xs font-bold underline">
Change
</button>
<span class="text-slate-600">&bull;</span>
<button onclick="resetAllFilters()" class="text-slate-400 hover:text-rose-300 text-xs font-medium">
Reset
</button>
</div>
</div>
</div>
<!-- Current Stock Grid (Display only) -->
<div id="stock-grid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3.5 sm:gap-4 pt-1">
<!-- Rendered items -->
</div>
<!-- Empty Stock State -->
<div id="empty-stock" class="hidden text-center py-16 px-4">
<div class="w-16 h-16 sm:w-20 sm:h-20 rounded-2xl bg-slate-900 text-slate-500 flex items-center justify-center mx-auto mb-3 border border-slate-800 text-3xl">
🧊
</div>
<h3 class="text-lg font-bold text-white mb-1">No items match your filter</h3>
<p class="text-xs sm:text-sm text-slate-400 max-w-xs mx-auto mb-6">Try resetting filters or adding items via Manager.</p>
<div class="flex items-center justify-center gap-3">
<button onclick="resetAllFilters()" class="px-4 py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-white text-xs sm:text-sm font-bold active:scale-95 touch-manipulation">
Reset Filters
</button>
<button onclick="navigateTo('/manage')" class="px-5 py-2.5 rounded-xl bg-teal-500 hover:bg-teal-400 text-white text-xs sm:text-sm font-bold flex items-center gap-2 shadow-lg shadow-teal-500/20 active:scale-95 touch-manipulation">
<i data-lucide="sliders-horizontal" class="w-4 h-4"></i>
<span>Go to Manager</span>
</button>
</div>
</div>
</main>
</div>
<!-- ======================================================== -->
<!-- FILTER OVERLAY MODAL -->
<!-- ======================================================== -->
<div id="filter-modal" class="fixed inset-0 z-50 bg-black/85 backdrop-blur-md hidden flex items-center justify-center p-3 sm:p-5 overflow-y-auto">
<div class="bg-slate-900 border border-slate-800 rounded-3xl max-w-2xl w-full p-5 sm:p-7 shadow-2xl space-y-6 my-auto animate-scale-up">
<!-- Top Title Bar -->
<div class="flex items-center justify-between pb-1 border-b border-slate-800/80">
<div>
<h3 class="text-lg sm:text-xl font-black text-white">Filter Stock</h3>
<p class="text-xs text-slate-400 mt-0.5">Filter inventory by condition or category</p>
</div>
<div class="flex items-center gap-2">
<button
onclick="resetAllFilters()"
class="px-3.5 py-1.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-300 hover:text-white text-xs font-bold transition active:scale-95 touch-manipulation border border-slate-700/60"
>
Reset
</button>
<button onclick="closeFilterOverlay()" class="text-slate-400 hover:text-white p-2 rounded-xl bg-slate-800/80 touch-manipulation hover:bg-slate-700 transition">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
</div>
<!-- Section 1: Pack States (Spacious 4-Grid, completely visible) -->
<div class="space-y-2.5">
<label class="text-xs font-bold text-teal-400 uppercase tracking-wider block">1. Pack State & Condition</label>
<div class="grid grid-cols-2 sm:grid-cols-4 gap-2.5">
<!-- All Pack States -->
<button
onclick="setStatusFilter('all')"
data-filter-status="all"
class="filter-status-card p-3.5 rounded-2xl border text-left flex flex-col justify-between space-y-2.5 transition-all active:scale-95 touch-manipulation bg-teal-500/20 border-teal-500 text-white shadow-lg shadow-teal-500/15 ring-2 ring-teal-500/30"
>
<div class="flex items-center justify-between">
<span class="w-8 h-8 rounded-xl bg-teal-500/20 text-teal-300 flex items-center justify-center">
<i data-lucide="layers" class="w-4 h-4"></i>
</span>
<span id="filter-count-all" class="text-xs font-bold px-2 py-0.5 rounded-md bg-slate-800 text-slate-200">0</span>
</div>
<div>
<h4 class="text-xs sm:text-sm font-extrabold text-white leading-tight">All Stock</h4>
<p class="text-[11px] text-slate-400 mt-0.5">Everything</p>
</div>
</button>
<!-- Full Packs -->
<button
onclick="setStatusFilter('full')"
data-filter-status="full"
class="filter-status-card p-3.5 rounded-2xl border text-left flex flex-col justify-between space-y-2.5 transition-all active:scale-95 touch-manipulation bg-slate-950 border-slate-800 text-slate-300 hover:border-slate-700"
>
<div class="flex items-center justify-between">
<span class="w-8 h-8 rounded-xl bg-emerald-500/20 text-emerald-400 flex items-center justify-center">
<i data-lucide="package-check" class="w-4 h-4"></i>
</span>
<span id="filter-count-full" class="text-xs font-bold px-2 py-0.5 rounded-md bg-slate-800 text-emerald-300">0</span>
</div>
<div>
<h4 class="text-xs sm:text-sm font-extrabold text-white leading-tight">Full Packs</h4>
<p class="text-[11px] text-slate-400 mt-0.5">Unopened</p>
</div>
</button>
<!-- Opened / In Use -->
<button
onclick="setStatusFilter('opened')"
data-filter-status="opened"
class="filter-status-card p-3.5 rounded-2xl border text-left flex flex-col justify-between space-y-2.5 transition-all active:scale-95 touch-manipulation bg-slate-950 border-slate-800 text-slate-300 hover:border-slate-700"
>
<div class="flex items-center justify-between">
<span class="w-8 h-8 rounded-xl bg-indigo-500/20 text-indigo-400 flex items-center justify-center">
<i data-lucide="package-open" class="w-4 h-4"></i>
</span>
<span id="filter-count-opened" class="text-xs font-bold px-2 py-0.5 rounded-md bg-slate-800 text-indigo-300">0</span>
</div>
<div>
<h4 class="text-xs sm:text-sm font-extrabold text-white leading-tight">Opened</h4>
<p class="text-[11px] text-slate-400 mt-0.5">In-Use / Partial</p>
</div>
</button>
<!-- Low Stock -->
<button
onclick="setStatusFilter('low')"
data-filter-status="low"
class="filter-status-card p-3.5 rounded-2xl border text-left flex flex-col justify-between space-y-2.5 transition-all active:scale-95 touch-manipulation bg-slate-950 border-slate-800 text-slate-300 hover:border-slate-700"
>
<div class="flex items-center justify-between">
<span class="w-8 h-8 rounded-xl bg-amber-500/20 text-amber-400 flex items-center justify-center">
<i data-lucide="alert-circle" class="w-4 h-4"></i>
</span>
<span id="filter-count-low" class="text-xs font-bold px-2 py-0.5 rounded-md bg-slate-800 text-amber-300">0</span>
</div>
<div>
<h4 class="text-xs sm:text-sm font-extrabold text-white leading-tight">Low Stock</h4>
<p class="text-[11px] text-slate-400 mt-0.5">&le;25% left</p>
</div>
</button>
</div>
</div>
<!-- Section 2: Categories (2-Column touch grid with full unabbreviated names) -->
<div class="space-y-2.5">
<label class="text-xs font-bold text-teal-400 uppercase tracking-wider block">2. Category</label>
<div id="filter-categories-container" class="grid grid-cols-1 sm:grid-cols-2 gap-2.5 max-h-[300px] overflow-y-auto p-1 pr-1.5 scrollbar-thin">
<!-- Populated dynamically with full unabbreviated names -->
</div>
</div>
<!-- Action: Big Prominent Done button -->
<div class="pt-2 border-t border-slate-800">
<button
onclick="closeFilterOverlay()"
class="w-full py-4 rounded-2xl bg-teal-500 hover:bg-teal-400 text-white font-black text-base sm:text-lg shadow-xl shadow-teal-500/25 active:scale-95 transition-all touch-manipulation flex items-center justify-center gap-2"
>
<i data-lucide="check" class="w-5 h-5 sm:w-6 sm:h-6"></i>
<span>Show Matching Stock (<span id="filter-total-count">0</span> items)</span>
</button>
</div>
</div>
</div>
<!-- ======================================================== -->
<!-- 2. MANAGER: /manage -->
<!-- ======================================================== -->
<div id="manage-view-page" class="hidden flex-1 flex flex-col">
<main class="flex-1 max-w-3xl mx-auto px-3 sm:px-6 py-4 sm:py-6 w-full space-y-4">
<!-- STEP 1: SCAN / SEARCH / ADD MANUALLY -->
<div id="tablet-step-select" class="bg-slate-900 border border-slate-800 rounded-3xl p-5 sm:p-7 shadow-xl space-y-5">
<div class="flex items-center justify-between gap-2">
<div>
<h2 class="text-lg sm:text-xl font-extrabold text-white">Manager</h2>
<p class="text-xs sm:text-sm text-slate-400">Scan barcode, search product, or add manually</p>
</div>
<!-- Add Manually Button -->
<button
onclick="openItemModal()"
class="px-4 py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-teal-300 border border-teal-500/30 text-xs sm:text-sm font-bold flex items-center gap-1.5 active:scale-95 touch-manipulation shadow-sm shrink-0"
>
<i data-lucide="plus" class="w-4 h-4"></i>
<span>Add Manually</span>
</button>
</div>
<!-- Integrated Camera Scanner & Live Search Box -->
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3 pt-1">
<!-- Big Camera Scanner Touch Launch -->
<button
onclick="openScannerModal()"
class="sm:col-span-1 p-4 rounded-2xl bg-gradient-to-r from-teal-500 to-emerald-600 hover:from-teal-400 hover:to-emerald-500 text-white font-extrabold flex items-center justify-center gap-3 shadow-lg shadow-teal-500/25 active:scale-95 touch-manipulation min-h-[60px]"
>
<i data-lucide="scan-barcode" class="w-6 h-6"></i>
<span class="text-sm sm:text-base">Scan Barcode</span>
</button>
<!-- Search or Barcode Input -->
<div class="sm:col-span-2 relative flex items-center">
<i data-lucide="search" class="w-5 h-5 text-slate-400 absolute left-4"></i>
<input
type="text"
id="tablet-search-input"
placeholder="Search product name, brand, or barcode..."
oninput="handleTabletSearch(this.value)"
class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-2xl pl-12 pr-4 py-3.5 text-sm sm:text-base text-white placeholder-slate-500 outline-none transition min-h-[60px]"
>
</div>
</div>
<!-- Matching Search Results Container (Only shows when searching) -->
<div id="tablet-search-results-container" class="hidden space-y-2 pt-3 border-t border-slate-800">
<label class="text-xs font-bold text-teal-400 uppercase tracking-wider block">Search Results:</label>
<div id="tablet-product-picker" class="grid grid-cols-1 sm:grid-cols-2 gap-2.5 max-h-64 overflow-y-auto p-1 scrollbar-none">
<!-- Populated dynamically when user searches -->
</div>
</div>
</div>
<!-- STEP 2 & 3: PRODUCT ACTION SCREEN (ADD / REMOVE -> PACKET / AMOUNT) -->
<div id="tablet-step-action" class="hidden bg-slate-900 border border-teal-500/40 rounded-3xl p-5 sm:p-6 shadow-2xl space-y-5 animate-scale-up">
<!-- Product Header Banner -->
<div class="bg-slate-950 p-4 rounded-2xl border border-slate-800 flex items-center justify-between gap-3">
<div class="flex items-center gap-3.5 min-w-0">
<div id="action-product-img" class="w-14 h-14 rounded-xl bg-slate-800 flex items-center justify-center text-teal-400 shrink-0 overflow-hidden">
<i data-lucide="package" class="w-7 h-7"></i>
</div>
<div class="min-w-0">
<h3 id="action-product-name" class="font-extrabold text-white text-base sm:text-lg truncate">Selected Product</h3>
<p id="action-product-sub" class="text-xs sm:text-sm text-slate-400 mt-0.5">Current Stock: 250g &bull; 1 Pack = 250g</p>
</div>
</div>
<button onclick="cancelActionAndReturnToManage()" class="text-slate-400 hover:text-white p-2 rounded-xl bg-slate-800/80 touch-manipulation">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<!-- Choose Action: Add or Remove -->
<div class="space-y-2.5">
<label class="text-xs font-bold text-slate-400 uppercase tracking-wider block">Choose Action:</label>
<div class="grid grid-cols-2 gap-3 sm:gap-4">
<button
id="action-btn-add"
onclick="setActionType('add')"
class="p-4 sm:p-5 rounded-2xl border-2 text-center font-extrabold transition-all active:scale-95 touch-manipulation flex flex-col items-center justify-center gap-2 min-h-[84px] bg-slate-950 border-slate-800 text-slate-300 hover:border-emerald-500/60 hover:text-white"
>
<i data-lucide="plus-circle" class="w-7 h-7 text-emerald-400"></i>
<span class="text-sm sm:text-base">➕ Add to Stock</span>
</button>
<button
id="action-btn-remove"
onclick="setActionType('remove')"
class="p-4 sm:p-5 rounded-2xl border-2 text-center font-extrabold transition-all active:scale-95 touch-manipulation flex flex-col items-center justify-center gap-2 min-h-[84px] bg-slate-950 border-slate-800 text-slate-300 hover:border-rose-500/60 hover:text-white"
>
<i data-lucide="minus-circle" class="w-7 h-7 text-rose-400"></i>
<span class="text-sm sm:text-base">➖ Remove from Stock</span>
</button>
</div>
</div>
<!-- Choose Mode: Whole Packet vs Specific Grams -->
<div id="action-qty-section" class="hidden space-y-4 pt-2 border-t border-slate-800">
<div class="grid grid-cols-2 gap-2 p-1.5 bg-slate-950 rounded-2xl border border-slate-800">
<button
id="btn-mode-packet"
onclick="setActionQtyMode('packet')"
class="py-3 px-3 rounded-xl font-bold text-xs sm:text-sm transition bg-teal-500 text-white shadow-md touch-manipulation flex items-center justify-center gap-2"
>
<i data-lucide="package" class="w-4 h-4"></i>
<span>Whole Packet(s)</span>
</button>
<button
id="btn-mode-amount"
onclick="setActionQtyMode('amount')"
class="py-3 px-3 rounded-xl font-bold text-xs sm:text-sm transition text-slate-300 hover:text-white touch-manipulation flex items-center justify-center gap-2"
>
<i data-lucide="scale" class="w-4 h-4"></i>
<span>Specific Grams / Amount</span>
</button>
</div>
<!-- Packet Controls -->
<div id="controls-packet" class="bg-slate-950 p-4 sm:p-5 rounded-2xl border border-slate-800 space-y-4 text-center">
<div class="text-xs sm:text-sm text-slate-400 font-medium">
1 Full Packet = <strong id="action-pack-size-label" class="text-teal-300 font-bold">250g</strong>
</div>
<div class="flex items-center justify-center gap-4">
<button onclick="changeActionPackCount(-1)" class="w-12 h-12 rounded-2xl bg-slate-800 hover:bg-slate-700 text-white font-extrabold text-2xl flex items-center justify-center active:scale-95 touch-manipulation border border-slate-700">-</button>
<div class="text-3xl sm:text-4xl font-black text-white min-w-[90px]">
<span id="action-pack-count-val">1</span> <span class="text-sm font-normal text-slate-400">pack</span>
</div>
<button onclick="changeActionPackCount(1)" class="w-12 h-12 rounded-2xl bg-slate-800 hover:bg-slate-700 text-white font-extrabold text-2xl flex items-center justify-center active:scale-95 touch-manipulation border border-slate-700">+</button>
</div>
<div class="flex items-center justify-center gap-2">
<button onclick="setActionPackCount(1)" class="px-3.5 py-1.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs text-slate-200 border border-slate-700 font-bold">1 Pack</button>
<button onclick="setActionPackCount(2)" class="px-3.5 py-1.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs text-slate-200 border border-slate-700 font-bold">2 Packs</button>
<button onclick="setActionPackCount(3)" class="px-3.5 py-1.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs text-slate-200 border border-slate-700 font-bold">3 Packs</button>
</div>
</div>
<!-- Specific Grams Controls (Slider & Quick Chips) -->
<div id="controls-amount" class="hidden bg-slate-950 p-4 sm:p-5 rounded-2xl border border-slate-800 space-y-4 text-center">
<div>
<div class="text-3xl sm:text-4xl font-black text-white flex items-center justify-center gap-1.5">
<span id="action-amount-val">150</span>
<span id="action-amount-unit" class="text-base font-normal text-teal-400">g</span>
</div>
<div class="text-xs text-slate-400 mt-1 font-medium">New remaining amount in stock</div>
</div>
<input
type="range"
id="action-amount-slider"
min="0"
max="500"
step="5"
value="150"
oninput="onActionAmountSlider(this.value)"
class="w-full accent-teal-500 cursor-pointer h-3.5 bg-slate-800 rounded-xl"
>
<div class="grid grid-cols-3 sm:grid-cols-6 gap-2">
<button onclick="applyActionDelta(-10)" class="py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs sm:text-sm text-slate-200 border border-slate-700 font-bold touch-manipulation">-10</button>
<button onclick="applyActionDelta(-25)" class="py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs sm:text-sm text-slate-200 border border-slate-700 font-bold touch-manipulation">-25</button>
<button onclick="applyActionDelta(-50)" class="py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs sm:text-sm text-slate-200 border border-slate-700 font-bold touch-manipulation">-50</button>
<button onclick="applyActionDelta(-100)" class="py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs sm:text-sm text-slate-200 border border-slate-700 font-bold touch-manipulation">-100</button>
<button onclick="setActionAmountRatio(0.5)" class="py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs sm:text-sm text-slate-200 border border-slate-700 font-bold touch-manipulation">Half</button>
<button onclick="setActionAmountRatio(0)" class="py-2.5 rounded-xl bg-rose-950/40 hover:bg-rose-900 text-xs sm:text-sm text-rose-300 border border-rose-800 font-bold touch-manipulation">0 (Empty)</button>
</div>
</div>
<!-- Confirm & Finish (Returns back to /manage) -->
<div class="flex items-center gap-3 pt-2">
<button
onclick="cancelActionAndReturnToManage()"
class="px-5 py-4 rounded-2xl bg-slate-800 hover:bg-slate-700 text-slate-300 font-bold text-sm touch-manipulation"
>
Cancel
</button>
<button
id="action-confirm-btn"
onclick="confirmAndFinishAction()"
class="flex-1 py-4 rounded-2xl bg-teal-500 hover:bg-teal-400 text-white font-black text-base sm:text-lg shadow-xl shadow-teal-500/25 active:scale-95 transition-all touch-manipulation flex items-center justify-center gap-2"
>
<i data-lucide="check" class="w-6 h-6"></i>
<span id="action-confirm-label">Confirm & Done</span>
</button>
</div>
</div>
</div>
</main>
</div>
<!-- ADD / EDIT ITEM MODAL -->
<div id="item-modal" class="fixed inset-0 z-50 bg-black/80 backdrop-blur-sm hidden flex items-center justify-center p-3 sm:p-4 overflow-y-auto">
<div class="bg-slate-900 border border-slate-800 rounded-3xl max-w-lg w-full p-5 sm:p-6 shadow-2xl space-y-4 my-8 animate-scale-up">
<div class="flex items-start justify-between">
<div>
<h3 id="item-modal-title" class="text-base sm:text-lg font-bold text-white">Add Product Manually</h3>
<p class="text-xs text-slate-400">Enter product name and package size</p>
</div>
<button onclick="closeItemModal()" class="text-slate-400 hover:text-white p-2 rounded-xl bg-slate-800/60 touch-manipulation">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<!-- Barcode Lookup row -->
<div class="bg-slate-950 p-2.5 sm:p-3 rounded-2xl border border-slate-800 flex items-center gap-2">
<div class="relative flex-1">
<i data-lucide="barcode" class="w-4 h-4 text-slate-400 absolute left-3 top-1/2 -translate-y-1/2"></i>
<input
type="text"
id="modal-barcode"
placeholder="Barcode (e.g. 4008452023451)"
class="w-full bg-slate-900 border border-slate-800 focus:border-teal-500 rounded-xl pl-9 pr-3 py-2 text-xs sm:text-sm text-white outline-none"
>
</div>
<button type="button" onclick="lookupCurrentBarcode()" id="modal-barcode-lookup-btn" class="px-3.5 py-2 rounded-xl bg-teal-600 hover:bg-teal-500 text-white text-xs sm:text-sm font-bold shrink-0 min-h-[38px] touch-manipulation">
Lookup
</button>
<button type="button" onclick="openScannerModal(true)" class="p-2 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-300 border border-slate-700 shrink-0 min-h-[38px] min-w-[38px] flex items-center justify-center touch-manipulation" title="Scan with Camera">
<i data-lucide="camera" class="w-4 h-4"></i>
</button>
</div>
<form id="item-form" onsubmit="handleItemFormSubmit(event)" class="space-y-3.5 text-xs sm:text-sm">
<input type="hidden" id="modal-item-id">
<input type="hidden" id="modal-image-url">
<div id="modal-image-container" class="hidden items-center gap-3 p-2.5 bg-slate-950 rounded-2xl border border-slate-800">
<img id="modal-image-preview" src="" alt="Product" class="w-12 h-12 object-contain rounded-xl bg-white/5">
<div class="flex-1 min-w-0">
<span class="text-xs text-teal-400 font-bold">Product Match</span>
<p id="modal-image-label" class="text-xs text-slate-400 truncate"></p>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-2.5">
<div class="sm:col-span-2">
<label class="block text-slate-300 font-semibold mb-1">Product Name *</label>
<input type="text" id="modal-name" required placeholder="e.g. Frozen Berries" class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-white outline-none">
</div>
<div>
<label class="block text-slate-300 font-semibold mb-1">Brand</label>
<input type="text" id="modal-brand" placeholder="e.g. Bio" class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-white outline-none">
</div>
</div>
<div class="grid grid-cols-3 gap-2.5">
<div>
<label class="block text-slate-300 font-semibold mb-1">Current Amount *</label>
<input type="number" id="modal-quantity" step="any" min="0" required placeholder="500" class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-white outline-none">
</div>
<div>
<label class="block text-slate-300 font-semibold mb-1">1 Full Pack Size *</label>
<input type="number" id="modal-initial-quantity" step="any" min="0" required placeholder="500" class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-white outline-none">
</div>
<div>
<label class="block text-slate-300 font-semibold mb-1">Unit</label>
<select id="modal-unit" class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-white outline-none">
<option value="g">Grams (g)</option>
<option value="ml">Milliliters (ml)</option>
<option value="pcs">Pieces (Stk)</option>
<option value="kg">Kilograms (kg)</option>
<option value="l">Liters (L)</option>
<option value="pack">Pack</option>
<option value="slices">Slices</option>
</select>
</div>
</div>
<div>
<label class="block text-slate-300 font-semibold mb-1">Category</label>
<select id="modal-category" class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-white outline-none">
<!-- Populated dynamically -->
</select>
</div>
<div>
<label class="block text-slate-300 font-semibold mb-1">Notes (Optional)</label>
<input type="text" id="modal-notes" placeholder="e.g. In freezer top basket" class="w-full bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-white outline-none">
</div>
<div class="flex items-center justify-end gap-3 pt-3 border-t border-slate-800">
<button type="button" onclick="closeItemModal()" class="px-5 py-3 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-300 text-sm font-medium touch-manipulation">Cancel</button>
<button type="submit" class="px-6 py-3 rounded-xl bg-teal-500 hover:bg-teal-400 text-white text-sm font-bold shadow-lg shadow-teal-500/20 active:scale-95 touch-manipulation">Save Product</button>
</div>
</form>
</div>
</div>
<!-- TABLET LIVE CAMERA BARCODE SCANNER MODAL -->
<div id="scanner-modal" class="fixed inset-0 z-50 bg-black/90 backdrop-blur-md hidden flex items-center justify-center p-3 sm:p-4">
<div class="bg-slate-900 border border-slate-800 rounded-3xl max-w-lg w-full overflow-hidden shadow-2xl flex flex-col animate-scale-up">
<div class="p-4 bg-slate-850 border-b border-slate-800 flex items-center justify-between">
<div class="flex items-center gap-2.5">
<div class="w-8 h-8 rounded-xl bg-teal-500/10 text-teal-400 flex items-center justify-center">
<i data-lucide="scan-barcode" class="w-5 h-5"></i>
</div>
<span class="font-extrabold text-white text-base">Barcode Scanner</span>
</div>
<button onclick="closeScannerModal()" class="text-slate-400 hover:text-white p-2 rounded-xl bg-slate-800/60 touch-manipulation">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<!-- Camera Viewfinder -->
<div class="relative bg-black flex items-center justify-center min-h-[300px] sm:min-h-[360px] w-full overflow-hidden">
<div id="barcode-reader" class="w-full"></div>
<div id="scanner-overlay" class="absolute inset-0 pointer-events-none border-2 border-teal-400/50 rounded-3xl m-8 sm:m-12 flex items-center justify-center">
<div class="w-full h-1 bg-red-500/90 animate-pulse shadow-lg shadow-red-500"></div>
</div>
</div>
<!-- Status & Manual fallback -->
<div class="p-4 bg-slate-900 space-y-3">
<div id="scanner-status" class="text-xs sm:text-sm text-center text-slate-400 font-medium">
Hold product barcode in front of camera
</div>
<div class="flex items-center gap-2">
<input
type="text"
id="scanner-manual-input"
placeholder="Or type barcode number manually..."
class="flex-1 bg-slate-950 border border-slate-800 focus:border-teal-500 rounded-xl px-3.5 py-2.5 text-xs sm:text-sm text-white outline-none"
onkeydown="if(event.key === 'Enter') handleManualBarcodeSubmit()"
>
<button onclick="handleManualBarcodeSubmit()" class="px-4 py-2.5 rounded-xl bg-teal-600 hover:bg-teal-500 text-white text-xs sm:text-sm font-bold min-h-[42px] touch-manipulation">
Lookup
</button>
</div>
</div>
</div>
</div>
<!-- TOAST NOTIFICATION CONTAINER -->
<div id="toast-container" class="fixed bottom-5 right-5 z-50 flex flex-col gap-2 max-w-sm pointer-events-none"></div>
<!-- MAIN SCRIPT -->
<script src="/app.js"></script>
</body>
</html>