253 lines
12 KiB
HTML
253 lines
12 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="en">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|||
|
|
<title>Reloads – ShooterHub</title>
|
|||
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
|||
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
|||
|
|
<link rel="stylesheet" href="/css/app.css">
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div id="navbar"></div>
|
|||
|
|
|
|||
|
|
<div class="container-fluid py-4">
|
|||
|
|
<h2 class="fw-bold mb-4 container"><i class="bi bi-gear-wide-connected me-2"></i><span data-i18n="reload.title">Reload Development</span></h2>
|
|||
|
|
|
|||
|
|
<div class="row g-0" style="min-height:70vh;">
|
|||
|
|
|
|||
|
|
<!-- ── Left: Recipes sidebar ─────────────────────────────────────────── -->
|
|||
|
|
<div class="col-md-3 border-end px-3">
|
|||
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|||
|
|
<h6 class="fw-semibold mb-0">Recipes</h6>
|
|||
|
|
<button class="btn btn-primary btn-sm" id="newRecipeBtn">
|
|||
|
|
<i class="bi bi-plus-lg"></i>
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
<div id="recipesSpinner" class="text-center py-3"><div class="spinner-border spinner-border-sm text-primary"></div></div>
|
|||
|
|
<div id="recipesEmpty" class="text-muted small d-none">No recipes yet.</div>
|
|||
|
|
<div id="recipesList"></div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- ── Right: Selected recipe + batches ──────────────────────────────── -->
|
|||
|
|
<div class="col-md-9 px-4" id="recipePanel">
|
|||
|
|
<div class="text-center text-muted py-5" id="noRecipeMsg">
|
|||
|
|
<i class="bi bi-arrow-left fs-3 d-block mb-2"></i>
|
|||
|
|
Select a recipe to view its batches
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- Recipe header (hidden until a recipe is selected) -->
|
|||
|
|
<div id="recipeDetail" class="d-none">
|
|||
|
|
<div class="d-flex justify-content-between align-items-start mb-3">
|
|||
|
|
<div>
|
|||
|
|
<h4 class="fw-bold mb-0" id="detailName"></h4>
|
|||
|
|
<span class="text-muted small" id="detailCaliber"></span>
|
|||
|
|
</div>
|
|||
|
|
<div class="d-flex gap-2">
|
|||
|
|
<button class="btn btn-sm btn-outline-secondary" id="togglePublicBtn" title="Make public/private">
|
|||
|
|
<i class="bi bi-lock me-1" id="togglePublicIcon"></i><span id="togglePublicLabel">Private</span>
|
|||
|
|
</button>
|
|||
|
|
<button class="btn btn-sm btn-outline-secondary" id="editRecipeBtn">
|
|||
|
|
<i class="bi bi-pencil me-1"></i>Edit
|
|||
|
|
</button>
|
|||
|
|
<button class="btn btn-sm btn-outline-danger" id="deleteRecipeBtn">
|
|||
|
|
<i class="bi bi-trash me-1"></i>Delete
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- Components summary -->
|
|||
|
|
<div class="row g-2 mb-4">
|
|||
|
|
<div class="col-sm-3">
|
|||
|
|
<div class="card bg-light border-0 p-3 text-center h-100">
|
|||
|
|
<div class="text-muted small mb-1"><i class="bi bi-dot"></i>Primer</div>
|
|||
|
|
<div class="fw-semibold small" id="detailPrimer"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-sm-3">
|
|||
|
|
<div class="card bg-light border-0 p-3 text-center h-100">
|
|||
|
|
<div class="text-muted small mb-1"><i class="bi bi-dot"></i>Brass</div>
|
|||
|
|
<div class="fw-semibold small" id="detailBrass"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-sm-3">
|
|||
|
|
<div class="card bg-light border-0 p-3 text-center h-100">
|
|||
|
|
<div class="text-muted small mb-1"><i class="bi bi-dot"></i>Bullet</div>
|
|||
|
|
<div class="fw-semibold small" id="detailBullet"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-sm-3">
|
|||
|
|
<div class="card bg-light border-0 p-3 text-center h-100">
|
|||
|
|
<div class="text-muted small mb-1"><i class="bi bi-chat-left-text"></i>Notes</div>
|
|||
|
|
<div class="fw-semibold small" id="detailNotes"></div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- Batches -->
|
|||
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|||
|
|
<h6 class="fw-semibold mb-0">Charge batches</h6>
|
|||
|
|
<button class="btn btn-primary btn-sm" id="newBatchBtn">
|
|||
|
|
<i class="bi bi-plus-lg me-1"></i>New batch
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
<div id="batchesSpinner" class="text-center py-3 d-none"><div class="spinner-border spinner-border-sm text-primary"></div></div>
|
|||
|
|
<div id="batchesEmpty" class="alert alert-secondary d-none">No batches yet. Create one to start developing this recipe.</div>
|
|||
|
|
<div class="table-responsive" id="batchesTableWrap">
|
|||
|
|
<table class="table table-hover align-middle">
|
|||
|
|
<thead class="table-light">
|
|||
|
|
<tr>
|
|||
|
|
<th>Powder</th>
|
|||
|
|
<th>Charge (gr)</th>
|
|||
|
|
<th>Qty</th>
|
|||
|
|
<th>OAL (mm)</th>
|
|||
|
|
<th>Crimp</th>
|
|||
|
|
<th>Loaded</th>
|
|||
|
|
<th></th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody id="batchesBody"></tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- ── Modal: Create / Edit Recipe ───────────────────────────────────────── -->
|
|||
|
|
<div class="modal fade" id="recipeModal" tabindex="-1">
|
|||
|
|
<div class="modal-dialog modal-lg">
|
|||
|
|
<div class="modal-content">
|
|||
|
|
<div class="modal-header">
|
|||
|
|
<h5 class="modal-title" id="recipeModalTitle">New recipe</h5>
|
|||
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|||
|
|
</div>
|
|||
|
|
<div class="modal-body">
|
|||
|
|
<input type="hidden" id="recipeId">
|
|||
|
|
<div class="row g-3">
|
|||
|
|
<div class="col-md-8">
|
|||
|
|
<label class="form-label">Recipe name <span class="text-danger">*</span></label>
|
|||
|
|
<input type="text" class="form-control" id="recipeName" placeholder="e.g. .308 match – Sierra 168">
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-4">
|
|||
|
|
<label class="form-label">Caliber <span class="text-danger">*</span></label>
|
|||
|
|
<select class="form-select" id="recipeCaliber"><option value="">Loading…</option></select>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-4">
|
|||
|
|
<label class="form-label d-flex justify-content-between">
|
|||
|
|
Primer <span class="text-danger">*</span>
|
|||
|
|
<a href="#" class="small text-primary suggest-comp-link" data-comp="primers">+ Suggest</a>
|
|||
|
|
</label>
|
|||
|
|
<select class="form-select" id="recipePrimer"><option value="">Loading…</option></select>
|
|||
|
|
<div class="suggest-comp-form mt-1 d-none" data-comp="primers"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-4">
|
|||
|
|
<label class="form-label d-flex justify-content-between">
|
|||
|
|
Brass <span class="text-danger">*</span>
|
|||
|
|
<a href="#" class="small text-primary suggest-comp-link" data-comp="brass">+ Suggest</a>
|
|||
|
|
</label>
|
|||
|
|
<select class="form-select" id="recipeBrass"><option value="">Loading…</option></select>
|
|||
|
|
<div class="suggest-comp-form mt-1 d-none" data-comp="brass"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-4">
|
|||
|
|
<label class="form-label d-flex justify-content-between">
|
|||
|
|
Bullet <span class="text-danger">*</span>
|
|||
|
|
<a href="#" class="small text-primary suggest-comp-link" data-comp="bullets">+ Suggest</a>
|
|||
|
|
</label>
|
|||
|
|
<select class="form-select" id="recipeBullet"><option value="">Loading…</option></select>
|
|||
|
|
<div class="suggest-comp-form mt-1 d-none" data-comp="bullets"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-12">
|
|||
|
|
<label class="form-label">Notes</label>
|
|||
|
|
<textarea class="form-control" id="recipeNotes" rows="2"></textarea>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div id="recipeModalAlert" class="alert alert-danger mt-3 d-none"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="modal-footer">
|
|||
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|||
|
|
<button type="button" class="btn btn-primary" id="saveRecipeBtn">Save</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- ── Modal: Create / Edit Batch ────────────────────────────────────────── -->
|
|||
|
|
<div class="modal fade" id="batchModal" tabindex="-1">
|
|||
|
|
<div class="modal-dialog">
|
|||
|
|
<div class="modal-content">
|
|||
|
|
<div class="modal-header">
|
|||
|
|
<h5 class="modal-title" id="batchModalTitle">New batch</h5>
|
|||
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|||
|
|
</div>
|
|||
|
|
<div class="modal-body">
|
|||
|
|
<input type="hidden" id="batchId">
|
|||
|
|
<div class="row g-3">
|
|||
|
|
<div class="col-md-6">
|
|||
|
|
<label class="form-label d-flex justify-content-between">
|
|||
|
|
Powder <span class="text-danger">*</span>
|
|||
|
|
<a href="#" class="small text-primary suggest-comp-link" data-comp="powders">+ Suggest</a>
|
|||
|
|
</label>
|
|||
|
|
<select class="form-select" id="batchPowder"><option value="">Loading…</option></select>
|
|||
|
|
<div class="suggest-comp-form mt-1 d-none" data-comp="powders"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-6">
|
|||
|
|
<label class="form-label">Charge (gr) <span class="text-danger">*</span></label>
|
|||
|
|
<input type="number" class="form-control" id="batchCharge" step="0.01" placeholder="42.50">
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-4">
|
|||
|
|
<label class="form-label">Quantity</label>
|
|||
|
|
<input type="number" class="form-control" id="batchQty" min="0">
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-4">
|
|||
|
|
<label class="form-label">OAL (mm)</label>
|
|||
|
|
<input type="number" class="form-control" id="batchOal" step="0.01">
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-4">
|
|||
|
|
<label class="form-label">COAL (mm)</label>
|
|||
|
|
<input type="number" class="form-control" id="batchCoal" step="0.01">
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-6">
|
|||
|
|
<label class="form-label">Crimp</label>
|
|||
|
|
<select class="form-select" id="batchCrimp">
|
|||
|
|
<option value="NONE">No crimp</option>
|
|||
|
|
<option value="TAPER">Taper crimp</option>
|
|||
|
|
<option value="ROLL">Roll crimp</option>
|
|||
|
|
</select>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-6">
|
|||
|
|
<label class="form-label">Loaded date</label>
|
|||
|
|
<input type="date" class="form-control" id="batchLoaded">
|
|||
|
|
</div>
|
|||
|
|
<div class="col-12">
|
|||
|
|
<label class="form-label">Case prep notes</label>
|
|||
|
|
<input type="text" class="form-control" id="batchCasePrep">
|
|||
|
|
</div>
|
|||
|
|
<div class="col-12">
|
|||
|
|
<label class="form-label">Notes</label>
|
|||
|
|
<textarea class="form-control" id="batchNotes" rows="2"></textarea>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div id="batchModalAlert" class="alert alert-danger mt-3 d-none"></div>
|
|||
|
|
</div>
|
|||
|
|
<div class="modal-footer">
|
|||
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|||
|
|
<button type="button" class="btn btn-primary" id="saveBatchBtn">Save</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div id="toastContainer"></div>
|
|||
|
|
|
|||
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|||
|
|
<script src="/js/api.js"></script>
|
|||
|
|
<script src="/js/utils.js"></script>
|
|||
|
|
<script src="/js/i18n.js"></script>
|
|||
|
|
<script src="/js/calibers.js"></script>
|
|||
|
|
<script src="/js/nav.js"></script>
|
|||
|
|
<script src="/js/reloads.js"></script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|