@@ -181,8 +195,17 @@ $effective_base_price = get_product_price($product);
@@ -209,17 +232,39 @@ $effective_base_price = get_product_price($product);
var button = event.relatedTarget;
var id = button.getAttribute('data-id');
var name = button.getAttribute('data-name');
+ var nameAr = button.getAttribute('data-name-ar');
var price = button.getAttribute('data-price');
var modalIdInput = editVariantModal.querySelector('#edit_variant_id');
var modalNameInput = editVariantModal.querySelector('#edit_variant_name');
+ var modalNameArInput = editVariantModal.querySelector('#edit_variant_name_ar');
var modalPriceInput = editVariantModal.querySelector('#edit_variant_price');
modalIdInput.value = id;
modalNameInput.value = name;
+ modalNameArInput.value = nameAr;
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);
+ }
+ }
\ No newline at end of file
diff --git a/admin/reports.php b/admin/reports.php
index d2dbd2f..01edd39 100644
--- a/admin/reports.php
+++ b/admin/reports.php
@@ -14,7 +14,7 @@ $endDate = $_GET['end_date'] ?? date('Y-m-d');
$outletId = $_GET['outlet_id'] ?? '';
// 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();
// Base query additions
@@ -31,6 +31,7 @@ if (!empty($outletId)) {
$staffStmt = $pdo->prepare("
SELECT
u.full_name as staff_name,
+ u.full_name_ar as staff_name_ar,
u.username,
COUNT(o.id) as order_count,
SUM(o.total_amount) as total_sales
@@ -48,6 +49,7 @@ $staffSales = $staffStmt->fetchAll();
$outletStmt = $pdo->prepare("
SELECT
ot.name as outlet_name,
+ ot.name_ar as outlet_name_ar,
COUNT(o.id) as order_count,
SUM(o.total_amount) as total_sales
FROM orders o
@@ -64,6 +66,7 @@ $outletSales = $outletStmt->fetchAll();
$categoryStmt = $pdo->prepare("
SELECT
c.name as category_name,
+ c.name_ar as category_name_ar,
SUM(oi.quantity) as items_sold,
SUM(oi.quantity * oi.unit_price) as total_sales
FROM order_items oi
@@ -82,6 +85,7 @@ $categorySales = $categoryStmt->fetchAll();
$expenseCatStmt = $pdo->prepare("
SELECT
ec.name as category_name,
+ ec.name_ar as category_name_ar,
SUM(e.amount) as total_amount
FROM expenses e
JOIN expense_categories ec ON e.category_id = ec.id
@@ -129,7 +133,7 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
@@ -236,6 +240,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
= htmlspecialchars($staff['staff_name'] ?: $staff['username']) ?>
+
+ = htmlspecialchars($staff['staff_name_ar']) ?>
+
|
= $staff['order_count'] ?> |
= format_currency($staff['total_sales']) ?> |
@@ -273,6 +280,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
= htmlspecialchars($outlet['outlet_name']) ?>
+
+ = htmlspecialchars($outlet['outlet_name_ar']) ?>
+
|
= $outlet['order_count'] ?> |
= format_currency($outlet['total_sales']) ?> |
@@ -310,6 +320,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
= htmlspecialchars($cat['category_name']) ?>
+
+ = htmlspecialchars($cat['category_name_ar']) ?>
+
|
= $cat['items_sold'] ?> |
= format_currency($cat['total_sales']) ?> |
@@ -346,6 +359,9 @@ $netProfit = ($summary['total_revenue'] ?? 0) - $totalExpenses;
|
= htmlspecialchars($exp['category_name']) ?>
+
+ = htmlspecialchars($exp['category_name_ar']) ?>
+
|
= format_currency($exp['total_amount']) ?> |
diff --git a/admin/users.php b/admin/users.php
index fd4dadd..a48d9de 100644
--- a/admin/users.php
+++ b/admin/users.php
@@ -11,6 +11,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
$username = trim($_POST['username']);
$full_name = trim($_POST['full_name']);
+ $full_name_ar = trim($_POST['full_name_ar'] ?? '');
$email = trim($_POST['email']);
$group_id = (int)$_POST['group_id'];
$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')) {
$message = '
Access Denied: You do not have permission to edit users.
';
} else {
- $sql = "UPDATE users SET username = ?, full_name = ?, 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];
+ $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, $full_name_ar, $email, $group_id, $is_active, $is_ratable, $profile_pic, $id];
if (!empty($_POST['password'])) {
$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 = ?";
- $params = [$username, $full_name, $email, $group_id, $is_active, $is_ratable, $profile_pic, $password, $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, $full_name_ar, $email, $group_id, $is_active, $is_ratable, $profile_pic, $password, $id];
}
$stmt = $pdo->prepare($sql);
@@ -63,8 +64,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$message = '
Access Denied: You do not have permission to add users.
';
} else {
$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->execute([$username, $password, $full_name, $email, $group_id, $is_active, $is_ratable, $profile_pic]);
+ $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, $full_name_ar, $email, $group_id, $is_active, $is_ratable, $profile_pic]);
$message = '
User created successfully!
';
}
}
@@ -132,6 +133,7 @@ include 'includes/header.php';
| User |
+ Arabic Name |
Email |
Role / Group |
Status |
@@ -155,6 +157,7 @@ include 'includes/header.php';
+ = htmlspecialchars($user['full_name_ar'] ?: '-') ?> |
= htmlspecialchars($user['email'] ?: '-') ?> |
= htmlspecialchars($user['group_name'] ?: 'None') ?> |
@@ -189,7 +192,7 @@ include 'includes/header.php';
|
- | No users found. |
+ No users found. |
@@ -223,7 +226,16 @@ include 'includes/header.php';
+
+
+
@@ -295,6 +307,7 @@ function prepareEditForm(user) {
document.getElementById('userAction').value = 'edit_user';
document.getElementById('userId').value = user.id;
document.getElementById('userFullName').value = user.full_name || '';
+ document.getElementById('userFullNameAr').value = user.full_name_ar || '';
document.getElementById('userUsername').value = user.username || '';
document.getElementById('userEmail').value = user.email || '';
document.getElementById('userGroupId').value = user.group_id || '';
@@ -312,7 +325,47 @@ function prepareEditForm(user) {
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 = '';
+
+ 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;
+ });
+});
-
+
\ No newline at end of file
diff --git a/db/migrations/031_add_name_ar_to_product_variants.sql b/db/migrations/031_add_name_ar_to_product_variants.sql
new file mode 100644
index 0000000..06b084e
--- /dev/null
+++ b/db/migrations/031_add_name_ar_to_product_variants.sql
@@ -0,0 +1,2 @@
+-- Add name_ar to product_variants
+ALTER TABLE product_variants ADD COLUMN name_ar VARCHAR(255) AFTER name;
diff --git a/db/migrations/032_add_full_name_ar_to_users.sql b/db/migrations/032_add_full_name_ar_to_users.sql
new file mode 100644
index 0000000..93f1a4d
--- /dev/null
+++ b/db/migrations/032_add_full_name_ar_to_users.sql
@@ -0,0 +1,2 @@
+-- Add full_name_ar to users table
+ALTER TABLE users ADD COLUMN full_name_ar VARCHAR(255) AFTER full_name;
diff --git a/db/migrations/033_add_name_ar_to_outlets_and_expenses.sql b/db/migrations/033_add_name_ar_to_outlets_and_expenses.sql
new file mode 100644
index 0000000..fbad9e2
--- /dev/null
+++ b/db/migrations/033_add_name_ar_to_outlets_and_expenses.sql
@@ -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;
diff --git a/qorder.php b/qorder.php
index a27a52b..e37500b 100644
--- a/qorder.php
+++ b/qorder.php
@@ -29,7 +29,7 @@ if (!$table_info) {
$outlet_id = (int)$table_info['outlet_id'];
$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
$variants_raw = $pdo->query("SELECT * FROM product_variants ORDER BY price_adjustment ASC")->fetchAll();
@@ -50,22 +50,46 @@ foreach ($variants_raw as $v) {
-
+
-
+
@@ -75,14 +99,27 @@ foreach ($variants_raw as $v) {
= htmlspecialchars($settings['company_name']) ?>
-
Table = htmlspecialchars($table_info['table_name']) ?>
+
+
AR
+
Table = htmlspecialchars($table_info['table_name']) ?>
+
-
All
+
+ All
+ الكل
+
-
= htmlspecialchars($cat['name']) ?>
+
+ = htmlspecialchars($cat['name']) ?>
+
+ = htmlspecialchars($cat['name_ar']) ?>
+
+ = htmlspecialchars($cat['name']) ?>
+
+
@@ -98,6 +135,7 @@ foreach ($variants_raw as $v) {
onclick="handleProductClick(= htmlspecialchars(json_encode([
'id' => $product['id'],
'name' => $product['name'],
+ 'name_ar' => $product['name_ar'] ?? $product['name'],
'price' => (float)$effective_price,
'has_variants' => $has_variants
])) ?>)">
@@ -110,7 +148,7 @@ foreach ($variants_raw as $v) {
= number_format((float)$product['price'], 3) ?>
- OMR
+
OMR
@@ -119,8 +157,14 @@ foreach ($variants_raw as $v) {
-
= htmlspecialchars($product['name']) ?>
-
= htmlspecialchars($product['category_name']) ?>
+
+ = htmlspecialchars($product['name']) ?>
+ = htmlspecialchars($product['name_ar'] ?? $product['name']) ?>
+
+
+ = htmlspecialchars($product['category_name']) ?>
+ = htmlspecialchars($product['category_name_ar'] ?? $product['category_name']) ?>
+
@@ -132,11 +176,11 @@ foreach ($variants_raw as $v) {
@@ -146,7 +190,7 @@ foreach ($variants_raw as $v) {
@@ -155,21 +199,21 @@ foreach ($variants_raw as $v) {
- Subtotal
+ Subtotal
0.000 OMR
- Total
+ Total
0.000 OMR
@@ -182,7 +226,7 @@ foreach ($variants_raw as $v) {
@@ -202,9 +246,83 @@ foreach ($variants_raw as $v) {
const PRODUCT_VARIANTS = = json_encode($variants_by_product) ?>;
let cart = [];
+ let currentLang = localStorage.getItem('qorder_lang') || 'en';
const cartModal = new bootstrap.Modal(document.getElementById('cartModal'));
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) {
document.querySelectorAll('.category-item').forEach(i => i.classList.remove('active'));
el.classList.add('active');
@@ -222,14 +340,14 @@ foreach ($variants_raw as $v) {
if (product.has_variants) {
showVariants(product);
} else {
- addToCart(product.id, product.name, product.price);
+ addToCart(product.id, currentLang === 'ar' ? product.name_ar : product.name, product.price);
}
}
function showVariants(product) {
const variants = PRODUCT_VARIANTS[product.id] || [];
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 = '';
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';
const adj = parseFloat(v.price_adjustment);
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 = `
-
${v.name}
-
${adj > 0 ? '+' : ''}${adj.toFixed(3)} OMR
+
${vName}
+
${adj > 0 ? '+' : ''}${adj.toFixed(3)} ${translations[currentLang].currency}
-
${finalPrice.toFixed(3)} OMR
+
${finalPrice.toFixed(3)} ${translations[currentLang].currency}
`;
btn.onclick = () => {
- addToCart(product.id, `${product.name} (${v.name})`, finalPrice, v.id);
+ addToCart(product.id, `${pName} (${vName})`, finalPrice, v.id);
variantModal.hide();
};
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 });
}
updateCartUI();
- showToast(name + ' added to cart');
+ showToast(name + ' ' + translations[currentLang].added_to_cart);
}
function updateCartUI() {
const total = cart.reduce((sum, item) => sum + (item.unit_price * 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-total-display').textContent = total.toFixed(3) + ' OMR';
+ document.getElementById('cart-items-count').textContent = count;
+ document.getElementById('cart-total-display').textContent = total.toFixed(3) + ' ' + currency;
const footer = document.getElementById('cart-footer');
if (count > 0) {
@@ -282,6 +404,7 @@ foreach ($variants_raw as $v) {
function showCart() {
const list = document.getElementById('cart-list');
list.innerHTML = '';
+ const currency = translations[currentLang].currency;
cart.forEach((item, index) => {
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);
- document.getElementById('modal-subtotal').textContent = total.toFixed(3) + ' OMR';
- document.getElementById('modal-total').textContent = total.toFixed(3) + ' OMR';
+ document.getElementById('modal-subtotal').textContent = total.toFixed(3) + ' ' + currency;
+ document.getElementById('modal-total').textContent = total.toFixed(3) + ' ' + currency;
cartModal.show();
}
@@ -328,19 +451,19 @@ foreach ($variants_raw as $v) {
const btn = document.getElementById('btn-place-order');
btn.disabled = true;
- btn.innerHTML = '
Placing Order...';
+ btn.innerHTML = `
${translations[currentLang].placing_order}`;
const total = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);
const customerName = document.getElementById('cust-name').value;
const payload = {
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',
customer_name: customerName,
items: cart,
total_amount: total,
- payment_type_id: null // Unpaid
+ payment_type_id: null
};
fetch('api/order.php', {
@@ -352,10 +475,10 @@ foreach ($variants_raw as $v) {
.then(data => {
if (data.success) {
Swal.fire({
- title: 'Order Placed!',
- text: 'Your order has been sent to the kitchen. Thank you!',
+ title: translations[currentLang].order_placed,
+ text: translations[currentLang].order_success_msg,
icon: 'success',
- confirmButtonText: 'Great!'
+ confirmButtonText: currentLang === 'ar' ? 'ممتاز' : 'Great!'
}).then(() => {
cart = [];
updateCartUI();
@@ -371,13 +494,22 @@ foreach ($variants_raw as $v) {
})
.finally(() => {
btn.disabled = false;
- btn.innerHTML = 'Place Order
';
+ btn.innerHTML = `${translations[currentLang].place_order}
`;
});
}
function showToast(msg) {
- // Simple alert for now, or use a toast
- console.log(msg);
+ const Toast = Swal.mixin({
+ toast: true,
+ position: 'top-end',
+ showConfirmButton: false,
+ timer: 2000,
+ timerProgressBar: true
+ });
+ Toast.fire({
+ icon: 'success',
+ title: msg
+ });
}
diff --git a/rate.php b/rate.php
index 3d52460..7b2b416 100644
--- a/rate.php
+++ b/rate.php
@@ -39,7 +39,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Fetch active and ratable users with pictures
$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);
?>
@@ -50,7 +50,7 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
Rate Our Service - = htmlspecialchars($companyName) ?>
-
+
@@ -219,21 +245,27 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
Thank You!
-
Your rating has been submitted successfully.
-
Back to Home
+
Thank You!
+
Your rating has been submitted successfully.
+
Back to Home
@@ -251,23 +283,23 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
Rate Our Services
-
How was your overall experience with us?
+
Rate Our Services
+
How was your overall experience with us?
-
OR RATE OUR STAFF
+ OR RATE OUR STAFF
-
No staff members are currently available for rating.
+
No staff members are currently available for rating.
-
+
![<?= htmlspecialchars($user['full_name']) ?>](<?= htmlspecialchars($user['profile_pic']) ?>)
@@ -275,7 +307,12 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
= strtoupper(substr($user['full_name'] ?: $user['username'], 0, 1)) ?>
-
= htmlspecialchars($user['full_name'] ?: $user['username']) ?>
+
+ = htmlspecialchars($user['full_name'] ?: $user['username']) ?>
+
+ = htmlspecialchars($user['full_name_ar']) ?>
+
+
@@ -287,7 +324,7 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
Rate
+
Rate
@@ -300,16 +337,16 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
-
+
+
-
+
-
+
@@ -317,7 +354,95 @@ $users = $stmt->fetchAll(PDO::FETCH_ASSOC);