Refactor store UI into dynamic multi-view shell

- Replace static HTML markup with app root and runtime asset loading
- Rebuild `script.js` as state-driven category/weapon/catalog views
- Add cart overlay scaffold, breadcrumbs, and window-style navigation UI
This commit is contained in:
Jacob Schmidt 2026-03-10 00:13:56 -05:00
parent 9cd7278746
commit 4ee6537fbc
3 changed files with 1543 additions and 977 deletions

View File

@ -1,149 +1,61 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FORGE Supply Exchange</title>
<script>
const addonRoot = "forge\\forge_client\\addons\\store\\ui\\_site\\";
const styleFiles = ["style.css"];
const scriptFiles = ["script.js"];
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Store</title>
<!-- <link rel="stylesheet" href="style.css" /> -->
<!--
Dynamic Resource Loading
The following script loads CSS and JavaScript files dynamically using the A3API
This approach is used instead of static HTML imports to work with Arma 3's file system
-->
<script>
Promise.all([
A3API.RequestFile(
"forge\\forge_client\\addons\\store\\ui\\_site\\style.css",
),
A3API.RequestFile(
"forge\\forge_client\\addons\\store\\ui\\_site\\script.js",
),
]).then(([css, js]) => {
const style = document.createElement("style");
style.textContent = css;
document.head.appendChild(style);
function requestText(path) {
if (
typeof A3API !== "undefined" &&
typeof A3API.RequestFile === "function"
) {
return A3API.RequestFile(addonRoot + path);
}
const script = document.createElement("script");
script.text = js;
document.head.appendChild(script);
});
</script>
</head>
return fetch(path).then((response) => {
if (!response.ok) {
throw new Error("Failed to load " + path);
}
<body>
<div class="store-container">
<!-- Header Section -->
<div class="store-header">
<div class="store-logo">
<div class="logo-icon">🛒</div>
</div>
<div class="store-info">
<h1 class="store-title">Supply Store</h1>
<p class="store-subtitle">Equipment & Resources</p>
</div>
<div class="balance-display">
<span class="balance-label">Available Funds</span>
<span class="balance-amount">$45,750</span>
</div>
<div class="header-actions">
<button class="action-btn cart-btn" id="cartToggle">
<span class="cart-icon">Cart</span>
<span class="cart-count">0</span>
</button>
<button class="action-btn close-btn">Close</button>
</div>
</div>
return response.text();
});
}
<!-- Main Content -->
<div class="store-content">
<!-- Left Panel - Categories -->
<div class="store-panel categories-panel">
<div class="panel-header">
<h2 class="panel-title">Categories</h2>
</div>
<div class="panel-content">
<div class="category-list">
<button class="category-item active" data-category="all">
<span class="category-icon"></span>
<span class="category-name">All Items</span>
<span class="category-count">24</span>
</button>
<button class="category-item" data-category="weapons">
<span class="category-icon"></span>
<span class="category-name">Weapons</span>
<span class="category-count">8</span>
</button>
<button class="category-item" data-category="equipment">
<span class="category-icon"></span>
<span class="category-name">Equipment</span>
<span class="category-count">6</span>
</button>
<button class="category-item" data-category="medical">
<span class="category-icon"></span>
<span class="category-name">Medical</span>
<span class="category-count">5</span>
</button>
<button class="category-item" data-category="supplies">
<span class="category-icon"></span>
<span class="category-name">Supplies</span>
<span class="category-count">5</span>
</button>
</div>
</div>
</div>
function appendStyle(css) {
const style = document.createElement("style");
style.textContent = css;
document.head.appendChild(style);
}
<!-- Center Panel - Items Grid -->
<div class="store-panel items-panel">
<div class="panel-header">
<h2 class="panel-title">Available Items</h2>
<div class="search-box">
<input type="text" class="search-input" placeholder="Search items..." id="searchInput">
</div>
</div>
<div class="panel-content">
<div class="items-grid" id="itemsGrid">
<!-- Items will be dynamically generated -->
</div>
</div>
</div>
function appendScript(js) {
const script = document.createElement("script");
script.text = js;
document.head.appendChild(script);
}
<!-- Right Panel - Cart (Initially Hidden) -->
<div class="store-panel cart-panel" id="cartPanel" style="display: none;">
<div class="panel-header">
<h2 class="panel-title">Shopping Cart</h2>
<button class="clear-cart-btn" id="clearCart">Clear</button>
</div>
<div class="panel-content">
<div class="cart-items" id="cartItems">
<div class="empty-cart">
<span class="empty-icon"></span>
<span class="empty-text">Your cart is empty</span>
</div>
</div>
<div class="cart-summary">
<div class="summary-row">
<span class="summary-label">Subtotal</span>
<span class="summary-value" id="cartSubtotal">$0</span>
</div>
<div class="summary-row">
<span class="summary-label">Tax (5%)</span>
<span class="summary-value" id="cartTax">$0</span>
</div>
<div class="summary-row summary-total">
<span class="summary-label">Total</span>
<span class="summary-value" id="cartTotal">$0</span>
</div>
<button class="action-btn action-btn-primary checkout-btn" id="checkoutBtn">
Complete Purchase
</button>
</div>
</div>
</div>
</div>
</div>
<!-- <script src="script.js"></script> -->
</body>
Promise.all(styleFiles.map(requestText))
.then((styles) => {
styles.forEach(appendStyle);
return Promise.all(scriptFiles.map(requestText));
})
.then((scripts) => {
scripts.forEach(appendScript);
})
.catch((error) => {
console.error(
"[Store UI] Failed to load site assets.",
error,
);
});
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff