2025-05-08 20:49:15 -04:00
|
|
|
{% extends "layout.html" %}
|
|
|
|
|
|
|
|
|
|
{% block title %}Add New Product - KCAP Demo Server{% endblock %}
|
|
|
|
|
|
|
|
|
|
{% block content %}
|
|
|
|
|
<div class="row mt-4">
|
|
|
|
|
<div class="col-md-8 offset-md-2">
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">
|
|
|
|
|
<h2>Add New Product</h2>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="card-body">
|
2025-10-20 21:36:01 -04:00
|
|
|
{% if not custom_fields %}
|
|
|
|
|
<div class="alert alert-warning" role="alert">
|
|
|
|
|
<h4 class="alert-heading"><i class="bi bi-exclamation-triangle-fill me-2"></i>No Fields Configured</h4>
|
|
|
|
|
<p>Unable to add products. You must configure custom AR fields before adding products.</p>
|
|
|
|
|
<hr>
|
|
|
|
|
<p class="mb-0">
|
|
|
|
|
<a href="/{{ tenant_id }}/ar_fields" class="btn btn-primary">
|
|
|
|
|
<i class="bi bi-gear-fill me-1"></i>Configure AR Fields
|
|
|
|
|
</a>
|
|
|
|
|
<a href="/{{ tenant_id }}/" class="btn btn-secondary ms-2">
|
|
|
|
|
<i class="bi bi-arrow-left me-1"></i>Back to Products
|
|
|
|
|
</a>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
{% else %}
|
2025-10-20 17:11:26 -04:00
|
|
|
<form action="/{{ tenant_id }}/add" method="POST" enctype="multipart/form-data">
|
2025-05-08 20:49:15 -04:00
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="product_id" class="form-label">Product ID *</label>
|
|
|
|
|
<div class="input-group">
|
|
|
|
|
<input type="text" class="form-control" id="product_id" name="product_id" required>
|
|
|
|
|
<button class="btn btn-outline-secondary" type="button" id="generate-id-btn" title="Generate Random ID">
|
|
|
|
|
<i class="bi bi-magic"></i> Generate
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="form-text">Must be unique. This will be used as the barcode for AR content.</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-19 15:46:22 -04:00
|
|
|
{% for field in custom_fields %}
|
|
|
|
|
{% if field.fieldName != '_id' %}
|
|
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="field_{{ field.fieldName }}" class="form-label">{{ field.label }}</label>
|
|
|
|
|
{% if field.fieldType == 'IMAGE_URI' %}
|
|
|
|
|
<input type="file" class="form-control" id="image_{{ field.fieldName }}" name="image_{{ field.fieldName }}" accept="image/*" onchange="previewImage(this, 'preview_{{ field.fieldName }}')">
|
|
|
|
|
<div class="form-text">Supported formats: .png, .jpg, .jpeg, .gif</div>
|
|
|
|
|
<div class="mt-2">
|
|
|
|
|
<img id="preview_{{ field.fieldName }}" class="image-preview" style="display: none; max-width: 200px;">
|
|
|
|
|
</div>
|
|
|
|
|
{% elif field.fieldType == 'TEXT' %}
|
|
|
|
|
{% if field.fieldName == '_price' %}
|
|
|
|
|
<div class="input-group">
|
|
|
|
|
<span class="input-group-text">$</span>
|
|
|
|
|
<input type="text" class="form-control" id="field_{{ field.fieldName }}" name="field_{{ field.fieldName }}" pattern="[0-9]+(\.[0-9]{1,2})?" placeholder="49.99">
|
|
|
|
|
</div>
|
|
|
|
|
{% else %}
|
|
|
|
|
<input type="text" class="form-control" id="field_{{ field.fieldName }}" name="field_{{ field.fieldName }}">
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% else %}
|
|
|
|
|
<input type="text" class="form-control" id="field_{{ field.fieldName }}" name="field_{{ field.fieldName }}">
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endfor %}
|
|
|
|
|
|
|
|
|
|
<!-- Fallback fields for backward compatibility -->
|
|
|
|
|
{% if not custom_fields|selectattr('fieldName', 'equalto', '_name')|list %}
|
2025-05-08 20:49:15 -04:00
|
|
|
<div class="mb-3">
|
2025-06-19 15:46:22 -04:00
|
|
|
<label for="name" class="form-label">Product Name</label>
|
|
|
|
|
<input type="text" class="form-control" id="name" name="name">
|
2025-05-08 20:49:15 -04:00
|
|
|
</div>
|
2025-06-19 15:46:22 -04:00
|
|
|
{% endif %}
|
2025-05-08 20:49:15 -04:00
|
|
|
|
2025-06-19 15:46:22 -04:00
|
|
|
{% if not custom_fields|selectattr('fieldName', 'equalto', '_price')|list %}
|
2025-05-08 20:49:15 -04:00
|
|
|
<div class="mb-3">
|
2025-06-19 15:46:22 -04:00
|
|
|
<label for="price" class="form-label">Price</label>
|
2025-05-08 20:49:15 -04:00
|
|
|
<div class="input-group">
|
|
|
|
|
<span class="input-group-text">$</span>
|
2025-06-19 15:46:22 -04:00
|
|
|
<input type="text" class="form-control" id="price" name="price" pattern="[0-9]+(\.[0-9]{1,2})?" placeholder="49.99">
|
2025-05-08 20:49:15 -04:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-19 15:46:22 -04:00
|
|
|
{% endif %}
|
2025-05-08 20:49:15 -04:00
|
|
|
|
|
|
|
|
<div class="d-flex justify-content-between">
|
2025-10-20 17:11:26 -04:00
|
|
|
<a href="/{{ tenant_id }}/" class="btn btn-secondary">Cancel</a>
|
2025-05-08 20:49:15 -04:00
|
|
|
<button type="submit" class="btn btn-primary">Add Product</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
2025-10-20 21:36:01 -04:00
|
|
|
{% endif %}
|
2025-05-08 20:49:15 -04:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
|
|
{% block extra_js %}
|
|
|
|
|
<script>
|
2025-06-19 15:46:22 -04:00
|
|
|
function previewImage(input, previewId) {
|
|
|
|
|
var preview = document.getElementById(previewId || 'image-preview');
|
2025-05-08 20:49:15 -04:00
|
|
|
|
|
|
|
|
if (input.files && input.files[0]) {
|
|
|
|
|
var reader = new FileReader();
|
|
|
|
|
|
|
|
|
|
reader.onload = function(e) {
|
|
|
|
|
preview.src = e.target.result;
|
|
|
|
|
preview.style.display = 'block';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reader.readAsDataURL(input.files[0]);
|
|
|
|
|
} else {
|
|
|
|
|
preview.style.display = 'none';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate a random product ID
|
|
|
|
|
document.getElementById('generate-id-btn').addEventListener('click', function() {
|
|
|
|
|
// Generate a random alphanumeric ID
|
|
|
|
|
// Format: 3 letters followed by 4 numbers (e.g., ABC1234)
|
|
|
|
|
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
|
|
|
const numbers = '0123456789';
|
|
|
|
|
|
|
|
|
|
let id = '';
|
|
|
|
|
|
|
|
|
|
// Add 3 random uppercase letters
|
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
|
|
|
id += letters.charAt(Math.floor(Math.random() * letters.length));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add 4 random numbers
|
|
|
|
|
for (let i = 0; i < 4; i++) {
|
|
|
|
|
id += numbers.charAt(Math.floor(Math.random() * numbers.length));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the generated ID in the input field
|
|
|
|
|
document.getElementById('product_id').value = id;
|
|
|
|
|
});
|
|
|
|
|
</script>
|
2025-06-19 15:46:22 -04:00
|
|
|
{% endblock %}
|