Add new fields to items: id_code, image, location; implement QR code generation and printing; update translations and UI

This commit is contained in:
2025-11-11 17:59:23 +01:00
parent 921a74bbe2
commit a15c976106
61 changed files with 5514 additions and 83 deletions

View File

@@ -32,16 +32,23 @@
<ul id="itemsList" class="list-group mb-4">
{% if items %}
{% for item in items %}
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
<h5>{{ item.name }}</h5>
<p class="text-muted">{{ trans('Category') }}: {{ item.category_name ?: trans('Uncategorized') }}</p>
<p>{{ item.description }}</p>
</div>
<div>
<button class="btn btn-sm btn-warning me-2 edit-btn" data-id="{{ item.id }}">Edit</button>
<button class="btn btn-sm btn-danger delete-btn" data-id="{{ item.id }}">Delete</button>
</div>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
<h5>{{ item.name }} <small class="text-muted">({{ item.id_code }})</small></h5>
<p class="text-muted">{{ trans('Category') }}: {{ item.category_path ?: trans('Uncategorized') }}</p>
<p>{{ item.description }}</p>
{% if item.image %}
<img src="{{ item.image }}" alt="Image" style="max-width: 100px; max-height: 100px;">
{% endif %}
{% if item.location %}
<p><strong>{{ trans('Location') }}:</strong> {{ item.location }}</p>
{% endif %}
</div>
<div>
<button class="btn btn-sm btn-warning me-2 edit-btn" data-id="{{ item.id }}">Edit</button>
<button class="btn btn-sm btn-info me-2" onclick="window.open('/print/{{ item.id }}', '_blank')">Print QR</button>
<button class="btn btn-sm btn-danger delete-btn" data-id="{{ item.id }}">Delete</button>
</div>
</li>
{% endfor %}
{% else %}
@@ -68,16 +75,24 @@
<label for="edit_item_description" class="form-label">{{ trans('Description') }}</label>
<textarea class="form-control" id="edit_item_description" name="item_description" rows="3"></textarea>
</div>
<div class="mb-3">
<label for="edit_item_category_id" class="form-label">{{ trans('Category') }}</label>
<select class="form-select" id="edit_item_category_id" name="category_id">
<option value="">{{ trans('-- Select Category --') }}</option>
{% for category in categories %}
<option value="{{ category.id }}">{{ category.path }}</option>
{% endfor %}
</select>
</div>
</form>
<div class="mb-3">
<label for="edit_item_category_id" class="form-label">{{ trans('Category') }}</label>
<select class="form-select" id="edit_item_category_id" name="category_id">
<option value="">{{ trans('-- Select Category --') }}</option>
{% for category in categories %}
<option value="{{ category.id }}">{{ category.path }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="edit_image" class="form-label">{{ trans('Image') }}</label>
<input type="file" class="form-control" id="edit_image" name="image" accept="image/*">
</div>
<div class="mb-3">
<label for="edit_location" class="form-label">{{ trans('Location') }}</label>
<input type="text" class="form-control" id="edit_location" name="location">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ trans('Cancel') }}</button>

View File

@@ -29,7 +29,14 @@
</div>
<!-- Bootstrap JS Bundle -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2AEu8T+c+7f+z/j43" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<!-- Translated messages for JS -->
<script>
window.translations = {
deletePartConfirm: "{{ delete_part_confirm|escape('js') }}",
deleteCategoryConfirm: "{{ delete_category_confirm|escape('js') }}"
};
</script>
<!-- Custom JS -->
<script src="js/app.js"></script>
</body>

View File

@@ -22,6 +22,14 @@
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="image" class="form-label">{{ trans('Image') }}</label>
<input type="file" class="form-control" id="image" name="image" accept="image/*">
</div>
<div class="mb-3">
<label for="location" class="form-label">{{ trans('Location') }}</label>
<input type="text" class="form-control" id="location" name="location">
</div>
<button type="submit" class="btn btn-primary">{{ trans('Add Part') }}</button>
</form>
</div>

32
templates/print_qr.twig Normal file
View File

@@ -0,0 +1,32 @@
{% autoescape %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QR Code for {{ item.name }}</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; margin: 20px; }
.qr-container { border: 1px solid #000; padding: 20px; display: inline-block; }
.qr-code { width: 200px; height: 200px; }
.details { margin-top: 20px; }
@media print { body { margin: 0; } .qr-container { page-break-inside: avoid; } }
</style>
</head>
<body>
<div class="qr-container">
<h2>{{ item.name }}</h2>
<p>ID Code: {{ item.id_code }}</p>
<img src="/uploads/qr/{{ item.id_code }}.png" alt="QR Code" class="qr-code">
<div class="details">
<p><strong>Description:</strong> {{ item.description }}</p>
<p><strong>Category:</strong> {{ item.category_path ?: 'Uncategorized' }}</p>
{% if item.location %}
<p><strong>Location:</strong> {{ item.location }}</p>
{% endif %}
</div>
</div>
<script>window.print();</script>
</body>
</html>
{% endautoescape %}