fix: restyle product edit modal with proper form layout and sections

- Product form: grouped fields with pf-group/pf-row/pf-section-title
- Modal: sticky header, scrollable body, proper padding
- Form sections: Public Photo, Hidden Content (after purchase)
- Photo fields: URL input + file upload side by side per section
- Inputs/selects/textareas: consistent sizing, focus ring
- Actions: Save + Cancel buttons with border separator
This commit is contained in:
NW
2026-06-23 21:04:00 +01:00
parent 8e52618a50
commit e00071b18a
2 changed files with 147 additions and 24 deletions

View File

@@ -351,13 +351,93 @@ pre { font-size: 0.8rem; white-space: pre-wrap; word-break: break-all; max-width
.modal-content {
background: var(--card);
border-radius: var(--radius);
padding: 1.5rem;
max-width: 560px;
width: 90%;
max-height: 90vh;
padding: 0;
max-width: 600px;
width: 95%;
max-height: 88vh;
overflow-y: auto;
}
.modal-content h2 {
position: sticky;
top: 0;
background: var(--card);
padding: 1rem 1.5rem;
margin: 0;
border-bottom: 1px solid var(--border);
z-index: 1;
}
.product-form {
padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.pf-group {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.pf-group label {
font-weight: 600;
font-size: 0.85rem;
color: var(--text);
}
.pf-group input,
.pf-group select,
.pf-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid var(--border);
border-radius: var(--radius);
font-size: 0.9rem;
font-family: inherit;
}
.pf-group textarea {
min-height: 60px;
resize: vertical;
}
.pf-group input:focus,
.pf-group select:focus,
.pf-group textarea:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}
.pf-file {
font-size: 0.85rem;
}
.pf-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.75rem;
}
.pf-section-title {
font-weight: 700;
font-size: 0.9rem;
color: var(--primary);
margin-top: 0.5rem;
padding-bottom: 0.25rem;
border-bottom: 1px solid var(--border);
}
.pf-actions {
display: flex;
gap: 0.5rem;
margin-top: 0.5rem;
padding-top: 0.75rem;
border-top: 1px solid var(--border);
}
.form-row {
display: flex;
gap: 0.5rem;

View File

@@ -2,27 +2,70 @@ export function renderProductEditForm(action, catOptions, subcatJson) {
const isEdit = action.includes('/edit');
const title = isEdit ? 'Edit Product' : 'Add Product';
return `<h2>${title}</h2>
<form method="POST" action="${action}" enctype="multipart/form-data" class="form">
<label>Name <input name="name" required></label>
<div class="form-row">
<label>Price <input name="price" type="number" step="0.01" required></label>
<label>Stock <input name="quantity_in_stock" type="number" value="0"></label>
<form method="POST" action="${action}" enctype="multipart/form-data" class="product-form">
<div class="pf-group">
<label>Name</label>
<input name="name" required placeholder="Product name">
</div>
<label>Description <textarea name="description"></textarea></label>
<label>Category <select name="category_id" required onchange="updateSubcats(this.value)">
<option value="">-- Select --</option>${catOptions}
</select></label>
<label>Subcategory <select name="subcategory_id"><option value="">-- Subcategory --</option></select></label>
<label>Photo URL <input name="photo_url" placeholder="https://... or upload below"></label>
<label>Photo File <input type="file" name="photo_file" accept="image/*"></label>
<label>Hidden Photo URL <input name="hidden_photo_url" placeholder="https://... or upload below"></label>
<label>Hidden Photo File <input type="file" name="hidden_photo_file" accept="image/*"></label>
<label>Hidden Coordinates <input name="hidden_coordinates" placeholder="lat,lng or address"></label>
<label>Hidden Description <textarea name="hidden_description"></textarea></label>
<label>Private Data <textarea name="private_data"></textarea></label>
<div style="display:flex;gap:0.5rem">
<button type="submit" class="btn">Save</button>
<div class="pf-row">
<div class="pf-group">
<label>Price ($)</label>
<input name="price" type="number" step="0.01" min="0" required placeholder="0.00">
</div>
<div class="pf-group">
<label>Stock</label>
<input name="quantity_in_stock" type="number" min="0" value="0" placeholder="0">
</div>
</div>
<div class="pf-group">
<label>Category</label>
<select name="category_id" required onchange="updateSubcats(this.value)">
<option value="">-- Select --</option>${catOptions}
</select>
</div>
<div class="pf-group">
<label>Subcategory</label>
<select name="subcategory_id"><option value="">-- Subcategory --</option></select>
</div>
<div class="pf-group">
<label>Description</label>
<textarea name="description" rows="3" placeholder="Public description"></textarea>
</div>
<div class="pf-section-title">Public Photo</div>
<div class="pf-group">
<label>Photo URL</label>
<input name="photo_url" placeholder="https://...">
</div>
<div class="pf-group">
<label>Or Upload Photo</label>
<input type="file" name="photo_file" accept="image/*" class="pf-file">
</div>
<div class="pf-section-title">Hidden Content (shown after purchase)</div>
<div class="pf-group">
<label>Hidden Photo URL</label>
<input name="hidden_photo_url" placeholder="https://...">
</div>
<div class="pf-group">
<label>Or Upload Hidden Photo</label>
<input type="file" name="hidden_photo_file" accept="image/*" class="pf-file">
</div>
<div class="pf-row">
<div class="pf-group">
<label>Hidden Coordinates</label>
<input name="hidden_coordinates" placeholder="lat,lng">
</div>
</div>
<div class="pf-group">
<label>Hidden Description</label>
<textarea name="hidden_description" rows="2" placeholder="Shown after purchase"></textarea>
</div>
<div class="pf-group">
<label>Private Data</label>
<textarea name="private_data" rows="2" placeholder="Internal notes, not shown to users"></textarea>
</div>
<div class="pf-actions">
<button type="submit" class="btn btn-success">Save</button>
<button type="button" class="btn btn-secondary" onclick="document.getElementById('product-modal').style.display='none'">Cancel</button>
</div>
</form>`;
}
}