Autosave: 20260224-082528
This commit is contained in:
parent
110b26742e
commit
291449ae16
@ -12,6 +12,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
$action = $_POST['action'];
|
$action = $_POST['action'];
|
||||||
$id = isset($_POST['id']) ? (int)$_POST['id'] : null;
|
$id = isset($_POST['id']) ? (int)$_POST['id'] : null;
|
||||||
$name = $_POST['name'];
|
$name = $_POST['name'];
|
||||||
|
$name_ar = $_POST['name_ar'] ?? '';
|
||||||
$description = $_POST['description'];
|
$description = $_POST['description'];
|
||||||
|
|
||||||
$image_url = null;
|
$image_url = null;
|
||||||
@ -41,16 +42,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
if (!has_permission('categories_edit') && !has_permission('categories_add')) {
|
if (!has_permission('categories_edit') && !has_permission('categories_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to edit categories.</div>';
|
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to edit categories.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("UPDATE categories SET name = ?, description = ?, image_url = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE categories SET name = ?, name_ar = ?, description = ?, image_url = ? WHERE id = ?");
|
||||||
$stmt->execute([$name, $description, $image_url, $id]);
|
$stmt->execute([$name, $name_ar, $description, $image_url, $id]);
|
||||||
$message = '<div class="alert alert-success">Category updated successfully!</div>';
|
$message = '<div class="alert alert-success">Category updated successfully!</div>';
|
||||||
}
|
}
|
||||||
} elseif ($action === 'add_category') {
|
} elseif ($action === 'add_category') {
|
||||||
if (!has_permission('categories_add')) {
|
if (!has_permission('categories_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to add categories.</div>';
|
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to add categories.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("INSERT INTO categories (name, description, image_url) VALUES (?, ?, ?)");
|
$stmt = $pdo->prepare("INSERT INTO categories (name, name_ar, description, image_url) VALUES (?, ?, ?, ?)");
|
||||||
$stmt->execute([$name, $description, $image_url]);
|
$stmt->execute([$name, $name_ar, $description, $image_url]);
|
||||||
$message = '<div class="alert alert-success">Category created successfully!</div>';
|
$message = '<div class="alert alert-success">Category created successfully!</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,6 +106,7 @@ include 'includes/header.php';
|
|||||||
<thead class="bg-light">
|
<thead class="bg-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="ps-4">Category</th>
|
<th class="ps-4">Category</th>
|
||||||
|
<th>Arabic Name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th class="text-end pe-4">Actions</th>
|
<th class="text-end pe-4">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -118,6 +120,9 @@ include 'includes/header.php';
|
|||||||
<div class="fw-bold text-dark fs-6"><?= htmlspecialchars($cat['name']) ?></div>
|
<div class="fw-bold text-dark fs-6"><?= htmlspecialchars($cat['name']) ?></div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="text-dark"><?= htmlspecialchars($cat['name_ar'] ?? '-') ?></div>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="text-muted small text-truncate" style="max-width: 300px;"><?= htmlspecialchars($cat['description'] ?? 'No description') ?></div>
|
<div class="text-muted small text-truncate" style="max-width: 300px;"><?= htmlspecialchars($cat['description'] ?? 'No description') ?></div>
|
||||||
</td>
|
</td>
|
||||||
@ -161,7 +166,17 @@ include 'includes/header.php';
|
|||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label small fw-bold text-muted">CATEGORY NAME <span class="text-danger">*</span></label>
|
<label class="form-label small fw-bold text-muted">CATEGORY NAME <span class="text-danger">*</span></label>
|
||||||
<input type="text" name="name" id="categoryName" class="form-control rounded-3 border-0 bg-light" required>
|
<div class="input-group">
|
||||||
|
<input type="text" name="name" id="categoryName" class="form-control rounded-start-3 border-0 bg-light" required>
|
||||||
|
<button class="btn btn-outline-secondary border-0 bg-light" type="button" id="btnTranslate">
|
||||||
|
<i class="bi bi-translate text-primary"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label small fw-bold text-muted">ARABIC NAME</label>
|
||||||
|
<input type="text" name="name_ar" id="categoryNameAr" class="form-control rounded-3 border-0 bg-light" dir="rtl">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@ -203,6 +218,7 @@ function prepareEditForm(cat) {
|
|||||||
document.getElementById('categoryAction').value = 'edit_category';
|
document.getElementById('categoryAction').value = 'edit_category';
|
||||||
document.getElementById('categoryId').value = cat.id;
|
document.getElementById('categoryId').value = cat.id;
|
||||||
document.getElementById('categoryName').value = cat.name;
|
document.getElementById('categoryName').value = cat.name;
|
||||||
|
document.getElementById('categoryNameAr').value = cat.name_ar || '';
|
||||||
document.getElementById('categoryDescription').value = cat.description || '';
|
document.getElementById('categoryDescription').value = cat.description || '';
|
||||||
|
|
||||||
if (cat.image_url) {
|
if (cat.image_url) {
|
||||||
@ -213,6 +229,46 @@ function prepareEditForm(cat) {
|
|||||||
document.getElementById('categoryImagePreview').style.display = 'none';
|
document.getElementById('categoryImagePreview').style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('btnTranslate').addEventListener('click', function() {
|
||||||
|
const text = document.getElementById('categoryName').value;
|
||||||
|
if (!text) {
|
||||||
|
alert('Please enter a category name first.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const btn = this;
|
||||||
|
const originalHtml = btn.innerHTML;
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.innerHTML = '<span class="spinner-border spinner-border-sm text-primary" role="status" aria-hidden="true"></span>';
|
||||||
|
|
||||||
|
fetch('../api/translate.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
text: text,
|
||||||
|
target_lang: 'Arabic'
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
document.getElementById('categoryNameAr').value = data.translated_text;
|
||||||
|
} else {
|
||||||
|
alert('Translation failed: ' + (data.error || 'Unknown error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred during translation.');
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.innerHTML = originalHtml;
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
|||||||
2
db/migrations/030_add_name_ar_to_categories.sql
Normal file
2
db/migrations/030_add_name_ar_to_categories.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- Add Arabic name to categories table
|
||||||
|
ALTER TABLE categories ADD COLUMN name_ar VARCHAR(255) AFTER name;
|
||||||
57
pos.php
57
pos.php
@ -156,12 +156,19 @@ if (!$loyalty_settings) {
|
|||||||
</button>
|
</button>
|
||||||
<?php foreach ($categories as $category): ?>
|
<?php foreach ($categories as $category): ?>
|
||||||
<button class="category-btn mb-1" onclick="filterCategory(<?= $category['id'] ?>, this)">
|
<button class="category-btn mb-1" onclick="filterCategory(<?= $category['id'] ?>, this)">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
<?php if (!empty($category['image_url'])): ?>
|
<?php if (!empty($category['image_url'])): ?>
|
||||||
<img src="<?= htmlspecialchars($category['image_url']) ?>" style="width: 20px; height: 20px; border-radius: 4px; object-fit: cover;" class="me-2">
|
<img src="<?= htmlspecialchars($category['image_url']) ?>" style="width: 24px; height: 24px; border-radius: 4px; object-fit: cover;" class="me-2">
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<i class="bi bi-tag me-2"></i>
|
<i class="bi bi-tag me-2"></i>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?= htmlspecialchars($category['name']) ?>
|
<div>
|
||||||
|
<div class="category-name"><?= htmlspecialchars($category['name']) ?></div>
|
||||||
|
<?php if (!empty($category['name_ar'])): ?>
|
||||||
|
<div class="small opacity-75" dir="rtl" style="font-size: 0.75rem;"><?= htmlspecialchars($category['name_ar']) ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
@ -173,7 +180,7 @@ if (!$loyalty_settings) {
|
|||||||
<select class="form-select" onchange="filterCategory(this.value)">
|
<select class="form-select" onchange="filterCategory(this.value)">
|
||||||
<option value="all">All Categories</option>
|
<option value="all">All Categories</option>
|
||||||
<?php foreach ($categories as $cat): ?>
|
<?php foreach ($categories as $cat): ?>
|
||||||
<option value="<?= $cat['id'] ?>"><?= htmlspecialchars($cat['name']) ?></option>
|
<option value="<?= $cat['id'] ?>"><?= htmlspecialchars($cat['name']) ?> <?= !empty($cat['name_ar']) ? '(' . $cat['name_ar'] . ')' : '' ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -500,17 +507,30 @@ if (!$loyalty_settings) {
|
|||||||
<div class="modal fade" id="ratingQRModal" tabindex="-1" aria-hidden="true">
|
<div class="modal fade" id="ratingQRModal" tabindex="-1" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header bg-warning">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title fw-bold text-dark"><i class="bi bi-star-fill me-2"></i> Customer Rating QR</h5>
|
<h5 class="modal-title fw-bold">Rating & Feedback QR</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body text-center py-4">
|
<div class="modal-body text-center p-4">
|
||||||
<p class="text-muted mb-4">Show this QR code to the customer to rate our staff and service.</p>
|
<p class="text-muted mb-4">Ask your customers to scan this QR code to rate your service and staff.</p>
|
||||||
<div class="mb-4">
|
<div id="rating-qr-container" class="mb-4">
|
||||||
<img id="rating-qr-img" src="" alt="Rating QR Code" class="img-fluid border p-3 bg-white shadow-sm" style="max-width: 250px;">
|
<!-- QR Code will be generated here -->
|
||||||
|
<div class="bg-light p-4 rounded-4 d-inline-block shadow-sm">
|
||||||
|
<?php
|
||||||
|
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
|
||||||
|
$host = $_SERVER['HTTP_HOST'];
|
||||||
|
$ratingUrl = $protocol . "://" . $host . "/rate.php";
|
||||||
|
|
||||||
|
// Using a public QR generator for simplicity
|
||||||
|
$qrUrl = "https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=" . urlencode($ratingUrl);
|
||||||
|
?>
|
||||||
|
<img src="<?= $qrUrl ?>" alt="Rating QR Code" class="img-fluid" style="width: 200px; height: 200px;">
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-light border small text-break" id="rating-url-text"></div>
|
</div>
|
||||||
<button class="btn btn-primary w-100 mt-3" onclick="window.print()">
|
<div class="alert alert-info small py-2">
|
||||||
|
<i class="bi bi-link-45deg me-1"></i> URL: <a href="<?= $ratingUrl ?>" target="_blank" class="text-decoration-none"><?= $ratingUrl ?></a>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary w-100 rounded-pill py-2 fw-bold" onclick="window.print()">
|
||||||
<i class="bi bi-printer me-2"></i> Print QR Code
|
<i class="bi bi-printer me-2"></i> Print QR Code
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -518,24 +538,13 @@ if (!$loyalty_settings) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="assets/js/main.js?v=<?= time() ?>"></script>
|
||||||
<script>
|
<script>
|
||||||
const COMPANY_SETTINGS = <?= json_encode($settings) ?>;
|
|
||||||
const LOYALTY_SETTINGS = <?= json_encode($loyalty_settings) ?>;
|
|
||||||
const PRODUCT_VARIANTS = <?= json_encode($variants_by_product) ?>;
|
|
||||||
const PAYMENT_TYPES = <?= json_encode($payment_types) ?>;
|
|
||||||
const CURRENT_USER = <?= json_encode(['id' => $currentUser['id'], 'name' => $currentUser['name']]) ?>;
|
|
||||||
const CURRENT_OUTLET = <?= json_encode(['id' => $outlet_id, 'name' => $current_outlet_name]) ?>;
|
|
||||||
const BASE_URL = '<?= get_base_url() ?>';
|
|
||||||
|
|
||||||
function showRatingQR() {
|
function showRatingQR() {
|
||||||
const ratingUrl = BASE_URL + 'rate.php';
|
|
||||||
document.getElementById('rating-qr-img').src = 'https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=' + encodeURIComponent(ratingUrl);
|
|
||||||
document.getElementById('rating-url-text').textContent = ratingUrl;
|
|
||||||
const modal = new bootstrap.Modal(document.getElementById('ratingQRModal'));
|
const modal = new bootstrap.Modal(document.getElementById('ratingQRModal'));
|
||||||
modal.show();
|
modal.show();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
||||||
<script src="assets/js/main.js?v=<?= time() ?>"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user