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:
@@ -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;
|
||||
|
||||
@@ -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>`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user