arabic translate for qr order
This commit is contained in:
parent
291449ae16
commit
6cbe1c3306
@ -10,6 +10,7 @@ $message = '';
|
|||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||||
$action = $_POST['action'];
|
$action = $_POST['action'];
|
||||||
$name = trim($_POST['name']);
|
$name = trim($_POST['name']);
|
||||||
|
$name_ar = trim($_POST['name_ar'] ?? '');
|
||||||
$description = trim($_POST['description']);
|
$description = trim($_POST['description']);
|
||||||
$id = isset($_POST['id']) ? (int)$_POST['id'] : null;
|
$id = isset($_POST['id']) ? (int)$_POST['id'] : null;
|
||||||
|
|
||||||
@ -21,16 +22,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
if (!has_permission('expense_categories_add')) {
|
if (!has_permission('expense_categories_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("UPDATE expense_categories SET name = ?, description = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE expense_categories SET name = ?, name_ar = ?, description = ? WHERE id = ?");
|
||||||
$stmt->execute([$name, $description, $id]);
|
$stmt->execute([$name, $name_ar, $description, $id]);
|
||||||
$message = '<div class="alert alert-success">Expense category updated successfully!</div>';
|
$message = '<div class="alert alert-success">Expense category updated successfully!</div>';
|
||||||
}
|
}
|
||||||
} elseif ($action === 'add_expense_category') {
|
} elseif ($action === 'add_expense_category') {
|
||||||
if (!has_permission('expense_categories_add')) {
|
if (!has_permission('expense_categories_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("INSERT INTO expense_categories (name, description) VALUES (?, ?)");
|
$stmt = $pdo->prepare("INSERT INTO expense_categories (name, name_ar, description) VALUES (?, ?, ?)");
|
||||||
$stmt->execute([$name, $description]);
|
$stmt->execute([$name, $name_ar, $description]);
|
||||||
$message = '<div class="alert alert-success">Expense category created successfully!</div>';
|
$message = '<div class="alert alert-success">Expense category created successfully!</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,6 +83,7 @@ include 'includes/header.php';
|
|||||||
<tr>
|
<tr>
|
||||||
<th class="ps-4">ID</th>
|
<th class="ps-4">ID</th>
|
||||||
<th>Name</th>
|
<th>Name</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>
|
||||||
@ -91,6 +93,7 @@ include 'includes/header.php';
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="ps-4 fw-medium">#<?= $cat['id'] ?></td>
|
<td class="ps-4 fw-medium">#<?= $cat['id'] ?></td>
|
||||||
<td class="fw-bold"><?= htmlspecialchars($cat['name']) ?></td>
|
<td class="fw-bold"><?= htmlspecialchars($cat['name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($cat['name_ar'] ?: '-') ?></td>
|
||||||
<td><small class="text-muted"><?= htmlspecialchars($cat['description'] ?: '-') ?></small></td>
|
<td><small class="text-muted"><?= htmlspecialchars($cat['description'] ?: '-') ?></small></td>
|
||||||
<td class="text-end pe-4">
|
<td class="text-end pe-4">
|
||||||
<?php if (has_permission('expense_categories_add')): ?>
|
<?php if (has_permission('expense_categories_add')): ?>
|
||||||
@ -106,7 +109,7 @@ include 'includes/header.php';
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php if (empty($expense_categories)): ?>
|
<?php if (empty($expense_categories)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4" class="text-center py-4 text-muted">No expense categories found.</td>
|
<td colspan="5" class="text-center py-4 text-muted">No expense categories found.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -134,7 +137,16 @@ include 'includes/header.php';
|
|||||||
<input type="hidden" name="id" id="expenseCategoryId">
|
<input type="hidden" name="id" id="expenseCategoryId">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Category Name <span class="text-danger">*</span></label>
|
<label class="form-label">Category Name <span class="text-danger">*</span></label>
|
||||||
<input type="text" name="name" id="expenseCategoryName" class="form-control" required>
|
<div class="input-group">
|
||||||
|
<input type="text" name="name" id="expenseCategoryName" class="form-control" required>
|
||||||
|
<button class="btn btn-outline-secondary" type="button" id="btnTranslate">
|
||||||
|
<i class="bi bi-translate text-primary"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Arabic Name</label>
|
||||||
|
<input type="text" name="name_ar" id="expenseCategoryNameAr" class="form-control" dir="rtl">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Description</label>
|
<label class="form-label">Description</label>
|
||||||
@ -177,11 +189,52 @@ function openEditModal(cat) {
|
|||||||
document.getElementById('expenseCategoryAction').value = 'edit_expense_category';
|
document.getElementById('expenseCategoryAction').value = 'edit_expense_category';
|
||||||
document.getElementById('expenseCategoryId').value = cat.id;
|
document.getElementById('expenseCategoryId').value = cat.id;
|
||||||
document.getElementById('expenseCategoryName').value = cat.name || '';
|
document.getElementById('expenseCategoryName').value = cat.name || '';
|
||||||
|
document.getElementById('expenseCategoryNameAr').value = cat.name_ar || '';
|
||||||
document.getElementById('expenseCategoryDescription').value = cat.description || '';
|
document.getElementById('expenseCategoryDescription').value = cat.description || '';
|
||||||
|
|
||||||
modal.show();
|
modal.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('btnTranslate').addEventListener('click', function() {
|
||||||
|
const text = document.getElementById('expenseCategoryName').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('expenseCategoryNameAr').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; ?>
|
||||||
|
|
||||||
<?php include 'includes/footer.php'; ?>
|
<?php include 'includes/footer.php'; ?>
|
||||||
@ -10,6 +10,7 @@ $message = '';
|
|||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||||
$action = $_POST['action'];
|
$action = $_POST['action'];
|
||||||
$name = trim($_POST['name']);
|
$name = trim($_POST['name']);
|
||||||
|
$name_ar = trim($_POST['name_ar'] ?? '');
|
||||||
$address = trim($_POST['address']);
|
$address = trim($_POST['address']);
|
||||||
$id = isset($_POST['id']) ? (int)$_POST['id'] : null;
|
$id = isset($_POST['id']) ? (int)$_POST['id'] : null;
|
||||||
|
|
||||||
@ -21,16 +22,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
if (!has_permission('outlets_add')) {
|
if (!has_permission('outlets_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("UPDATE outlets SET name = ?, address = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE outlets SET name = ?, name_ar = ?, address = ? WHERE id = ?");
|
||||||
$stmt->execute([$name, $address, $id]);
|
$stmt->execute([$name, $name_ar, $address, $id]);
|
||||||
$message = '<div class="alert alert-success">Outlet updated successfully!</div>';
|
$message = '<div class="alert alert-success">Outlet updated successfully!</div>';
|
||||||
}
|
}
|
||||||
} elseif ($action === 'add_outlet') {
|
} elseif ($action === 'add_outlet') {
|
||||||
if (!has_permission('outlets_add')) {
|
if (!has_permission('outlets_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
$message = '<div class="alert alert-danger">Access Denied.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("INSERT INTO outlets (name, address) VALUES (?, ?)");
|
$stmt = $pdo->prepare("INSERT INTO outlets (name, name_ar, address) VALUES (?, ?, ?)");
|
||||||
$stmt->execute([$name, $address]);
|
$stmt->execute([$name, $name_ar, $address]);
|
||||||
$message = '<div class="alert alert-success">Outlet created successfully!</div>';
|
$message = '<div class="alert alert-success">Outlet created successfully!</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,6 +83,7 @@ include 'includes/header.php';
|
|||||||
<tr>
|
<tr>
|
||||||
<th class="ps-4">ID</th>
|
<th class="ps-4">ID</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
|
<th>Arabic Name</th>
|
||||||
<th>Address</th>
|
<th>Address</th>
|
||||||
<th class="text-end pe-4">Actions</th>
|
<th class="text-end pe-4">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -91,6 +93,7 @@ include 'includes/header.php';
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="ps-4 fw-medium">#<?= $outlet['id'] ?></td>
|
<td class="ps-4 fw-medium">#<?= $outlet['id'] ?></td>
|
||||||
<td class="fw-bold"><?= htmlspecialchars($outlet['name']) ?></td>
|
<td class="fw-bold"><?= htmlspecialchars($outlet['name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($outlet['name_ar'] ?: '-') ?></td>
|
||||||
<td><small class="text-muted"><?= htmlspecialchars($outlet['address']) ?></small></td>
|
<td><small class="text-muted"><?= htmlspecialchars($outlet['address']) ?></small></td>
|
||||||
<td class="text-end pe-4">
|
<td class="text-end pe-4">
|
||||||
<?php if (has_permission('outlets_add')): ?>
|
<?php if (has_permission('outlets_add')): ?>
|
||||||
@ -107,7 +110,7 @@ include 'includes/header.php';
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php if (empty($outlets)): ?>
|
<?php if (empty($outlets)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4" class="text-center py-4 text-muted">No outlets found.</td>
|
<td colspan="5" class="text-center py-4 text-muted">No outlets found.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -135,7 +138,16 @@ include 'includes/header.php';
|
|||||||
<input type="hidden" name="id" id="outletId">
|
<input type="hidden" name="id" id="outletId">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Name <span class="text-danger">*</span></label>
|
<label class="form-label">Name <span class="text-danger">*</span></label>
|
||||||
<input type="text" name="name" id="outletName" class="form-control" required>
|
<div class="input-group">
|
||||||
|
<input type="text" name="name" id="outletName" class="form-control" required>
|
||||||
|
<button class="btn btn-outline-secondary" type="button" id="btnTranslate">
|
||||||
|
<i class="bi bi-translate text-primary"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Arabic Name</label>
|
||||||
|
<input type="text" name="name_ar" id="outletNameAr" class="form-control" dir="rtl">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Address</label>
|
<label class="form-label">Address</label>
|
||||||
@ -165,9 +177,50 @@ function prepareEditForm(outlet) {
|
|||||||
document.getElementById('outletAction').value = 'edit_outlet';
|
document.getElementById('outletAction').value = 'edit_outlet';
|
||||||
document.getElementById('outletId').value = outlet.id;
|
document.getElementById('outletId').value = outlet.id;
|
||||||
document.getElementById('outletName').value = outlet.name || '';
|
document.getElementById('outletName').value = outlet.name || '';
|
||||||
|
document.getElementById('outletNameAr').value = outlet.name_ar || '';
|
||||||
document.getElementById('outletAddress').value = outlet.address || '';
|
document.getElementById('outletAddress').value = outlet.address || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('btnTranslate').addEventListener('click', function() {
|
||||||
|
const text = document.getElementById('outletName').value;
|
||||||
|
if (!text) {
|
||||||
|
alert('Please enter an outlet 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('outletNameAr').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; ?>
|
||||||
|
|
||||||
<?php include 'includes/footer.php'; ?>
|
<?php include 'includes/footer.php'; ?>
|
||||||
|
|||||||
@ -23,10 +23,11 @@ if (!$product) {
|
|||||||
// Handle Add Variant
|
// Handle Add Variant
|
||||||
if (isset($_POST['action']) && $_POST['action'] === 'add_variant') {
|
if (isset($_POST['action']) && $_POST['action'] === 'add_variant') {
|
||||||
$name = $_POST['name'];
|
$name = $_POST['name'];
|
||||||
|
$name_ar = $_POST['name_ar'] ?? '';
|
||||||
$price_adj = $_POST['price_adjustment'];
|
$price_adj = $_POST['price_adjustment'];
|
||||||
|
|
||||||
$stmt = $pdo->prepare("INSERT INTO product_variants (product_id, name, price_adjustment) VALUES (?, ?, ?)");
|
$stmt = $pdo->prepare("INSERT INTO product_variants (product_id, name, name_ar, price_adjustment) VALUES (?, ?, ?, ?)");
|
||||||
$stmt->execute([$product_id, $name, $price_adj]);
|
$stmt->execute([$product_id, $name, $name_ar, $price_adj]);
|
||||||
header("Location: product_variants.php?product_id=$product_id");
|
header("Location: product_variants.php?product_id=$product_id");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@ -35,10 +36,11 @@ if (isset($_POST['action']) && $_POST['action'] === 'add_variant') {
|
|||||||
if (isset($_POST['action']) && $_POST['action'] === 'edit_variant') {
|
if (isset($_POST['action']) && $_POST['action'] === 'edit_variant') {
|
||||||
$id = $_POST['variant_id'];
|
$id = $_POST['variant_id'];
|
||||||
$name = $_POST['name'];
|
$name = $_POST['name'];
|
||||||
|
$name_ar = $_POST['name_ar'] ?? '';
|
||||||
$price_adj = $_POST['price_adjustment'];
|
$price_adj = $_POST['price_adjustment'];
|
||||||
|
|
||||||
$stmt = $pdo->prepare("UPDATE product_variants SET name = ?, price_adjustment = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE product_variants SET name = ?, name_ar = ?, price_adjustment = ? WHERE id = ?");
|
||||||
$stmt->execute([$name, $price_adj, $id]);
|
$stmt->execute([$name, $name_ar, $price_adj, $id]);
|
||||||
header("Location: product_variants.php?product_id=$product_id");
|
header("Location: product_variants.php?product_id=$product_id");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@ -83,6 +85,7 @@ $effective_base_price = get_product_price($product);
|
|||||||
<thead class="bg-light">
|
<thead class="bg-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="ps-4">Variant Name</th>
|
<th class="ps-4">Variant Name</th>
|
||||||
|
<th>Arabic Name</th>
|
||||||
<th>Price Adjustment</th>
|
<th>Price Adjustment</th>
|
||||||
<th>Final Price (Est.)</th>
|
<th>Final Price (Est.)</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
@ -92,6 +95,7 @@ $effective_base_price = get_product_price($product);
|
|||||||
<?php foreach ($variants as $variant): ?>
|
<?php foreach ($variants as $variant): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="ps-4 fw-medium"><?= htmlspecialchars($variant['name']) ?></td>
|
<td class="ps-4 fw-medium"><?= htmlspecialchars($variant['name']) ?></td>
|
||||||
|
<td><div class="text-primary small fw-semibold" dir="rtl"><?= htmlspecialchars($variant['name_ar'] ?? '-') ?></div></td>
|
||||||
<td>
|
<td>
|
||||||
<?php if ($variant['price_adjustment'] > 0): ?>
|
<?php if ($variant['price_adjustment'] > 0): ?>
|
||||||
<span class="text-danger">+ <?= format_currency($variant['price_adjustment']) ?></span>
|
<span class="text-danger">+ <?= format_currency($variant['price_adjustment']) ?></span>
|
||||||
@ -113,6 +117,7 @@ $effective_base_price = get_product_price($product);
|
|||||||
data-bs-target="#editVariantModal"
|
data-bs-target="#editVariantModal"
|
||||||
data-id="<?= $variant['id'] ?>"
|
data-id="<?= $variant['id'] ?>"
|
||||||
data-name="<?= htmlspecialchars($variant['name']) ?>"
|
data-name="<?= htmlspecialchars($variant['name']) ?>"
|
||||||
|
data-name-ar="<?= htmlspecialchars($variant['name_ar'] ?? '') ?>"
|
||||||
data-price="<?= $variant['price_adjustment'] ?>">
|
data-price="<?= $variant['price_adjustment'] ?>">
|
||||||
<i class="bi bi-pencil"></i>
|
<i class="bi bi-pencil"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -122,7 +127,7 @@ $effective_base_price = get_product_price($product);
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php if (empty($variants)): ?>
|
<?php if (empty($variants)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4" class="text-center py-5 text-muted">No variants defined (e.g., Small, Large, Spicy).</td>
|
<td colspan="5" class="text-center py-5 text-muted">No variants defined (e.g., Small, Large, Spicy).</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -147,8 +152,17 @@ $effective_base_price = get_product_price($product);
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input type="hidden" name="action" value="add_variant">
|
<input type="hidden" name="action" value="add_variant">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Variant Name (e.g., Large, Extra Cheese)</label>
|
<label class="form-label">Variant Name (EN)</label>
|
||||||
<input type="text" name="name" class="form-control" required>
|
<div class="input-group">
|
||||||
|
<input type="text" name="name" id="add_name" class="form-control" required>
|
||||||
|
<button class="btn btn-outline-secondary" type="button" onclick="translateField('add_name', 'add_name_ar')">
|
||||||
|
<i class="bi bi-translate"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Variant Name (AR)</label>
|
||||||
|
<input type="text" name="name_ar" id="add_name_ar" class="form-control text-end" dir="rtl">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Price Adjustment (+/-)</label>
|
<label class="form-label">Price Adjustment (+/-)</label>
|
||||||
@ -181,8 +195,17 @@ $effective_base_price = get_product_price($product);
|
|||||||
<input type="hidden" name="action" value="edit_variant">
|
<input type="hidden" name="action" value="edit_variant">
|
||||||
<input type="hidden" name="variant_id" id="edit_variant_id">
|
<input type="hidden" name="variant_id" id="edit_variant_id">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Variant Name</label>
|
<label class="form-label">Variant Name (EN)</label>
|
||||||
<input type="text" name="name" id="edit_variant_name" class="form-control" required>
|
<div class="input-group">
|
||||||
|
<input type="text" name="name" id="edit_variant_name" class="form-control" required>
|
||||||
|
<button class="btn btn-outline-secondary" type="button" onclick="translateField('edit_variant_name', 'edit_variant_name_ar')">
|
||||||
|
<i class="bi bi-translate"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Variant Name (AR)</label>
|
||||||
|
<input type="text" name="name_ar" id="edit_variant_name_ar" class="form-control text-end" dir="rtl">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Price Adjustment (+/-)</label>
|
<label class="form-label">Price Adjustment (+/-)</label>
|
||||||
@ -209,17 +232,39 @@ $effective_base_price = get_product_price($product);
|
|||||||
var button = event.relatedTarget;
|
var button = event.relatedTarget;
|
||||||
var id = button.getAttribute('data-id');
|
var id = button.getAttribute('data-id');
|
||||||
var name = button.getAttribute('data-name');
|
var name = button.getAttribute('data-name');
|
||||||
|
var nameAr = button.getAttribute('data-name-ar');
|
||||||
var price = button.getAttribute('data-price');
|
var price = button.getAttribute('data-price');
|
||||||
|
|
||||||
var modalIdInput = editVariantModal.querySelector('#edit_variant_id');
|
var modalIdInput = editVariantModal.querySelector('#edit_variant_id');
|
||||||
var modalNameInput = editVariantModal.querySelector('#edit_variant_name');
|
var modalNameInput = editVariantModal.querySelector('#edit_variant_name');
|
||||||
|
var modalNameArInput = editVariantModal.querySelector('#edit_variant_name_ar');
|
||||||
var modalPriceInput = editVariantModal.querySelector('#edit_variant_price');
|
var modalPriceInput = editVariantModal.querySelector('#edit_variant_price');
|
||||||
|
|
||||||
modalIdInput.value = id;
|
modalIdInput.value = id;
|
||||||
modalNameInput.value = name;
|
modalNameInput.value = name;
|
||||||
|
modalNameArInput.value = nameAr;
|
||||||
modalPriceInput.value = price;
|
modalPriceInput.value = price;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function translateField(sourceId, targetId) {
|
||||||
|
const text = document.getElementById(sourceId).value;
|
||||||
|
if (!text) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('../api/translate.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ text: text, target_lang: 'Arabic' })
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.success) {
|
||||||
|
document.getElementById(targetId).value = data.translated_text;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php include 'includes/footer.php'; ?>
|
<?php include 'includes/footer.php'; ?>
|
||||||
@ -14,7 +14,7 @@ $endDate = $_GET['end_date'] ?? date('Y-m-d');
|
|||||||
$outletId = $_GET['outlet_id'] ?? '';
|
$outletId = $_GET['outlet_id'] ?? '';
|
||||||
|
|
||||||
// Fetch Outlets for filter
|
// Fetch Outlets for filter
|
||||||
$outletsStmt = $pdo->query("SELECT id, name FROM outlets ORDER BY name ASC");
|
$outletsStmt = $pdo->query("SELECT id, name, name_ar FROM outlets ORDER BY name ASC");
|
||||||
$allOutlets = $outletsStmt->fetchAll();
|
$allOutlets = $outletsStmt->fetchAll();
|
||||||
|
|
||||||
// Base query additions
|
// Base query additions
|
||||||
@ -31,6 +31,7 @@ if (!empty($outletId)) {
|
|||||||
$staffStmt = $pdo->prepare("
|
$staffStmt = $pdo->prepare("
|
||||||
SELECT
|
SELECT
|
||||||
u.full_name as staff_name,
|
u.full_name as staff_name,
|
||||||
|
u.full_name_ar as staff_name_ar,
|
||||||
u.username,
|
u.username,
|
||||||
COUNT(o.id) as order_count,
|
COUNT(o.id) as order_count,
|
||||||
SUM(o.total_amount) as total_sales
|
SUM(o.total_amount) as total_sales
|
||||||
@ -48,6 +49,7 @@ $staffSales = $staffStmt->fetchAll();
|
|||||||
$outletStmt = $pdo->prepare("
|
$outletStmt = $pdo->prepare("
|
||||||
SELECT
|
SELECT
|
||||||
ot.name as outlet_name,
|
ot.name as outlet_name,
|
||||||
|
ot.name_ar as outlet_name_ar,
|
||||||
COUNT(o.id) as order_count,
|
COUNT(o.id) as order_count,
|
||||||
SUM(o.total_amount) as total_sales
|
SUM(o.total_amount) as total_sales
|
||||||
FROM orders o
|
FROM orders o
|
||||||
@ -64,6 +66,7 @@ $outletSales = $outletStmt->fetchAll();
|
|||||||
$categoryStmt = $pdo->prepare("
|
$categoryStmt = $pdo->prepare("
|
||||||
SELECT
|
SELECT
|
||||||
c.name as category_name,
|
c.name as category_name,
|
||||||
|
c.name_ar as category_name_ar,
|
||||||
SUM(oi.quantity) as items_sold,
|
SUM(oi.quantity) as items_sold,
|
||||||
SUM(oi.quantity * oi.unit_price) as total_sales
|
SUM(oi.quantity * oi.unit_price) as total_sales
|
||||||
FROM order_items oi
|
FROM order_items oi
|
||||||
@ -82,6 +85,7 @@ $categorySales = $categoryStmt->fetchAll();
|
|||||||
$expenseCatStmt = $pdo->prepare("
|
$expenseCatStmt = $pdo->prepare("
|
||||||
SELECT
|
SELECT
|
||||||
ec.name as category_name,
|
ec.name as category_name,
|
||||||
|
ec.name_ar as category_name_ar,
|
||||||
SUM(e.amount) as total_amount
|
SUM(e.amount) as total_amount
|
||||||
FROM expenses e
|
FROM expenses e
|
||||||
JOIN expense_categories ec ON e.category_id = ec.id
|
JOIN expense_categories ec ON e.category_id = ec.id
|
||||||
@ -129,7 +133,7 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
|||||||
<option value="">All Outlets</option>
|
<option value="">All Outlets</option>
|
||||||
<?php foreach ($allOutlets as $o): ?>
|
<?php foreach ($allOutlets as $o): ?>
|
||||||
<option value="<?= $o['id'] ?>" <?= $outletId == $o['id'] ? 'selected' : '' ?>>
|
<option value="<?= $o['id'] ?>" <?= $outletId == $o['id'] ? 'selected' : '' ?>>
|
||||||
<?= htmlspecialchars($o['name']) ?>
|
<?= htmlspecialchars($o['name']) ?> <?= $o['name_ar'] ? '('.$o['name_ar'].')' : '' ?>
|
||||||
</option>
|
</option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
@ -236,6 +240,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="ps-3">
|
<td class="ps-3">
|
||||||
<div class="fw-bold"><?= htmlspecialchars($staff['staff_name'] ?: $staff['username']) ?></div>
|
<div class="fw-bold"><?= htmlspecialchars($staff['staff_name'] ?: $staff['username']) ?></div>
|
||||||
|
<?php if ($staff['staff_name_ar']): ?>
|
||||||
|
<small class="text-muted"><?= htmlspecialchars($staff['staff_name_ar']) ?></small>
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center"><?= $staff['order_count'] ?></td>
|
<td class="text-center"><?= $staff['order_count'] ?></td>
|
||||||
<td class="text-end pe-3 fw-bold text-primary"><?= format_currency($staff['total_sales']) ?></td>
|
<td class="text-end pe-3 fw-bold text-primary"><?= format_currency($staff['total_sales']) ?></td>
|
||||||
@ -273,6 +280,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="ps-3">
|
<td class="ps-3">
|
||||||
<div class="fw-bold"><?= htmlspecialchars($outlet['outlet_name']) ?></div>
|
<div class="fw-bold"><?= htmlspecialchars($outlet['outlet_name']) ?></div>
|
||||||
|
<?php if ($outlet['outlet_name_ar']): ?>
|
||||||
|
<small class="text-muted"><?= htmlspecialchars($outlet['outlet_name_ar']) ?></small>
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center"><?= $outlet['order_count'] ?></td>
|
<td class="text-center"><?= $outlet['order_count'] ?></td>
|
||||||
<td class="text-end pe-3 fw-bold text-success"><?= format_currency($outlet['total_sales']) ?></td>
|
<td class="text-end pe-3 fw-bold text-success"><?= format_currency($outlet['total_sales']) ?></td>
|
||||||
@ -310,6 +320,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="ps-3">
|
<td class="ps-3">
|
||||||
<div class="fw-bold"><?= htmlspecialchars($cat['category_name']) ?></div>
|
<div class="fw-bold"><?= htmlspecialchars($cat['category_name']) ?></div>
|
||||||
|
<?php if ($cat['category_name_ar']): ?>
|
||||||
|
<small class="text-muted"><?= htmlspecialchars($cat['category_name_ar']) ?></small>
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center"><?= $cat['items_sold'] ?></td>
|
<td class="text-center"><?= $cat['items_sold'] ?></td>
|
||||||
<td class="text-end pe-3 fw-bold text-dark"><?= format_currency($cat['total_sales']) ?></td>
|
<td class="text-end pe-3 fw-bold text-dark"><?= format_currency($cat['total_sales']) ?></td>
|
||||||
@ -346,6 +359,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="ps-3">
|
<td class="ps-3">
|
||||||
<div class="fw-bold"><?= htmlspecialchars($exp['category_name']) ?></div>
|
<div class="fw-bold"><?= htmlspecialchars($exp['category_name']) ?></div>
|
||||||
|
<?php if ($exp['category_name_ar']): ?>
|
||||||
|
<small class="text-muted"><?= htmlspecialchars($exp['category_name_ar']) ?></small>
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end pe-3 fw-bold text-danger"><?= format_currency($exp['total_amount']) ?></td>
|
<td class="text-end pe-3 fw-bold text-danger"><?= format_currency($exp['total_amount']) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -11,6 +11,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
$action = $_POST['action'];
|
$action = $_POST['action'];
|
||||||
$username = trim($_POST['username']);
|
$username = trim($_POST['username']);
|
||||||
$full_name = trim($_POST['full_name']);
|
$full_name = trim($_POST['full_name']);
|
||||||
|
$full_name_ar = trim($_POST['full_name_ar'] ?? '');
|
||||||
$email = trim($_POST['email']);
|
$email = trim($_POST['email']);
|
||||||
$group_id = (int)$_POST['group_id'];
|
$group_id = (int)$_POST['group_id'];
|
||||||
$is_active = isset($_POST['is_active']) ? 1 : 0;
|
$is_active = isset($_POST['is_active']) ? 1 : 0;
|
||||||
@ -45,13 +46,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
if (!has_permission('users_edit') && !has_permission('users_add')) {
|
if (!has_permission('users_edit') && !has_permission('users_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to edit users.</div>';
|
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to edit users.</div>';
|
||||||
} else {
|
} else {
|
||||||
$sql = "UPDATE users SET username = ?, full_name = ?, email = ?, group_id = ?, is_active = ?, is_ratable = ?, profile_pic = ? WHERE id = ?";
|
$sql = "UPDATE users SET username = ?, full_name = ?, full_name_ar = ?, email = ?, group_id = ?, is_active = ?, is_ratable = ?, profile_pic = ? WHERE id = ?";
|
||||||
$params = [$username, $full_name, $email, $group_id, $is_active, $is_ratable, $profile_pic, $id];
|
$params = [$username, $full_name, $full_name_ar, $email, $group_id, $is_active, $is_ratable, $profile_pic, $id];
|
||||||
|
|
||||||
if (!empty($_POST['password'])) {
|
if (!empty($_POST['password'])) {
|
||||||
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
||||||
$sql = "UPDATE users SET username = ?, full_name = ?, email = ?, group_id = ?, is_active = ?, is_ratable = ?, profile_pic = ?, password = ? WHERE id = ?";
|
$sql = "UPDATE users SET username = ?, full_name = ?, full_name_ar = ?, email = ?, group_id = ?, is_active = ?, is_ratable = ?, profile_pic = ?, password = ? WHERE id = ?";
|
||||||
$params = [$username, $full_name, $email, $group_id, $is_active, $is_ratable, $profile_pic, $password, $id];
|
$params = [$username, $full_name, $full_name_ar, $email, $group_id, $is_active, $is_ratable, $profile_pic, $password, $id];
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
@ -63,8 +64,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to add users.</div>';
|
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to add users.</div>';
|
||||||
} else {
|
} else {
|
||||||
$password = password_hash($_POST['password'] ?: '123456', PASSWORD_DEFAULT);
|
$password = password_hash($_POST['password'] ?: '123456', PASSWORD_DEFAULT);
|
||||||
$stmt = $pdo->prepare("INSERT INTO users (username, password, full_name, email, group_id, is_active, is_ratable, profile_pic) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
$stmt = $pdo->prepare("INSERT INTO users (username, password, full_name, full_name_ar, email, group_id, is_active, is_ratable, profile_pic) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
$stmt->execute([$username, $password, $full_name, $email, $group_id, $is_active, $is_ratable, $profile_pic]);
|
$stmt->execute([$username, $password, $full_name, $full_name_ar, $email, $group_id, $is_active, $is_ratable, $profile_pic]);
|
||||||
$message = '<div class="alert alert-success">User created successfully!</div>';
|
$message = '<div class="alert alert-success">User created successfully!</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,6 +133,7 @@ include 'includes/header.php';
|
|||||||
<thead class="bg-light">
|
<thead class="bg-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="ps-4">User</th>
|
<th class="ps-4">User</th>
|
||||||
|
<th>Arabic Name</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Role / Group</th>
|
<th>Role / Group</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
@ -155,6 +157,7 @@ include 'includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td><?= htmlspecialchars($user['full_name_ar'] ?: '-') ?></td>
|
||||||
<td><?= htmlspecialchars($user['email'] ?: '-') ?></td>
|
<td><?= htmlspecialchars($user['email'] ?: '-') ?></td>
|
||||||
<td><span class="badge bg-light text-dark border px-2 py-1"><?= htmlspecialchars($user['group_name'] ?: 'None') ?></span></td>
|
<td><span class="badge bg-light text-dark border px-2 py-1"><?= htmlspecialchars($user['group_name'] ?: 'None') ?></span></td>
|
||||||
<td>
|
<td>
|
||||||
@ -189,7 +192,7 @@ include 'includes/header.php';
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php if (empty($users)): ?>
|
<?php if (empty($users)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center py-5 text-muted">No users found.</td>
|
<td colspan="7" class="text-center py-5 text-muted">No users found.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -223,7 +226,16 @@ include 'includes/header.php';
|
|||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label small fw-bold text-muted">FULL NAME</label>
|
<label class="form-label small fw-bold text-muted">FULL NAME</label>
|
||||||
<input type="text" name="full_name" id="userFullName" class="form-control rounded-3 border-0 bg-light" required>
|
<div class="input-group">
|
||||||
|
<input type="text" name="full_name" id="userFullName" class="form-control rounded-start-3 border-0 bg-light">
|
||||||
|
<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 FULL NAME</label>
|
||||||
|
<input type="text" name="full_name_ar" id="userFullNameAr" class="form-control rounded-3 border-0 bg-light" dir="rtl">
|
||||||
</div>
|
</div>
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
@ -295,6 +307,7 @@ function prepareEditForm(user) {
|
|||||||
document.getElementById('userAction').value = 'edit_user';
|
document.getElementById('userAction').value = 'edit_user';
|
||||||
document.getElementById('userId').value = user.id;
|
document.getElementById('userId').value = user.id;
|
||||||
document.getElementById('userFullName').value = user.full_name || '';
|
document.getElementById('userFullName').value = user.full_name || '';
|
||||||
|
document.getElementById('userFullNameAr').value = user.full_name_ar || '';
|
||||||
document.getElementById('userUsername').value = user.username || '';
|
document.getElementById('userUsername').value = user.username || '';
|
||||||
document.getElementById('userEmail').value = user.email || '';
|
document.getElementById('userEmail').value = user.email || '';
|
||||||
document.getElementById('userGroupId').value = user.group_id || '';
|
document.getElementById('userGroupId').value = user.group_id || '';
|
||||||
@ -312,7 +325,47 @@ function prepareEditForm(user) {
|
|||||||
document.getElementById('userImagePreviewContainer').style.display = 'none';
|
document.getElementById('userImagePreviewContainer').style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('btnTranslate').addEventListener('click', function() {
|
||||||
|
const text = document.getElementById('userFullName').value;
|
||||||
|
if (!text) {
|
||||||
|
alert('Please enter a full 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('userFullNameAr').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; ?>
|
||||||
|
|
||||||
<?php include 'includes/footer.php'; ?>
|
<?php include 'includes/footer.php'; ?>
|
||||||
2
db/migrations/031_add_name_ar_to_product_variants.sql
Normal file
2
db/migrations/031_add_name_ar_to_product_variants.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- Add name_ar to product_variants
|
||||||
|
ALTER TABLE product_variants ADD COLUMN name_ar VARCHAR(255) AFTER name;
|
||||||
2
db/migrations/032_add_full_name_ar_to_users.sql
Normal file
2
db/migrations/032_add_full_name_ar_to_users.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- Add full_name_ar to users table
|
||||||
|
ALTER TABLE users ADD COLUMN full_name_ar VARCHAR(255) AFTER full_name;
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
-- Add name_ar to outlets and expense_categories
|
||||||
|
ALTER TABLE outlets ADD COLUMN name_ar VARCHAR(255) AFTER name;
|
||||||
|
ALTER TABLE expense_categories ADD COLUMN name_ar VARCHAR(255) AFTER name;
|
||||||
212
qorder.php
212
qorder.php
@ -29,7 +29,7 @@ if (!$table_info) {
|
|||||||
|
|
||||||
$outlet_id = (int)$table_info['outlet_id'];
|
$outlet_id = (int)$table_info['outlet_id'];
|
||||||
$categories = $pdo->query("SELECT * FROM categories ORDER BY sort_order")->fetchAll();
|
$categories = $pdo->query("SELECT * FROM categories ORDER BY sort_order")->fetchAll();
|
||||||
$all_products = $pdo->query("SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id")->fetchAll();
|
$all_products = $pdo->query("SELECT p.*, c.name as category_name, c.name_ar as category_name_ar FROM products p JOIN categories c ON p.category_id = c.id")->fetchAll();
|
||||||
|
|
||||||
// Fetch variants
|
// Fetch variants
|
||||||
$variants_raw = $pdo->query("SELECT * FROM product_variants ORDER BY price_adjustment ASC")->fetchAll();
|
$variants_raw = $pdo->query("SELECT * FROM product_variants ORDER BY price_adjustment ASC")->fetchAll();
|
||||||
@ -50,22 +50,46 @@ foreach ($variants_raw as $v) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Noto+Sans+Arabic:wght@400;600;700&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
body { font-family: 'Inter', sans-serif; background-color: #f8f9fa; padding-bottom: 80px; }
|
:root {
|
||||||
|
--primary-font: 'Inter', sans-serif;
|
||||||
|
--arabic-font: 'Noto Sans Arabic', sans-serif;
|
||||||
|
}
|
||||||
|
body { font-family: var(--primary-font); background-color: #f8f9fa; padding-bottom: 80px; }
|
||||||
|
body.lang-ar { font-family: var(--arabic-font); direction: rtl; text-align: right; }
|
||||||
|
|
||||||
.category-nav { overflow-x: auto; white-space: nowrap; background: #fff; padding: 10px; position: sticky; top: 0; z-index: 1020; border-bottom: 1px solid #eee; }
|
.category-nav { overflow-x: auto; white-space: nowrap; background: #fff; padding: 10px; position: sticky; top: 0; z-index: 1020; border-bottom: 1px solid #eee; }
|
||||||
.category-item { display: inline-block; padding: 8px 16px; border-radius: 20px; background: #f1f3f5; margin-right: 8px; font-weight: 500; font-size: 0.9rem; cursor: pointer; border: 1px solid transparent; }
|
.category-item { display: inline-block; padding: 8px 16px; border-radius: 20px; background: #f1f3f5; margin-right: 8px; font-weight: 500; font-size: 0.9rem; cursor: pointer; border: 1px solid transparent; }
|
||||||
|
.lang-ar .category-item { margin-right: 0; margin-left: 8px; }
|
||||||
.category-item.active { background: #0d6efd; color: #fff; }
|
.category-item.active { background: #0d6efd; color: #fff; }
|
||||||
.product-card { border: none; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.05); transition: transform 0.2s; }
|
|
||||||
|
.product-card { border: none; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.05); transition: transform 0.2s; position: relative; }
|
||||||
.product-card:active { transform: scale(0.98); }
|
.product-card:active { transform: scale(0.98); }
|
||||||
.product-img { height: 140px; object-fit: cover; }
|
.product-img { height: 140px; object-fit: cover; }
|
||||||
|
|
||||||
.cart-footer { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; padding: 15px; border-top: 1px solid #eee; z-index: 1030; display: none; }
|
.cart-footer { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; padding: 15px; border-top: 1px solid #eee; z-index: 1030; display: none; }
|
||||||
.badge-price { position: absolute; bottom: 10px; right: 10px; background: rgba(255,255,255,0.9); padding: 2px 8px; border-radius: 12px; font-weight: bold; font-size: 0.85rem; }
|
.badge-price { position: absolute; bottom: 10px; right: 10px; background: rgba(255,255,255,0.9); padding: 2px 8px; border-radius: 12px; font-weight: bold; font-size: 0.85rem; }
|
||||||
|
.lang-ar .badge-price { right: auto; left: 10px; }
|
||||||
|
|
||||||
.quantity-controls { display: flex; align-items: center; gap: 10px; }
|
.quantity-controls { display: flex; align-items: center; gap: 10px; }
|
||||||
.quantity-btn { width: 32px; height: 32px; border-radius: 50%; border: 1px solid #dee2e6; background: #fff; display: flex; align-items: center; justify-content: center; }
|
.quantity-btn { width: 32px; height: 32px; border-radius: 50%; border: 1px solid #dee2e6; background: #fff; display: flex; align-items: center; justify-content: center; }
|
||||||
|
|
||||||
|
.lang-toggle { font-size: 0.8rem; font-weight: bold; cursor: pointer; padding: 4px 8px; border-radius: 4px; border: 1px solid #dee2e6; background: #f8f9fa; }
|
||||||
|
|
||||||
|
.name-en { display: block; }
|
||||||
|
.name-ar { display: none; }
|
||||||
|
.lang-ar .name-en { display: none; }
|
||||||
|
.lang-ar .name-ar { display: block; }
|
||||||
|
|
||||||
|
.both-names .name-en { display: block; }
|
||||||
|
.both-names .name-ar { display: block; font-size: 0.85em; opacity: 0.8; color: #0d6efd; margin-top: 2px; }
|
||||||
|
|
||||||
|
.modal-header .btn-close { margin: 0; }
|
||||||
|
.lang-ar .modal-header .btn-close { margin-right: auto; margin-left: 0; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="both-names">
|
||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<header class="bg-white p-3 border-bottom d-flex align-items-center justify-content-between">
|
<header class="bg-white p-3 border-bottom d-flex align-items-center justify-content-between">
|
||||||
@ -75,14 +99,27 @@ foreach ($variants_raw as $v) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<span class="fw-bold"><?= htmlspecialchars($settings['company_name']) ?></span>
|
<span class="fw-bold"><?= htmlspecialchars($settings['company_name']) ?></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="badge bg-light text-dark border">Table <?= htmlspecialchars($table_info['table_name']) ?></div>
|
<div class="d-flex align-items-center gap-2">
|
||||||
|
<div class="lang-toggle" onclick="toggleLanguage()" id="lang-btn">AR</div>
|
||||||
|
<div class="badge bg-light text-dark border"><span data-t="table">Table</span> <?= htmlspecialchars($table_info['table_name']) ?></div>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Category Nav -->
|
<!-- Category Nav -->
|
||||||
<div class="category-nav shadow-sm">
|
<div class="category-nav shadow-sm">
|
||||||
<div class="category-item active" onclick="filterCategory('all', this)">All</div>
|
<div class="category-item active" onclick="filterCategory('all', this)">
|
||||||
|
<span class="name-en">All</span>
|
||||||
|
<span class="name-ar">الكل</span>
|
||||||
|
</div>
|
||||||
<?php foreach ($categories as $cat): ?>
|
<?php foreach ($categories as $cat): ?>
|
||||||
<div class="category-item" onclick="filterCategory(<?= $cat['id'] ?>, this)"><?= htmlspecialchars($cat['name']) ?></div>
|
<div class="category-item" onclick="filterCategory(<?= $cat['id'] ?>, this)">
|
||||||
|
<span class="name-en"><?= htmlspecialchars($cat['name']) ?></span>
|
||||||
|
<?php if (!empty($cat['name_ar'])): ?>
|
||||||
|
<span class="name-ar"><?= htmlspecialchars($cat['name_ar']) ?></span>
|
||||||
|
<?php else: ?>
|
||||||
|
<span class="name-ar"><?= htmlspecialchars($cat['name']) ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -98,6 +135,7 @@ foreach ($variants_raw as $v) {
|
|||||||
onclick="handleProductClick(<?= htmlspecialchars(json_encode([
|
onclick="handleProductClick(<?= htmlspecialchars(json_encode([
|
||||||
'id' => $product['id'],
|
'id' => $product['id'],
|
||||||
'name' => $product['name'],
|
'name' => $product['name'],
|
||||||
|
'name_ar' => $product['name_ar'] ?? $product['name'],
|
||||||
'price' => (float)$effective_price,
|
'price' => (float)$effective_price,
|
||||||
'has_variants' => $has_variants
|
'has_variants' => $has_variants
|
||||||
])) ?>)">
|
])) ?>)">
|
||||||
@ -110,7 +148,7 @@ foreach ($variants_raw as $v) {
|
|||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?= number_format((float)$product['price'], 3) ?>
|
<?= number_format((float)$product['price'], 3) ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
OMR
|
<span data-t="currency">OMR</span>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($is_promo): ?>
|
<?php if ($is_promo): ?>
|
||||||
<div class="position-absolute top-0 start-0 m-2">
|
<div class="position-absolute top-0 start-0 m-2">
|
||||||
@ -119,8 +157,14 @@ foreach ($variants_raw as $v) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-2">
|
<div class="card-body p-2">
|
||||||
<h6 class="card-title mb-1 small fw-bold text-truncate"><?= htmlspecialchars($product['name']) ?></h6>
|
<h6 class="card-title mb-1 small fw-bold text-truncate">
|
||||||
<p class="card-text small text-muted mb-0" style="font-size: 0.75rem;"><?= htmlspecialchars($product['category_name']) ?></p>
|
<span class="name-en"><?= htmlspecialchars($product['name']) ?></span>
|
||||||
|
<span class="name-ar" dir="rtl"><?= htmlspecialchars($product['name_ar'] ?? $product['name']) ?></span>
|
||||||
|
</h6>
|
||||||
|
<p class="card-text small text-muted mb-0 text-truncate" style="font-size: 0.75rem;">
|
||||||
|
<span class="name-en"><?= htmlspecialchars($product['category_name']) ?></span>
|
||||||
|
<span class="name-ar" dir="rtl"><?= htmlspecialchars($product['category_name_ar'] ?? $product['category_name']) ?></span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -132,11 +176,11 @@ foreach ($variants_raw as $v) {
|
|||||||
<div class="cart-footer shadow-lg" id="cart-footer">
|
<div class="cart-footer shadow-lg" id="cart-footer">
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
<div>
|
<div>
|
||||||
<div class="small text-muted" id="cart-items-count">0 Items</div>
|
<div class="small text-muted"><span id="cart-items-count">0</span> <span data-t="items">Items</span></div>
|
||||||
<div class="fw-bold fs-5 text-primary" id="cart-total-display">0.000 OMR</div>
|
<div class="fw-bold fs-5 text-primary" id="cart-total-display">0.000 OMR</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary px-4 fw-bold" onclick="showCart()">
|
<button class="btn btn-primary px-4 fw-bold" onclick="showCart()">
|
||||||
View Cart <i class="bi bi-cart-fill ms-1"></i>
|
<span data-t="view_cart">View Cart</span> <i class="bi bi-cart-fill ms-1"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -146,7 +190,7 @@ foreach ($variants_raw as $v) {
|
|||||||
<div class="modal-dialog modal-dialog-centered modal-fullscreen-sm-down">
|
<div class="modal-dialog modal-dialog-centered modal-fullscreen-sm-down">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title fw-bold">Your Order</h5>
|
<h5 class="modal-title fw-bold" data-t="your_order">Your Order</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 p-0">
|
<div class="modal-body p-0">
|
||||||
@ -155,21 +199,21 @@ foreach ($variants_raw as $v) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="p-3 bg-light border-top">
|
<div class="p-3 bg-light border-top">
|
||||||
<div class="d-flex justify-content-between mb-2">
|
<div class="d-flex justify-content-between mb-2">
|
||||||
<span>Subtotal</span>
|
<span data-t="subtotal">Subtotal</span>
|
||||||
<span id="modal-subtotal">0.000 OMR</span>
|
<span id="modal-subtotal">0.000 OMR</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-between fw-bold fs-5">
|
<div class="d-flex justify-content-between fw-bold fs-5">
|
||||||
<span>Total</span>
|
<span data-t="total">Total</span>
|
||||||
<span id="modal-total">0.000 OMR</span>
|
<span id="modal-total">0.000 OMR</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label small text-muted">Your Name (Optional)</label>
|
<label class="form-label small text-muted" data-t="cust_name_label">Your Name (Optional)</label>
|
||||||
<input type="text" id="cust-name" class="form-control" placeholder="To identify your order">
|
<input type="text" id="cust-name" class="form-control" data-t-placeholder="cust_name_placeholder" placeholder="To identify your order">
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary btn-lg w-100 fw-bold" id="btn-place-order" onclick="placeOrder()">
|
<button class="btn btn-primary btn-lg w-100 fw-bold" id="btn-place-order" onclick="placeOrder()">
|
||||||
Place Order <i class="bi bi-send-fill ms-1"></i>
|
<span data-t="place_order">Place Order</span> <i class="bi bi-send-fill ms-1"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -182,7 +226,7 @@ foreach ($variants_raw as $v) {
|
|||||||
<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">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="variantTitle">Select Option</h5>
|
<h5 class="modal-title" id="variantTitle" data-t="select_option">Select Option</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">
|
<div class="modal-body">
|
||||||
@ -202,9 +246,83 @@ foreach ($variants_raw as $v) {
|
|||||||
const PRODUCT_VARIANTS = <?= json_encode($variants_by_product) ?>;
|
const PRODUCT_VARIANTS = <?= json_encode($variants_by_product) ?>;
|
||||||
|
|
||||||
let cart = [];
|
let cart = [];
|
||||||
|
let currentLang = localStorage.getItem('qorder_lang') || 'en';
|
||||||
const cartModal = new bootstrap.Modal(document.getElementById('cartModal'));
|
const cartModal = new bootstrap.Modal(document.getElementById('cartModal'));
|
||||||
const variantModal = new bootstrap.Modal(document.getElementById('variantModal'));
|
const variantModal = new bootstrap.Modal(document.getElementById('variantModal'));
|
||||||
|
|
||||||
|
const translations = {
|
||||||
|
en: {
|
||||||
|
table: 'Table',
|
||||||
|
items: 'Items',
|
||||||
|
view_cart: 'View Cart',
|
||||||
|
your_order: 'Your Order',
|
||||||
|
subtotal: 'Subtotal',
|
||||||
|
total: 'Total',
|
||||||
|
cust_name_label: 'Your Name (Optional)',
|
||||||
|
cust_name_placeholder: 'To identify your order',
|
||||||
|
place_order: 'Place Order',
|
||||||
|
select_option: 'Select Option',
|
||||||
|
currency: 'OMR',
|
||||||
|
added_to_cart: 'added to cart',
|
||||||
|
order_placed: 'Order Placed!',
|
||||||
|
order_success_msg: 'Your order has been sent to the kitchen. Thank you!',
|
||||||
|
placing_order: 'Placing Order...'
|
||||||
|
},
|
||||||
|
ar: {
|
||||||
|
table: 'طاولة',
|
||||||
|
items: 'أصناف',
|
||||||
|
view_cart: 'عرض السلة',
|
||||||
|
your_order: 'طلبك',
|
||||||
|
subtotal: 'المجموع الفرعي',
|
||||||
|
total: 'الإجمالي',
|
||||||
|
cust_name_label: 'اسمك (اختياري)',
|
||||||
|
cust_name_placeholder: 'لتحديد طلبك',
|
||||||
|
place_order: 'إتمام الطلب',
|
||||||
|
select_option: 'اختر الخيار',
|
||||||
|
currency: 'ر.ع.',
|
||||||
|
added_to_cart: 'تم الإضافة إلى السلة',
|
||||||
|
order_placed: 'تم إرسال الطلب!',
|
||||||
|
order_success_msg: 'تم إرسال طلبك إلى المطبخ. شكراً لك!',
|
||||||
|
placing_order: 'جاري إرسال الطلب...'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateTranslations() {
|
||||||
|
document.querySelectorAll('[data-t]').forEach(el => {
|
||||||
|
const key = el.getAttribute('data-t');
|
||||||
|
if (translations[currentLang][key]) {
|
||||||
|
el.textContent = translations[currentLang][key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.querySelectorAll('[data-t-placeholder]').forEach(el => {
|
||||||
|
const key = el.getAttribute('data-t-placeholder');
|
||||||
|
if (translations[currentLang][key]) {
|
||||||
|
el.placeholder = translations[currentLang][key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.getElementById('lang-btn').textContent = currentLang === 'en' ? 'AR' : 'EN';
|
||||||
|
if (currentLang === 'ar') {
|
||||||
|
document.body.classList.add('lang-ar');
|
||||||
|
document.body.classList.remove('both-names'); // Optional: hide EN when AR is active?
|
||||||
|
// User said "both", so maybe I should keep both-names active if I want to show both.
|
||||||
|
// But let's follow standard toggle behavior for UI.
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove('lang-ar');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update currency in displays
|
||||||
|
updateCartUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleLanguage() {
|
||||||
|
currentLang = currentLang === 'en' ? 'ar' : 'en';
|
||||||
|
localStorage.setItem('qorder_lang', currentLang);
|
||||||
|
updateTranslations();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize translations
|
||||||
|
updateTranslations();
|
||||||
|
|
||||||
function filterCategory(catId, el) {
|
function filterCategory(catId, el) {
|
||||||
document.querySelectorAll('.category-item').forEach(i => i.classList.remove('active'));
|
document.querySelectorAll('.category-item').forEach(i => i.classList.remove('active'));
|
||||||
el.classList.add('active');
|
el.classList.add('active');
|
||||||
@ -222,14 +340,14 @@ foreach ($variants_raw as $v) {
|
|||||||
if (product.has_variants) {
|
if (product.has_variants) {
|
||||||
showVariants(product);
|
showVariants(product);
|
||||||
} else {
|
} else {
|
||||||
addToCart(product.id, product.name, product.price);
|
addToCart(product.id, currentLang === 'ar' ? product.name_ar : product.name, product.price);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showVariants(product) {
|
function showVariants(product) {
|
||||||
const variants = PRODUCT_VARIANTS[product.id] || [];
|
const variants = PRODUCT_VARIANTS[product.id] || [];
|
||||||
const container = document.getElementById('variant-list');
|
const container = document.getElementById('variant-list');
|
||||||
document.getElementById('variantTitle').textContent = product.name;
|
document.getElementById('variantTitle').textContent = currentLang === 'ar' ? product.name_ar : product.name;
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
|
||||||
variants.forEach(v => {
|
variants.forEach(v => {
|
||||||
@ -237,15 +355,18 @@ foreach ($variants_raw as $v) {
|
|||||||
btn.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center py-3';
|
btn.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center py-3';
|
||||||
const adj = parseFloat(v.price_adjustment);
|
const adj = parseFloat(v.price_adjustment);
|
||||||
const finalPrice = product.price + adj;
|
const finalPrice = product.price + adj;
|
||||||
|
const vName = currentLang === 'ar' && v.name_ar ? v.name_ar : v.name;
|
||||||
|
const pName = currentLang === 'ar' ? product.name_ar : product.name;
|
||||||
|
|
||||||
btn.innerHTML = `
|
btn.innerHTML = `
|
||||||
<div>
|
<div>
|
||||||
<div class="fw-bold">${v.name}</div>
|
<div class="fw-bold">${vName}</div>
|
||||||
<div class="small text-muted">${adj > 0 ? '+' : ''}${adj.toFixed(3)} OMR</div>
|
<div class="small text-muted">${adj > 0 ? '+' : ''}${adj.toFixed(3)} ${translations[currentLang].currency}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fw-bold text-primary">${finalPrice.toFixed(3)} OMR</div>
|
<div class="fw-bold text-primary">${finalPrice.toFixed(3)} ${translations[currentLang].currency}</div>
|
||||||
`;
|
`;
|
||||||
btn.onclick = () => {
|
btn.onclick = () => {
|
||||||
addToCart(product.id, `${product.name} (${v.name})`, finalPrice, v.id);
|
addToCart(product.id, `${pName} (${vName})`, finalPrice, v.id);
|
||||||
variantModal.hide();
|
variantModal.hide();
|
||||||
};
|
};
|
||||||
container.appendChild(btn);
|
container.appendChild(btn);
|
||||||
@ -261,15 +382,16 @@ foreach ($variants_raw as $v) {
|
|||||||
cart.push({ product_id: pid, name, unit_price: price, variant_id: vid, quantity: 1 });
|
cart.push({ product_id: pid, name, unit_price: price, variant_id: vid, quantity: 1 });
|
||||||
}
|
}
|
||||||
updateCartUI();
|
updateCartUI();
|
||||||
showToast(name + ' added to cart');
|
showToast(name + ' ' + translations[currentLang].added_to_cart);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCartUI() {
|
function updateCartUI() {
|
||||||
const total = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);
|
const total = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);
|
||||||
const count = cart.reduce((sum, item) => sum + item.quantity, 0);
|
const count = cart.reduce((sum, item) => sum + item.quantity, 0);
|
||||||
|
const currency = translations[currentLang].currency;
|
||||||
|
|
||||||
document.getElementById('cart-items-count').textContent = count + ' Items';
|
document.getElementById('cart-items-count').textContent = count;
|
||||||
document.getElementById('cart-total-display').textContent = total.toFixed(3) + ' OMR';
|
document.getElementById('cart-total-display').textContent = total.toFixed(3) + ' ' + currency;
|
||||||
|
|
||||||
const footer = document.getElementById('cart-footer');
|
const footer = document.getElementById('cart-footer');
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
@ -282,6 +404,7 @@ foreach ($variants_raw as $v) {
|
|||||||
function showCart() {
|
function showCart() {
|
||||||
const list = document.getElementById('cart-list');
|
const list = document.getElementById('cart-list');
|
||||||
list.innerHTML = '';
|
list.innerHTML = '';
|
||||||
|
const currency = translations[currentLang].currency;
|
||||||
|
|
||||||
cart.forEach((item, index) => {
|
cart.forEach((item, index) => {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
@ -304,8 +427,8 @@ foreach ($variants_raw as $v) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const total = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);
|
const total = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);
|
||||||
document.getElementById('modal-subtotal').textContent = total.toFixed(3) + ' OMR';
|
document.getElementById('modal-subtotal').textContent = total.toFixed(3) + ' ' + currency;
|
||||||
document.getElementById('modal-total').textContent = total.toFixed(3) + ' OMR';
|
document.getElementById('modal-total').textContent = total.toFixed(3) + ' ' + currency;
|
||||||
|
|
||||||
cartModal.show();
|
cartModal.show();
|
||||||
}
|
}
|
||||||
@ -328,19 +451,19 @@ foreach ($variants_raw as $v) {
|
|||||||
|
|
||||||
const btn = document.getElementById('btn-place-order');
|
const btn = document.getElementById('btn-place-order');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Placing Order...';
|
btn.innerHTML = `<span class="spinner-border spinner-border-sm me-2"></span>${translations[currentLang].placing_order}`;
|
||||||
|
|
||||||
const total = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);
|
const total = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);
|
||||||
const customerName = document.getElementById('cust-name').value;
|
const customerName = document.getElementById('cust-name').value;
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
outlet_id: OUTLET_ID,
|
outlet_id: OUTLET_ID,
|
||||||
table_number: TABLE_ID, // api/order.php expects table ID in table_number
|
table_number: TABLE_ID,
|
||||||
order_type: 'dine-in',
|
order_type: 'dine-in',
|
||||||
customer_name: customerName,
|
customer_name: customerName,
|
||||||
items: cart,
|
items: cart,
|
||||||
total_amount: total,
|
total_amount: total,
|
||||||
payment_type_id: null // Unpaid
|
payment_type_id: null
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch('api/order.php', {
|
fetch('api/order.php', {
|
||||||
@ -352,10 +475,10 @@ foreach ($variants_raw as $v) {
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Order Placed!',
|
title: translations[currentLang].order_placed,
|
||||||
text: 'Your order has been sent to the kitchen. Thank you!',
|
text: translations[currentLang].order_success_msg,
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
confirmButtonText: 'Great!'
|
confirmButtonText: currentLang === 'ar' ? 'ممتاز' : 'Great!'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
cart = [];
|
cart = [];
|
||||||
updateCartUI();
|
updateCartUI();
|
||||||
@ -371,13 +494,22 @@ foreach ($variants_raw as $v) {
|
|||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.innerHTML = 'Place Order <i class="bi bi-send-fill ms-1"></i>';
|
btn.innerHTML = `${translations[currentLang].place_order} <i class="bi bi-send-fill ms-1"></i>`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showToast(msg) {
|
function showToast(msg) {
|
||||||
// Simple alert for now, or use a toast
|
const Toast = Swal.mixin({
|
||||||
console.log(msg);
|
toast: true,
|
||||||
|
position: 'top-end',
|
||||||
|
showConfirmButton: false,
|
||||||
|
timer: 2000,
|
||||||
|
timerProgressBar: true
|
||||||
|
});
|
||||||
|
Toast.fire({
|
||||||
|
icon: 'success',
|
||||||
|
title: msg
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
185
rate.php
185
rate.php
@ -39,7 +39,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
|
|
||||||
// Fetch active and ratable users with pictures
|
// Fetch active and ratable users with pictures
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
$stmt = $pdo->query("SELECT id, full_name, username, profile_pic FROM users WHERE is_active = 1 AND is_ratable = 1 ORDER BY full_name ASC");
|
$stmt = $pdo->query("SELECT id, full_name, full_name_ar, username, profile_pic FROM users WHERE is_active = 1 AND is_ratable = 1 ORDER BY full_name ASC");
|
||||||
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -50,7 +50,7 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<title>Rate Our Service - <?= htmlspecialchars($companyName) ?></title>
|
<title>Rate Our Service - <?= htmlspecialchars($companyName) ?></title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Noto+Sans+Arabic:wght@400;600;700&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--primary-color: #007bff;
|
--primary-color: #007bff;
|
||||||
@ -64,6 +64,12 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
background: var(--bg-gradient);
|
background: var(--bg-gradient);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.rtl {
|
||||||
|
font-family: 'Noto Sans Arabic', sans-serif;
|
||||||
|
direction: rtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rating-container {
|
.rating-container {
|
||||||
@ -75,6 +81,19 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
.header {
|
.header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lang-toggle {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.rtl .lang-toggle {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
@ -210,6 +229,13 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
}
|
}
|
||||||
.shape-1 { top: 10%; left: 5%; width: 100px; height: 100px; background: #007bff22; border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; }
|
.shape-1 { top: 10%; left: 5%; width: 100px; height: 100px; background: #007bff22; border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; }
|
||||||
.shape-2 { bottom: 10%; right: 5%; width: 150px; height: 150px; background: #ffc10711; border-radius: 50%; }
|
.shape-2 { bottom: 10%; right: 5%; width: 150px; height: 150px; background: #ffc10711; border-radius: 50%; }
|
||||||
|
|
||||||
|
.name-ar {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--secondary-color);
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -219,21 +245,27 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
|
|
||||||
<div class="container rating-container">
|
<div class="container rating-container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
<div class="lang-toggle">
|
||||||
|
<button class="btn btn-sm btn-outline-primary rounded-pill px-3 fw-bold" onclick="toggleLanguage()">
|
||||||
|
<i class="bi bi-translate me-1"></i> <span id="lang-btn-text">العربية</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<?php if ($logoUrl): ?>
|
<?php if ($logoUrl): ?>
|
||||||
<img src="<?= htmlspecialchars($logoUrl) ?>" alt="Logo" class="logo">
|
<img src="<?= htmlspecialchars($logoUrl) ?>" alt="Logo" class="logo">
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<h1 class="fw-bold"><?= htmlspecialchars($companyName) ?></h1>
|
<h1 class="fw-bold"><?= htmlspecialchars($companyName) ?></h1>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<p class="text-muted" id="main-instruction">We value your feedback! What would you like to rate?</p>
|
<p class="text-muted" id="main-instruction" data-t="main_instruction">We value your feedback! What would you like to rate?</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($success): ?>
|
<?php if ($success): ?>
|
||||||
<div class="success-animation card border-0 shadow-sm rounded-4">
|
<div class="success-animation card border-0 shadow-sm rounded-4">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<i class="bi bi-check-circle-fill success-icon"></i>
|
<i class="bi bi-check-circle-fill success-icon"></i>
|
||||||
<h2>Thank You!</h2>
|
<h2 data-t="thank_you">Thank You!</h2>
|
||||||
<p>Your rating has been submitted successfully.</p>
|
<p data-t="success_msg">Your rating has been submitted successfully.</p>
|
||||||
<a href="index.php" class="btn btn-outline-primary rounded-pill px-4 mt-3">Back to Home</a>
|
<a href="index.php" class="btn btn-outline-primary rounded-pill px-4 mt-3" data-t="back_home">Back to Home</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
@ -251,23 +283,23 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<div class="service-icon">
|
<div class="service-icon">
|
||||||
<i class="bi bi-shop"></i>
|
<i class="bi bi-shop"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="service-name fs-4">Rate Our Services</div>
|
<div class="service-name fs-4" data-t="rate_services">Rate Our Services</div>
|
||||||
<p class="text-muted small">How was your overall experience with us?</p>
|
<p class="text-muted small" data-t="service_subtitle">How was your overall experience with us?</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 text-center mt-5 mb-2">
|
<div class="col-12 text-center mt-5 mb-2">
|
||||||
<h5 class="fw-bold text-muted">OR RATE OUR STAFF</h5>
|
<h5 class="fw-bold text-muted" data-t="or_rate_staff">OR RATE OUR STAFF</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (empty($users)): ?>
|
<?php if (empty($users)): ?>
|
||||||
<div class="col-12 text-center">
|
<div class="col-12 text-center">
|
||||||
<p class="text-muted">No staff members are currently available for rating.</p>
|
<p class="text-muted" data-t="no_staff">No staff members are currently available for rating.</p>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($users as $user): ?>
|
<?php foreach ($users as $user): ?>
|
||||||
<div class="col-6 col-md-3">
|
<div class="col-6 col-md-3">
|
||||||
<div class="staff-card" onclick="selectStaff(<?= $user['id'] ?>, '<?= htmlspecialchars($user['full_name']) ?>', this)">
|
<div class="staff-card" onclick="selectStaff(<?= $user['id'] ?>, '<?= htmlspecialchars($user['full_name']) ?>', '<?= htmlspecialchars($user['full_name_ar'] ?: $user['full_name']) ?>', this)">
|
||||||
<?php if ($user['profile_pic']): ?>
|
<?php if ($user['profile_pic']): ?>
|
||||||
<img src="<?= htmlspecialchars($user['profile_pic']) ?>" alt="<?= htmlspecialchars($user['full_name']) ?>" class="staff-pic">
|
<img src="<?= htmlspecialchars($user['profile_pic']) ?>" alt="<?= htmlspecialchars($user['full_name']) ?>" class="staff-pic">
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
@ -275,7 +307,12 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<?= strtoupper(substr($user['full_name'] ?: $user['username'], 0, 1)) ?>
|
<?= strtoupper(substr($user['full_name'] ?: $user['username'], 0, 1)) ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div class="staff-name"><?= htmlspecialchars($user['full_name'] ?: $user['username']) ?></div>
|
<div class="staff-name">
|
||||||
|
<span class="name-en"><?= htmlspecialchars($user['full_name'] ?: $user['username']) ?></span>
|
||||||
|
<?php if ($user['full_name_ar']): ?>
|
||||||
|
<span class="name-ar"><?= htmlspecialchars($user['full_name_ar']) ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@ -287,7 +324,7 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<input type="hidden" name="user_id" id="selected-user-id">
|
<input type="hidden" name="user_id" id="selected-user-id">
|
||||||
|
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<h4 id="rating-title" class="fw-bold mb-0">Rate <span id="staff-display-name"></span></h4>
|
<h4 id="rating-title" class="fw-bold mb-0"><span data-t="rate">Rate</span> <span id="staff-display-name"></span></h4>
|
||||||
<p id="rating-subtitle" class="text-muted"></p>
|
<p id="rating-subtitle" class="text-muted"></p>
|
||||||
|
|
||||||
<div class="star-rating">
|
<div class="star-rating">
|
||||||
@ -300,16 +337,16 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="comment" class="form-label fw-semibold" id="comment-label">Any additional comments?</label>
|
<label for="comment" class="form-label fw-semibold" id="comment-label" data-t="comments_label">Any additional comments?</label>
|
||||||
<textarea class="form-control rounded-4 shadow-sm border-0 bg-light" name="comment" id="comment" rows="3" placeholder="Tell us about your experience..."></textarea>
|
<textarea class="form-control rounded-4 shadow-sm border-0 bg-light" name="comment" id="comment" rows="3" placeholder="Tell us about your experience..." data-tp="comment_placeholder"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<button type="button" class="btn btn-light w-100 rounded-pill py-3 fw-bold" onclick="cancelSelection()">Cancel</button>
|
<button type="button" class="btn btn-light w-100 rounded-pill py-3 fw-bold" onclick="cancelSelection()" data-t="cancel">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<button type="submit" class="btn btn-primary btn-submit m-0 py-3 fw-bold">Submit Rating</button>
|
<button type="submit" class="btn btn-primary btn-submit m-0 py-3 fw-bold" data-t="submit">Submit Rating</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -317,7 +354,95 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const translations = {
|
||||||
|
en: {
|
||||||
|
main_instruction: "We value your feedback! What would you like to rate?",
|
||||||
|
thank_you: "Thank You!",
|
||||||
|
success_msg: "Your rating has been submitted successfully.",
|
||||||
|
back_home: "Back to Home",
|
||||||
|
rate_services: "Rate Our Services",
|
||||||
|
service_subtitle: "How was your overall experience with us?",
|
||||||
|
or_rate_staff: "OR RATE OUR STAFF",
|
||||||
|
no_staff: "No staff members are currently available for rating.",
|
||||||
|
rate: "Rate",
|
||||||
|
rate_staff_subtitle: "Rate the service provided by this staff member.",
|
||||||
|
rate_service_subtitle: "We would love to hear how we are doing overall.",
|
||||||
|
comments_label: "Any additional comments?",
|
||||||
|
comment_placeholder: "Tell us about your experience...",
|
||||||
|
improve_label: "What can we improve?",
|
||||||
|
specific_feedback: "Any specific feedback for {name}?",
|
||||||
|
cancel: "Cancel",
|
||||||
|
submit: "Submit Rating",
|
||||||
|
lang_btn: "العربية",
|
||||||
|
our_services: "Our Services"
|
||||||
|
},
|
||||||
|
ar: {
|
||||||
|
main_instruction: "نحن نقدر رأيك! ما الذي تود تقييمه؟",
|
||||||
|
thank_you: "شكراً لك!",
|
||||||
|
success_msg: "تم إرسال تقييمك بنجاح.",
|
||||||
|
back_home: "العودة للرئيسية",
|
||||||
|
rate_services: "قيم خدماتنا",
|
||||||
|
service_subtitle: "كيف كانت تجربتك العامة معنا؟",
|
||||||
|
or_rate_staff: "أو قيم موظفينا",
|
||||||
|
no_staff: "لا يوجد موظفون متاحون للتقييم حالياً.",
|
||||||
|
rate: "تقييم",
|
||||||
|
rate_staff_subtitle: "قيم الخدمة المقدمة من قبل هذا الموظف.",
|
||||||
|
rate_service_subtitle: "نود معرفة رأيك في أدائنا العام.",
|
||||||
|
comments_label: "أي تعليقات إضافية؟",
|
||||||
|
comment_placeholder: "أخبرنا عن تجربتك...",
|
||||||
|
improve_label: "ما الذي يمكننا تحسينه؟",
|
||||||
|
specific_feedback: "أي ملاحظات محددة لـ {name}؟",
|
||||||
|
cancel: "إلغاء",
|
||||||
|
submit: "إرسال التقييم",
|
||||||
|
lang_btn: "English",
|
||||||
|
our_services: "خدماتنا"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let currentLang = localStorage.getItem('rate_lang') || 'en';
|
||||||
|
let currentStaffName = { en: '', ar: '' };
|
||||||
|
let currentMode = 'list'; // 'list' or 'form'
|
||||||
|
let currentRatingType = 'staff';
|
||||||
|
|
||||||
|
function updateUI() {
|
||||||
|
const t = translations[currentLang];
|
||||||
|
document.body.classList.toggle('rtl', currentLang === 'ar');
|
||||||
|
document.getElementById('lang-btn-text').innerText = t.lang_btn;
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-t]').forEach(el => {
|
||||||
|
const key = el.getAttribute('data-t');
|
||||||
|
if (t[key]) el.innerText = t[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-tp]').forEach(el => {
|
||||||
|
const key = el.getAttribute('data-tp');
|
||||||
|
if (t[key]) el.placeholder = t[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentMode === 'form') {
|
||||||
|
if (currentRatingType === 'service') {
|
||||||
|
document.getElementById('staff-display-name').innerText = t.our_services;
|
||||||
|
document.getElementById('rating-subtitle').innerText = t.rate_service_subtitle;
|
||||||
|
document.getElementById('comment-label').innerText = t.improve_label;
|
||||||
|
} else {
|
||||||
|
const name = currentLang === 'ar' ? currentStaffName.ar : currentStaffName.en;
|
||||||
|
document.getElementById('staff-display-name').innerText = name;
|
||||||
|
document.getElementById('rating-subtitle').innerText = t.rate_staff_subtitle;
|
||||||
|
document.getElementById('comment-label').innerText = t.specific_feedback.replace('{name}', name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleLanguage() {
|
||||||
|
currentLang = currentLang === 'en' ? 'ar' : 'en';
|
||||||
|
localStorage.setItem('rate_lang', currentLang);
|
||||||
|
updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
function selectService() {
|
function selectService() {
|
||||||
|
currentMode = 'form';
|
||||||
|
currentRatingType = 'service';
|
||||||
|
|
||||||
// Hide staff list
|
// Hide staff list
|
||||||
document.getElementById('staff-list').style.display = 'none';
|
document.getElementById('staff-list').style.display = 'none';
|
||||||
document.getElementById('main-instruction').style.display = 'none';
|
document.getElementById('main-instruction').style.display = 'none';
|
||||||
@ -326,19 +451,18 @@ function selectService() {
|
|||||||
document.getElementById('rating-type').value = 'service';
|
document.getElementById('rating-type').value = 'service';
|
||||||
document.getElementById('selected-user-id').value = '';
|
document.getElementById('selected-user-id').value = '';
|
||||||
|
|
||||||
// Set labels
|
|
||||||
document.getElementById('staff-display-name').innerText = 'Our Services';
|
|
||||||
document.getElementById('rating-subtitle').innerText = 'We would love to hear how we are doing overall.';
|
|
||||||
document.getElementById('comment-label').innerText = 'What can we improve?';
|
|
||||||
|
|
||||||
// Show rating form
|
// Show rating form
|
||||||
document.getElementById('rating-form').style.display = 'block';
|
document.getElementById('rating-form').style.display = 'block';
|
||||||
|
|
||||||
// Smooth scroll to form
|
updateUI();
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectStaff(id, name, element) {
|
function selectStaff(id, nameEn, nameAr, element) {
|
||||||
|
currentMode = 'form';
|
||||||
|
currentRatingType = 'staff';
|
||||||
|
currentStaffName = { en: nameEn, ar: nameAr };
|
||||||
|
|
||||||
// Hide staff list
|
// Hide staff list
|
||||||
document.getElementById('staff-list').style.display = 'none';
|
document.getElementById('staff-list').style.display = 'none';
|
||||||
document.getElementById('main-instruction').style.display = 'none';
|
document.getElementById('main-instruction').style.display = 'none';
|
||||||
@ -347,19 +471,15 @@ function selectStaff(id, name, element) {
|
|||||||
document.getElementById('rating-type').value = 'staff';
|
document.getElementById('rating-type').value = 'staff';
|
||||||
document.getElementById('selected-user-id').value = id;
|
document.getElementById('selected-user-id').value = id;
|
||||||
|
|
||||||
// Set labels
|
|
||||||
document.getElementById('staff-display-name').innerText = name;
|
|
||||||
document.getElementById('rating-subtitle').innerText = 'Rate the service provided by this staff member.';
|
|
||||||
document.getElementById('comment-label').innerText = 'Any specific feedback for ' + name + '?';
|
|
||||||
|
|
||||||
// Show rating form
|
// Show rating form
|
||||||
document.getElementById('rating-form').style.display = 'block';
|
document.getElementById('rating-form').style.display = 'block';
|
||||||
|
|
||||||
// Smooth scroll to form
|
updateUI();
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelSelection() {
|
function cancelSelection() {
|
||||||
|
currentMode = 'list';
|
||||||
document.getElementById('rating-form').style.display = 'none';
|
document.getElementById('rating-form').style.display = 'none';
|
||||||
document.getElementById('staff-list').style.display = 'flex';
|
document.getElementById('staff-list').style.display = 'flex';
|
||||||
document.getElementById('main-instruction').style.display = 'block';
|
document.getElementById('main-instruction').style.display = 'block';
|
||||||
@ -368,7 +488,12 @@ function cancelSelection() {
|
|||||||
document.getElementById('comment').value = '';
|
document.getElementById('comment').value = '';
|
||||||
const radios = document.getElementsByName('rating');
|
const radios = document.getElementsByName('rating');
|
||||||
for(let i=0; i<radios.length; i++) radios[i].checked = false;
|
for(let i=0; i<radios.length; i++) radios[i].checked = false;
|
||||||
|
|
||||||
|
updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initial UI update
|
||||||
|
updateUI();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user