Merge branch 'dev'
This commit is contained in:
@@ -59,6 +59,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* PWA install banner — rendered by JS only on mobile, hidden once dismissed or already installed *@
|
||||
<div id="pwa-install-banner" class="row mb-4" style="display:none!important;">
|
||||
<div class="col-12">
|
||||
<div class="alert alert-permanent mb-0 d-flex align-items-start gap-3 py-3"
|
||||
style="background:var(--pcl-paper-2);border:1px solid var(--pcl-rule);border-left:4px solid var(--pcl-ember);">
|
||||
<div class="flex-shrink-0 mt-1">
|
||||
<img src="/images/pwa-icon-192.png" alt="" width="36" height="36" style="border-radius:8px;">
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-semibold mb-1" id="pwa-banner-title">Add to Home Screen</div>
|
||||
<div class="text-muted small" id="pwa-banner-msg"></div>
|
||||
</div>
|
||||
<button type="button" class="btn-close flex-shrink-0" id="pwa-banner-dismiss" aria-label="Dismiss"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (guidedActivationBanner?.Show == true)
|
||||
{
|
||||
<div class="row mb-4">
|
||||
@@ -1253,6 +1270,61 @@
|
||||
</script>
|
||||
}
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var DISMISSED_KEY = 'pcl_pwa_banner_dismissed';
|
||||
|
||||
// Already installed as standalone — never show
|
||||
var isStandalone = window.navigator.standalone === true ||
|
||||
window.matchMedia('(display-mode: standalone)').matches;
|
||||
if (isStandalone) return;
|
||||
|
||||
// Already dismissed
|
||||
if (localStorage.getItem(DISMISSED_KEY)) return;
|
||||
|
||||
var ua = navigator.userAgent || '';
|
||||
var isIOS = /iphone|ipad|ipod/i.test(ua);
|
||||
var isAndroid = /android/i.test(ua);
|
||||
|
||||
// Only show on mobile
|
||||
if (!isIOS && !isAndroid) return;
|
||||
|
||||
var banner = document.getElementById('pwa-install-banner');
|
||||
var msgEl = document.getElementById('pwa-banner-msg');
|
||||
var titleEl = document.getElementById('pwa-banner-title');
|
||||
|
||||
if (isIOS) {
|
||||
// Detect Safari: has WebKit in UA but NOT Chrome/CriOS/FxiOS
|
||||
var isSafari = /webkit/i.test(ua) && !/crios|chrome|fxios|opios/i.test(ua);
|
||||
if (isSafari) {
|
||||
titleEl.textContent = 'Add to Home Screen';
|
||||
msgEl.innerHTML = 'For the best experience — and so the camera only asks once — open the ' +
|
||||
'<strong>Share menu</strong> <span style="font-size:1.1em">▲</span> at the bottom of Safari ' +
|
||||
'and tap <strong>Add to Home Screen</strong>.';
|
||||
} else {
|
||||
titleEl.textContent = 'Open in Safari to Install';
|
||||
msgEl.innerHTML = 'To add Powder Coating Logix to your home screen, <strong>open this page in Safari</strong> ' +
|
||||
'(not Chrome or another browser), then tap the <strong>Share menu</strong> ' +
|
||||
'<span style="font-size:1.1em">▲</span> and choose <strong>Add to Home Screen</strong>. ' +
|
||||
'This also means the camera only asks for permission once.';
|
||||
}
|
||||
} else {
|
||||
// Android
|
||||
titleEl.textContent = 'Add to Home Screen';
|
||||
msgEl.innerHTML = 'Tap the browser <strong>menu (⋮)</strong> and choose ' +
|
||||
'<strong>Add to Home Screen</strong> or <strong>Install App</strong> for the best experience ' +
|
||||
'and persistent camera access.';
|
||||
}
|
||||
|
||||
banner.style.removeProperty('display');
|
||||
|
||||
document.getElementById('pwa-banner-dismiss').addEventListener('click', function () {
|
||||
localStorage.setItem(DISMISSED_KEY, '1');
|
||||
banner.style.display = 'none';
|
||||
});
|
||||
}());
|
||||
</script>
|
||||
|
||||
@functions {
|
||||
IHtmlContent PriorityBadge(string priorityCode, string displayName, string colorClass)
|
||||
{
|
||||
|
||||
@@ -379,6 +379,56 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="mobile-install" class="mb-5">
|
||||
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
|
||||
<i class="bi bi-phone text-primary me-2"></i>Using on Mobile — Add to Home Screen
|
||||
</h2>
|
||||
<p>
|
||||
Powder Coating Logix works in any phone browser, but installing it as a <strong>home screen app</strong>
|
||||
gives your shop floor workers a much better experience:
|
||||
</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-1">Opens full-screen with no browser chrome — feels like a native app.</li>
|
||||
<li class="mb-1">The camera (used by the inventory label scanner) only asks for permission <strong>once</strong> after installation, instead of every browser session.</li>
|
||||
<li class="mb-1">Faster to launch — one tap from the home screen.</li>
|
||||
</ul>
|
||||
|
||||
<div class="alert alert-permanent alert-warning d-flex gap-2 mb-4" role="alert">
|
||||
<i class="bi bi-apple flex-shrink-0 mt-1"></i>
|
||||
<div>
|
||||
<strong>iPhone / iPad users must use Safari.</strong> Adding to the home screen from Chrome,
|
||||
Firefox, or other iOS browsers creates a regular bookmark that opens in that browser — not
|
||||
a standalone app. Only Safari on iOS supports the full home screen install.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-3 mb-2"><i class="bi bi-apple me-1"></i>iOS (iPhone / iPad) — Safari only</h3>
|
||||
<ol class="mb-4">
|
||||
<li class="mb-1">Open the app in <strong>Safari</strong>.</li>
|
||||
<li class="mb-1">Tap the <strong>Share</strong> button <i class="bi bi-box-arrow-up"></i> at the bottom of the screen.</li>
|
||||
<li class="mb-1">Scroll down and tap <strong>Add to Home Screen</strong>.</li>
|
||||
<li class="mb-1">Confirm the name and tap <strong>Add</strong>.</li>
|
||||
<li class="mb-1">The app icon appears on your home screen. Tap it to open in full-screen mode.</li>
|
||||
</ol>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-3 mb-2"><i class="bi bi-android2 me-1"></i>Android — Chrome</h3>
|
||||
<ol class="mb-4">
|
||||
<li class="mb-1">Open the app in <strong>Chrome</strong>.</li>
|
||||
<li class="mb-1">Chrome may show an <strong>Install App</strong> banner at the bottom automatically — tap it to install.</li>
|
||||
<li class="mb-1">If no banner appears, tap the <strong>menu (⋮)</strong> in the top-right corner and choose <strong>Add to Home Screen</strong> or <strong>Install App</strong>.</li>
|
||||
<li class="mb-1">Confirm and the icon is added to your home screen.</li>
|
||||
</ol>
|
||||
|
||||
<div class="alert alert-permanent alert-info d-flex gap-2 mb-0" role="alert">
|
||||
<i class="bi bi-lightbulb-fill flex-shrink-0 mt-1"></i>
|
||||
<div>
|
||||
When you open the Dashboard on a mobile browser (before installing), a banner at the top
|
||||
of the page guides you through the install steps for your specific device. Once the app is
|
||||
installed as a home screen app, the banner disappears automatically.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 d-none d-lg-block">
|
||||
@@ -393,6 +443,7 @@
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#roles-and-permissions">Roles and Permissions</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#your-first-steps">Your First Steps</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#after-the-wizard">After the Wizard</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#mobile-install">Using on Mobile</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -73,6 +73,54 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="catalog-lookup" class="mb-5">
|
||||
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
|
||||
<i class="bi bi-search text-primary me-2"></i>Catalog Lookup & Label Scanner
|
||||
</h2>
|
||||
<p>
|
||||
When adding or editing an inventory item, you don't have to type every field manually.
|
||||
Two shortcuts let you auto-fill product details in seconds:
|
||||
</p>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-3 mb-2"><i class="bi bi-upc-scan me-1"></i>Smart Catalog Lookup</h3>
|
||||
<p>
|
||||
Click the <strong>Lookup</strong> button next to the SKU/Part Number field. Type a color name,
|
||||
SKU, or part number and the system searches a built-in catalog of thousands of Prismatic Powders
|
||||
and other manufacturer SKUs. Select a match and the form fills in automatically — item name,
|
||||
manufacturer, color code, finish, coverage rate, SDS/TDS links, and cure specifications.
|
||||
</p>
|
||||
<ul class="mb-3">
|
||||
<li class="mb-1">The catalog only shows products <strong>not already in your inventory</strong>, preventing duplicates. When editing an existing item, its own catalog entry is always shown.</li>
|
||||
<li class="mb-1">If no catalog match is found, the lookup falls back to <strong>AI Lookup</strong> — Claude searches the web for product specs and fills in whatever it can find.</li>
|
||||
<li class="mb-1">If a vendor name is selected in the Vendor field before searching, results are scoped to that vendor first, then broadened automatically if nothing matches.</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="h6 fw-semibold mt-4 mb-2"><i class="bi bi-camera me-1"></i>Label Scanner (Camera)</h3>
|
||||
<p>
|
||||
Click the <strong>camera icon</strong> next to the Lookup button to open the label scanner.
|
||||
Point your phone or webcam at the QR code printed on a powder bag or manufacturer label.
|
||||
The scanner reads the code and attempts to identify the product:
|
||||
</p>
|
||||
<ol class="mb-3">
|
||||
<li class="mb-1">If the QR code matches a product in the platform catalog, the form fills in automatically — same as a manual catalog lookup.</li>
|
||||
<li class="mb-1">If no catalog match is found, the AI analyzes the label image and fills in whatever details it can extract (color name, SKU, manufacturer, finish).</li>
|
||||
<li class="mb-1">
|
||||
If the scanned product is <strong>already in your inventory</strong>, a prompt appears to
|
||||
<strong>Add Stock</strong> to the existing item instead — enter the quantity received and an
|
||||
optional updated unit cost, then save. No duplicate item is created.
|
||||
</li>
|
||||
</ol>
|
||||
<div class="alert alert-permanent alert-info d-flex gap-2 mb-0" role="alert">
|
||||
<i class="bi bi-phone me-1 flex-shrink-0 mt-1"></i>
|
||||
<div>
|
||||
The label scanner works best on a phone. If you're on iOS, open the page in
|
||||
<strong>Safari</strong> for reliable camera access. For persistent camera permission
|
||||
(no prompt each session), <a asp-controller="Help" asp-action="GettingStarted" class="alert-link"
|
||||
fragment="mobile-install">add the app to your home screen</a>.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="stock-levels" class="mb-5">
|
||||
<h2 class="h4 fw-bold border-bottom pb-2 mb-3">
|
||||
<i class="bi bi-boxes text-primary me-2"></i>Stock Levels and Reorder Points
|
||||
@@ -485,6 +533,7 @@
|
||||
<nav class="nav flex-column">
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#overview">Overview</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#adding-items">Adding Inventory Items</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#catalog-lookup">Catalog Lookup & Label Scanner</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#stock-levels">Stock Levels and Reorder Points</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#stock-adjustment">Stock Adjustment</a>
|
||||
<a class="nav-link py-1 px-3 small text-body" href="#transactions">Transaction Types</a>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
</button>
|
||||
@if ((bool)(ViewBag.AiInventoryAssistEnabled ?? false))
|
||||
{
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary ms-1" id="scan-label-btn" title="Scan a powder bag label with your camera">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary ms-1 d-lg-none" id="scan-label-btn" title="Scan a powder bag label with your camera">
|
||||
<i class="bi bi-qr-code-scan me-1"></i>Scan Label
|
||||
</button>
|
||||
}
|
||||
|
||||
@@ -74,12 +74,12 @@
|
||||
<div class="d-flex align-items-center gap-2 border-bottom pb-2 mb-3">
|
||||
<h5 class="mb-0 d-flex align-items-center">
|
||||
<i class="bi bi-palette me-2 text-primary"></i>Product Details
|
||||
<button type="button" class="btn btn-sm btn-primary ms-2" id="smart-lookup-btn">
|
||||
<button type="button" class="btn btn-sm btn-primary ms-2" id="smart-lookup-btn" data-current-id="@Model.Id">
|
||||
<i class="bi bi-search me-1"></i>Lookup
|
||||
</button>
|
||||
@if ((bool)(ViewBag.AiInventoryAssistEnabled ?? false))
|
||||
{
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary ms-1" id="scan-label-btn" title="Scan a powder bag label with your camera">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary ms-1 d-lg-none" id="scan-label-btn" title="Scan a powder bag label with your camera">
|
||||
<i class="bi bi-qr-code-scan me-1"></i>Scan Label
|
||||
</button>
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
const categorySelect = document.getElementById('field-category');
|
||||
const coatingSection = document.getElementById('coating-specs-section');
|
||||
const smartLookupBtn = document.getElementById('smart-lookup-btn');
|
||||
const scanLabelBtn = document.getElementById('scan-label-btn');
|
||||
|
||||
let coatingMap = {};
|
||||
if (categorySelect && categorySelect.dataset.coatingMap) {
|
||||
@@ -54,6 +55,7 @@
|
||||
const show = isCoatingCategory(catId);
|
||||
if (coatingSection) coatingSection.style.display = show ? '' : 'none';
|
||||
if (smartLookupBtn) smartLookupBtn.style.display = show ? '' : 'none';
|
||||
if (scanLabelBtn) scanLabelBtn.style.display = show ? '' : 'none';
|
||||
const samplePanelSection = document.getElementById('sample-panel-section');
|
||||
if (samplePanelSection) samplePanelSection.style.display = show ? '' : 'none';
|
||||
coatingOnlyFields.forEach(id => {
|
||||
|
||||
@@ -101,6 +101,13 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - Powder Coating Logix</title>
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="theme-color" content="#1A1A1C" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<meta name="apple-mobile-web-app-title" content="PCLogix" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png" />
|
||||
|
||||
<!-- First-paint theme: server already stamped data-surface from cookie.
|
||||
This script only corrects first-visit (no cookie) using OS preference. -->
|
||||
@@ -2192,5 +2199,10 @@
|
||||
}, true);
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/sw.js').catch(() => {});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user