update items
This commit is contained in:
parent
a7d442be5d
commit
35d8fe23f8
452
items.php
452
items.php
@ -1,205 +1,38 @@
|
||||
<?php
|
||||
// ACTION HANDLING FIRST (to allow redirects)
|
||||
ob_start();
|
||||
session_start();
|
||||
|
||||
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
||||
$isAjax = isset($_POST['ajax']) || isset($_GET['ajax']) || (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
|
||||
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/includes/lang.php';
|
||||
|
||||
$isAjax = isset($_POST['ajax']) || (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => false, 'error' => 'Unauthorized']);
|
||||
exit;
|
||||
}
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Initial view check
|
||||
if (!has_permission('view')) {
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => false, 'error' => 'Forbidden']);
|
||||
exit;
|
||||
}
|
||||
header('Location: admin.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$branch_id = $_SESSION['branch_id'];
|
||||
|
||||
function handleImageUpload($file) {
|
||||
if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$targetDir = "assets/images/items/";
|
||||
if (!is_dir($targetDir)) {
|
||||
mkdir($targetDir, 0775, true);
|
||||
}
|
||||
|
||||
$fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
$newFileName = uniqid('item_', true) . '.' . $fileExtension;
|
||||
$targetFile = $targetDir . $newFileName;
|
||||
|
||||
// Check if image file is a actual image or fake image
|
||||
$check = getimagesize($file['tmp_name']);
|
||||
if($check === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Allow certain file formats
|
||||
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
|
||||
if (!in_array($fileExtension, $allowedExtensions)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (move_uploaded_file($file['tmp_name'], $targetFile)) {
|
||||
return $targetFile;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function deleteOldImage($imageUrl) {
|
||||
if ($imageUrl && strpos($imageUrl, 'assets/images/items/') === 0) {
|
||||
if (file_exists($imageUrl)) {
|
||||
unlink($imageUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to render category list HTML for AJAX
|
||||
function renderCategoryList($lang) {
|
||||
$categories = db()->query("SELECT * FROM categories ORDER BY name_en ASC")->fetchAll();
|
||||
$html = '';
|
||||
foreach($categories as $cat) {
|
||||
$html .= '<tr>
|
||||
<td>
|
||||
<strong>' . htmlspecialchars($cat['name_en']) . '</strong><br>
|
||||
<small class="text-muted">' . htmlspecialchars($cat['name_ar']) . '</small>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
';
|
||||
if (has_permission('edit')) {
|
||||
$html .= '<button type="button" class="btn btn-sm btn-light p-2 me-1" style="border-radius: 8px;" onclick="editCategory(' . htmlspecialchars(json_encode($cat), ENT_QUOTES) . ')">
|
||||
<i class="bi bi-pencil text-primary"></i>
|
||||
</button>';
|
||||
}
|
||||
if (has_permission('delete')) {
|
||||
$html .= '<button type="button" class="btn btn-sm btn-light p-2" style="border-radius: 8px;" onclick="confirmDeleteAjax(\'category\', ' . $cat['id'] . ')">
|
||||
<i class="bi bi-trash text-danger"></i>
|
||||
</button>';
|
||||
}
|
||||
$html .= '</td></tr>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Helper to render service list HTML for AJAX
|
||||
function renderServiceList($lang) {
|
||||
$services = db()->query("SELECT * FROM services ORDER BY name_en ASC")->fetchAll();
|
||||
$html = '';
|
||||
foreach($services as $svc) {
|
||||
$html .= '<tr>
|
||||
<td>
|
||||
<strong>' . htmlspecialchars($svc['name_en']) . '</strong><br>
|
||||
<small class="text-muted">' . htmlspecialchars($svc['name_ar']) . '</small>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
';
|
||||
if (has_permission('edit')) {
|
||||
$html .= '<button type="button" class="btn btn-sm btn-light p-2 me-1" style="border-radius: 8px;" onclick="editService(' . htmlspecialchars(json_encode($svc), ENT_QUOTES) . ')">
|
||||
<i class="bi bi-pencil text-primary"></i>
|
||||
</button>';
|
||||
}
|
||||
if (has_permission('delete')) {
|
||||
$html .= '<button type="button" class="btn btn-sm btn-light p-2" style="border-radius: 8px;" onclick="confirmDeleteAjax(\'service\', ' . $svc['id'] . ')">
|
||||
<i class="bi bi-trash text-danger"></i>
|
||||
</button>';
|
||||
}
|
||||
$html .= '</td></tr>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Handle Actions
|
||||
// Action handling
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
$action = $_POST['action'];
|
||||
|
||||
// Permission mapping for actions
|
||||
$required_permission = 'view';
|
||||
if (strpos($action, 'add_') === 0) $required_permission = 'add';
|
||||
if (strpos($action, 'edit_') === 0 || strpos($action, 'update_') === 0) $required_permission = 'edit';
|
||||
if (strpos($action, 'delete_') === 0) $required_permission = 'delete';
|
||||
|
||||
if (!has_permission($required_permission)) {
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => false, 'error' => 'Forbidden']);
|
||||
exit;
|
||||
}
|
||||
header('Location: items.php?error=no_permission');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'add_item') {
|
||||
$name_en = $_POST['name_en'];
|
||||
$name_ar = $_POST['name_ar'];
|
||||
$category_id = $_POST['category_id'] ?: null;
|
||||
$vat_percent = $_POST['vat_percent'] ?: 0.00;
|
||||
|
||||
$image_url = handleImageUpload($_FILES['image'] ?? null);
|
||||
|
||||
$stmt = db()->prepare("INSERT INTO items (category_id, name_en, name_ar, image_url, vat_percent) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$category_id, $name_en, $name_ar, $image_url, $vat_percent]);
|
||||
header('Location: items.php?success=item_added');
|
||||
exit;
|
||||
} elseif ($action === 'edit_item') {
|
||||
$id = $_POST['id'];
|
||||
$name_en = $_POST['name_en'];
|
||||
$name_ar = $_POST['name_ar'];
|
||||
$category_id = $_POST['category_id'] ?: null;
|
||||
$vat_percent = $_POST['vat_percent'] ?: 0.00;
|
||||
|
||||
// Get current image to delete it if new one is uploaded
|
||||
$stmt = db()->prepare("SELECT image_url FROM items WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$currentItem = $stmt->fetch();
|
||||
$image_url = $currentItem['image_url'] ?? null;
|
||||
|
||||
$new_image = handleImageUpload($_FILES['image'] ?? null);
|
||||
if ($new_image) {
|
||||
deleteOldImage($image_url);
|
||||
$image_url = $new_image;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare("UPDATE items SET category_id = ?, name_en = ?, name_ar = ?, image_url = ?, vat_percent = ? WHERE id = ?");
|
||||
$stmt->execute([$category_id, $name_en, $name_ar, $image_url, $vat_percent, $id]);
|
||||
header('Location: items.php?success=item_updated');
|
||||
exit;
|
||||
} elseif ($action === 'delete_item') {
|
||||
$id = $_POST['id'];
|
||||
|
||||
// Delete image file if exists
|
||||
$stmt = db()->prepare("SELECT image_url FROM items WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$item = $stmt->fetch();
|
||||
deleteOldImage($item['image_url'] ?? null);
|
||||
|
||||
$stmt = db()->prepare("DELETE FROM items WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
header('Location: items.php?success=item_deleted');
|
||||
exit;
|
||||
} elseif ($action === 'add_category') {
|
||||
if ($action === 'add_category') {
|
||||
$name_en = $_POST['cat_name_en'];
|
||||
$name_ar = $_POST['cat_name_ar'];
|
||||
$stmt = db()->prepare("INSERT INTO categories (name_en, name_ar) VALUES (?, ?)");
|
||||
$stmt->execute([$name_en, $name_ar]);
|
||||
|
||||
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => true, 'html' => renderCategoryList($lang)]);
|
||||
$categories = db()->query("SELECT * FROM categories ORDER BY name_en ASC")->fetchAll();
|
||||
ob_start();
|
||||
foreach($categories as $cat): ?>
|
||||
<tr>
|
||||
<td><?= $cat['name_en'] ?></td>
|
||||
<td><?= $cat['name_ar'] ?></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light p-1 me-1" onclick='editCategory(<?= json_encode($cat) ?>)'><i class="bi bi-pencil text-primary"></i></button>
|
||||
<button class="btn btn-sm btn-light p-1" onclick="confirmDeleteAjax('category', <?= $cat['id'] ?>)"><i class="bi bi-trash text-danger"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;
|
||||
$html = ob_get_clean();
|
||||
echo json_encode(['success' => true, 'html' => $html]);
|
||||
exit;
|
||||
}
|
||||
header('Location: items.php?success=category_added');
|
||||
@ -213,7 +46,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => true, 'html' => renderCategoryList($lang)]);
|
||||
$categories = db()->query("SELECT * FROM categories ORDER BY name_en ASC")->fetchAll();
|
||||
ob_start();
|
||||
foreach($categories as $cat): ?>
|
||||
<tr>
|
||||
<td><?= $cat['name_en'] ?></td>
|
||||
<td><?= $cat['name_ar'] ?></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light p-1 me-1" onclick='editCategory(<?= json_encode($cat) ?>)'><i class="bi bi-pencil text-primary"></i></button>
|
||||
<button class="btn btn-sm btn-light p-1" onclick="confirmDeleteAjax('category', <?= $cat['id'] ?>)"><i class="bi bi-trash text-danger"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;
|
||||
$html = ob_get_clean();
|
||||
echo json_encode(['success' => true, 'html' => $html]);
|
||||
exit;
|
||||
}
|
||||
header('Location: items.php?success=category_updated');
|
||||
@ -225,11 +71,78 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['success' => true, 'html' => renderCategoryList($lang)]);
|
||||
$categories = db()->query("SELECT * FROM categories ORDER BY name_en ASC")->fetchAll();
|
||||
ob_start();
|
||||
foreach($categories as $cat): ?>
|
||||
<tr>
|
||||
<td><?= $cat['name_en'] ?></td>
|
||||
<td><?= $cat['name_ar'] ?></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light p-1 me-1" onclick='editCategory(<?= json_encode($cat) ?>)'><i class="bi bi-pencil text-primary"></i></button>
|
||||
<button class="btn btn-sm btn-light p-1" onclick="confirmDeleteAjax('category', <?= $cat['id'] ?>)"><i class="bi bi-trash text-danger"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;
|
||||
$html = ob_get_clean();
|
||||
echo json_encode(['success' => true, 'html' => $html]);
|
||||
exit;
|
||||
}
|
||||
header('Location: items.php?success=category_deleted');
|
||||
exit;
|
||||
} elseif ($action === 'add_item') {
|
||||
$category_id = $_POST['category_id'] ?: null;
|
||||
$name_en = $_POST['name_en'];
|
||||
$name_ar = $_POST['name_ar'];
|
||||
$vat_percent = $_POST['vat_percent'] ?: 0;
|
||||
|
||||
$image_url = null;
|
||||
if (isset($_FILES['image']) && $_FILES['image']['error'] === 0) {
|
||||
$ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
|
||||
$filename = 'item_' . uniqid('', true) . '.' . $ext;
|
||||
$upload_dir = __DIR__ . '/assets/images/items/';
|
||||
if (!is_dir($upload_dir)) mkdir($upload_dir, 0777, true);
|
||||
if (move_uploaded_file($_FILES['image']['tmp_name'], $upload_dir . $filename)) {
|
||||
$image_url = 'assets/images/items/' . $filename;
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = db()->prepare("INSERT INTO items (category_id, name_en, name_ar, vat_percent, image_url) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$category_id, $name_en, $name_ar, $vat_percent, $image_url]);
|
||||
header('Location: items.php?success=item_added');
|
||||
exit;
|
||||
} elseif ($action === 'edit_item') {
|
||||
$id = $_POST['id'];
|
||||
$category_id = $_POST['category_id'] ?: null;
|
||||
$name_en = $_POST['name_en'];
|
||||
$name_ar = $_POST['name_ar'];
|
||||
$vat_percent = $_POST['vat_percent'] ?: 0;
|
||||
|
||||
$image_url = null;
|
||||
if (isset($_FILES['image']) && $_FILES['image']['error'] === 0) {
|
||||
$ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
|
||||
$filename = 'item_' . uniqid('', true) . '.' . $ext;
|
||||
$upload_dir = __DIR__ . '/assets/images/items/';
|
||||
if (!is_dir($upload_dir)) mkdir($upload_dir, 0777, true);
|
||||
if (move_uploaded_file($_FILES['image']['tmp_name'], $upload_dir . $filename)) {
|
||||
$image_url = 'assets/images/items/' . $filename;
|
||||
}
|
||||
}
|
||||
|
||||
if ($image_url) {
|
||||
$stmt = db()->prepare("UPDATE items SET category_id = ?, name_en = ?, name_ar = ?, vat_percent = ?, image_url = ? WHERE id = ?");
|
||||
$stmt->execute([$category_id, $name_en, $name_ar, $vat_percent, $image_url, $id]);
|
||||
} else {
|
||||
$stmt = db()->prepare("UPDATE items SET category_id = ?, name_en = ?, name_ar = ?, vat_percent = ? WHERE id = ?");
|
||||
$stmt->execute([$category_id, $name_en, $name_ar, $vat_percent, $id]);
|
||||
}
|
||||
header('Location: items.php?success=item_updated');
|
||||
exit;
|
||||
} elseif ($action === 'delete_item') {
|
||||
$id = $_POST['id'];
|
||||
$stmt = db()->prepare("DELETE FROM items WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
header('Location: items.php?success=item_deleted');
|
||||
exit;
|
||||
} elseif ($action === 'add_service') {
|
||||
$name_en = $_POST['svc_name_en'];
|
||||
$name_ar = $_POST['svc_name_ar'];
|
||||
@ -279,11 +192,29 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
$price = str_replace(',', '.', $price); // Handle comma as decimal separator
|
||||
$price = (float)$price;
|
||||
|
||||
// Determine branch_id from session (if available)
|
||||
$branch_id = $_SESSION['branch_id'] ?? null;
|
||||
if ($branch_id === 'all') $branch_id = null;
|
||||
|
||||
// Final sanity check for branch_id to avoid FK errors if session has stale ID
|
||||
if ($branch_id) {
|
||||
$chk = db()->prepare("SELECT id FROM branches WHERE id = ?");
|
||||
$chk->execute([$branch_id]);
|
||||
if (!$chk->fetch()) $branch_id = null;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = db()->prepare("INSERT INTO prices (item_id, service_id, price)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE price = ?");
|
||||
$stmt->execute([$item_id, $service_id, $price, $price]);
|
||||
if ($branch_id) {
|
||||
$stmt = db()->prepare("INSERT INTO prices (item_id, service_id, price, branch_id)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE price = ?");
|
||||
$stmt->execute([$item_id, $service_id, $price, $branch_id, $price]);
|
||||
} else {
|
||||
$stmt = db()->prepare("INSERT INTO prices (item_id, service_id, price)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE price = ?");
|
||||
$stmt->execute([$item_id, $service_id, $price, $price]);
|
||||
}
|
||||
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
@ -350,6 +281,22 @@ $prices = [];
|
||||
foreach ($prices_raw as $p) {
|
||||
$prices[$p['item_id']][$p['service_id']] = $p['price'];
|
||||
}
|
||||
|
||||
function renderServiceList($lang) {
|
||||
$services = db()->query("SELECT * FROM services ORDER BY name_en ASC")->fetchAll();
|
||||
ob_start();
|
||||
foreach($services as $svc): ?>
|
||||
<tr>
|
||||
<td><?= $svc['name_en'] ?></td>
|
||||
<td><?= $svc['name_ar'] ?></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light p-1 me-1" onclick='editService(<?= json_encode($svc) ?>)'><i class="bi bi-pencil text-primary"></i></button>
|
||||
<button class="btn btn-sm btn-light p-1" onclick="confirmDeleteAjax('service', <?= $svc['id'] ?>)"><i class="bi bi-trash text-danger"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;
|
||||
return ob_get_clean();
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
@ -558,15 +505,25 @@ foreach ($prices_raw as $p) {
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<div class="table-responsive" style="max-height: 400px; overflow-y: auto;">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="bg-light">
|
||||
<table class="table table-hover small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= __('name') ?></th>
|
||||
<th><?= __('name_en') ?></th>
|
||||
<th><?= __('name_ar') ?></th>
|
||||
<th class="text-end"><?= __('actions') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="categoryTableBody">
|
||||
<?= renderCategoryList($lang) ?>
|
||||
<?php foreach($categories as $cat): ?>
|
||||
<tr>
|
||||
<td><?= $cat['name_en'] ?></td>
|
||||
<td><?= $cat['name_ar'] ?></td>
|
||||
<td class="text-end">
|
||||
<button class="btn btn-sm btn-light p-1 me-1" onclick='editCategory(<?= json_encode($cat) ?>)'><i class="bi bi-pencil text-primary"></i></button>
|
||||
<button class="btn btn-sm btn-light p-1" onclick="confirmDeleteAjax('category', <?= $cat['id'] ?>)"><i class="bi bi-trash text-danger"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -621,10 +578,11 @@ foreach ($prices_raw as $p) {
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<div class="table-responsive" style="max-height: 400px; overflow-y: auto;">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="bg-light">
|
||||
<table class="table table-hover small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= __('name') ?></th>
|
||||
<th><?= __('name_en') ?></th>
|
||||
<th><?= __('name_ar') ?></th>
|
||||
<th class="text-end"><?= __('actions') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -641,80 +599,58 @@ foreach ($prices_raw as $p) {
|
||||
</div>
|
||||
|
||||
<!-- Pricing Modals -->
|
||||
<?php foreach($items as $item):
|
||||
?><div class="modal fade pricing-modal" id="pricingModal<?= $item['id'] ?>" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<?php foreach($items as $item): ?>
|
||||
<div class="modal fade" id="pricingModal<?= $item['id'] ?>" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content" style="border-radius: 25px;">
|
||||
<div class="modal-header border-0 p-4">
|
||||
<div>
|
||||
<h5 class="modal-title fw-bold m-0"><?= __('service_pricing') ?? 'Service Pricing' ?></h5>
|
||||
<p class="text-muted m-0 small"><?= $lang === 'ar' ? $item['name_ar'] : $item['name_en'] ?></p>
|
||||
</div>
|
||||
<h5 class="modal-title fw-bold">
|
||||
<?= __('set_prices_for') ?> <?= $lang === 'ar' ? $item['name_ar'] : $item['name_en'] ?>
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body p-4 pt-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="bg-light">
|
||||
<tr class="small text-muted">
|
||||
<th style="min-width: 200px;"><?= __('service') ?></th>
|
||||
<th class="text-center"><?= __('price') ?> (<?= currency() ?>)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($services as $service):
|
||||
?><tr>
|
||||
<td class="fw-bold">
|
||||
<?= $lang === 'ar' ? $service['name_ar'] : $service['name_en'] ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="input-group input-group-sm justify-content-center mx-auto" style="width: 150px; position: relative;">
|
||||
<input type="number" step="0.001" class="form-control text-center price-input"
|
||||
value="<?= number_format($prices[$item['id']][$service['id']] ?? 0, decimals(), '.', '') ?>"
|
||||
data-item-id="<?= $item['id'] ?>"
|
||||
data-service-id="<?= $service['id'] ?>"
|
||||
style="border-radius: 8px;"
|
||||
<?= !has_permission('edit') ? 'readonly disabled' : '' ?>>
|
||||
<span class="input-group-text bg-transparent border-0 d-none success-indicator" style="position: absolute; right: -25px; top: 5px;">
|
||||
<i class="bi bi-check-lg text-success"></i>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="alert alert-info py-2 small mt-3 mb-0" style="border-radius: 10px;">
|
||||
<i class="bi bi-info-circle me-2"></i>
|
||||
<?= has_permission('edit') ? 'Prices are saved automatically as you type.' : 'You can view prices but cannot edit them.' ?>
|
||||
<div class="alert alert-light small border-0 mb-4" style="border-radius: 15px;">
|
||||
<i class="bi bi-info-circle me-2"></i><?= __('prices_saved_automatically') ?>
|
||||
</div>
|
||||
|
||||
<?php foreach($services as $svc): ?>
|
||||
<div class="mb-3 d-flex align-items-center justify-content-between p-3 bg-light" style="border-radius: 15px;">
|
||||
<div class="fw-bold small">
|
||||
<?= $lang === 'ar' ? $svc['name_ar'] : $svc['name_en'] ?>
|
||||
</div>
|
||||
<div class="d-flex align-items-center" style="width: 150px;">
|
||||
<input type="number" step="0.001"
|
||||
class="form-control form-control-sm border-0 bg-white price-input"
|
||||
style="border-radius: 10px;"
|
||||
data-item-id="<?= $item['id'] ?>"
|
||||
data-service-id="<?= $svc['id'] ?>"
|
||||
value="<?= $prices[$item['id']][$svc['id']] ?? '' ?>"
|
||||
placeholder="0.000">
|
||||
<i class="bi bi-check-circle-fill text-success ms-2 success-indicator d-none"></i>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<button type="button" class="btn btn-dark w-100 py-3 fw-bold mt-3 shadow-sm" style="border-radius: 15px;" data-bs-dismiss="modal">
|
||||
<?= __('done') ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<!-- Delete Confirmation Form -->
|
||||
<form id="deleteForm" method="POST" style="display: none;">
|
||||
<form id="deleteForm" method="POST" class="d-none">
|
||||
<input type="hidden" name="action" id="deleteAction">
|
||||
<input type="hidden" name="id" id="deleteId">
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.bg-soft-primary { background-color: rgba(13, 110, 253, 0.1); }
|
||||
.price-input:focus {
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
.pricing-modal .table th { border-top: none; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
async function translateField(sourceId, targetId, direction) {
|
||||
const sourceEl = document.getElementById(sourceId);
|
||||
const targetEl = document.getElementById(targetId);
|
||||
const text = sourceEl.value.trim();
|
||||
const text = sourceEl.value;
|
||||
if (!text) return;
|
||||
const btn = event.currentTarget;
|
||||
const originalHtml = btn.innerHTML;
|
||||
@ -892,4 +828,4 @@ document.getElementById('itemImageFile').addEventListener('change', function(e)
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
Loading…
x
Reference in New Issue
Block a user