Autosave: 20260312-071130

This commit is contained in:
Flatlogic Bot 2026-03-12 07:11:31 +00:00
parent cc73fe5d8d
commit d82e9249b7
8 changed files with 643 additions and 147 deletions

View File

@ -34,6 +34,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else {
$error = "حدث خطأ أثناء إضافة القيد.";
}
} elseif (isset($_POST['edit_entry'])) {
$id_to_edit = (int)$_POST['edit_id'];
$date = $_POST["date"] ?? "";
$description = $_POST["description"] ?? "";
$reference = $_POST["reference"] ?? "";
$entries = [
["account" => $_POST["debit_account"] ?? "", "debit" => (float)($_POST["amount"] ?? 0), "credit" => 0],
["account" => $_POST["credit_account"] ?? "", "debit" => 0, "credit" => (float)($_POST["amount"] ?? 0)]
];
if (edit_journal_entry($id_to_edit, $date, $description, $reference, $entries)) {
$message = "تم تعديل القيد بنجاح.";
} else {
$error = "حدث خطأ أثناء تعديل القيد.";
}
} elseif (isset($_POST['delete_entry'])) {
$id_to_delete = (int)$_POST['delete_id'];
if (delete_journal_entry($id_to_delete)) {
@ -74,9 +89,6 @@ $ledger = array_slice($ledger_all, $offset, $limit);
<i class="fas fa-plus"></i> إضافة قيد جديد
</button>
</div>
<?php if (isset($message)) echo "<div class='alert alert-success'>$message</div>"; ?>
<?php if (isset($error)) echo "<div class='alert alert-danger'>$error</div>"; ?>
<!-- Filter Form -->
<div class="card mb-4 shadow-sm">
@ -99,7 +111,7 @@ $ledger = array_slice($ledger_all, $offset, $limit);
</div>
</div>
<!-- Journal Modal -->
<!-- Journal Modal (Add) -->
<div class="modal fade" id="journalModal" tabindex="-1" aria-labelledby="journalModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
@ -128,6 +140,7 @@ $ledger = array_slice($ledger_all, $offset, $limit);
<div class="col-md-4 mb-3">
<label>حساب المدين</label>
<select name="debit_account" class="form-select accountSelect" required style="width: 100%;">
<option value="" disabled selected>اختر الحساب...</option>
<?php foreach (get_all_accounts() as $acc): ?>
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
<?php endforeach; ?>
@ -136,6 +149,7 @@ $ledger = array_slice($ledger_all, $offset, $limit);
<div class="col-md-4 mb-3">
<label>حساب الدائن</label>
<select name="credit_account" class="form-select accountSelect" required style="width: 100%;">
<option value="" disabled selected>اختر الحساب...</option>
<?php foreach (get_all_accounts() as $acc): ?>
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
<?php endforeach; ?>
@ -155,6 +169,66 @@ $ledger = array_slice($ledger_all, $offset, $limit);
</div>
</div>
</div>
<!-- Edit Journal Modal -->
<div class="modal fade" id="editJournalModal" tabindex="-1" aria-labelledby="editJournalModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form method="POST">
<div class="modal-header">
<h5 class="modal-title" id="editJournalModalLabel">تعديل قيد محاسبي</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="hidden" name="edit_entry" value="1">
<input type="hidden" name="edit_id" id="edit_id" value="">
<div class="row">
<div class="col-md-6 mb-3">
<label>التاريخ</label>
<input type="date" name="date" id="edit_date" class="form-control" required>
</div>
<div class="col-md-6 mb-3">
<label>المرجع</label>
<input type="text" name="reference" id="edit_reference" class="form-control">
</div>
</div>
<div class="mb-3">
<label>الوصف</label>
<input type="text" name="description" id="edit_description" class="form-control" required>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label>حساب المدين</label>
<select name="debit_account" id="edit_debit_account" class="form-select accountSelectEdit" required style="width: 100%;">
<option value="" disabled>اختر الحساب...</option>
<?php foreach (get_all_accounts() as $acc): ?>
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4 mb-3">
<label>حساب الدائن</label>
<select name="credit_account" id="edit_credit_account" class="form-select accountSelectEdit" required style="width: 100%;">
<option value="" disabled>اختر الحساب...</option>
<?php foreach (get_all_accounts() as $acc): ?>
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4 mb-3">
<label>المبلغ</label>
<input type="number" step="0.01" name="amount" id="edit_amount" class="form-control" required min="0.01">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إغلاق</button>
<button type="submit" class="btn btn-primary">حفظ التعديلات</button>
</div>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
@ -172,12 +246,12 @@ $ledger = array_slice($ledger_all, $offset, $limit);
<td><?= number_format($row['debit'], 2) ?></td>
<td><?= number_format($row['credit'], 2) ?></td>
<td>
<button type="button" class="btn btn-sm btn-link text-warning p-0 me-2" title="تعديل" onclick="alert('ميزة تعديل القيود قيد التطوير.')"><i class="fas fa-edit"></i></button>
<button type="button" class="btn btn-sm btn-link text-warning p-0 me-2" title="تعديل" onclick="openEditModal(<?= $row['id'] ?>)"><i class="fas fa-edit"></i></button>
<form method="POST" class="d-inline" onsubmit="return confirm('هل أنت متأكد من حذف هذا القيد بشكل نهائي؟ (سيتم حذف القيد من جميع الحسابات المرتبطة)')">
<form method="POST" class="d-inline delete-form">
<input type="hidden" name="delete_entry" value="1">
<input type="hidden" name="delete_id" value="<?= htmlspecialchars($row['id']) ?>">
<button type="submit" class="btn btn-sm btn-link text-danger p-0" title="حذف">
<button type="button" class="btn btn-sm btn-link text-danger p-0 delete-btn" title="حذف">
<i class="fas fa-trash"></i>
</button>
</form>
@ -201,6 +275,7 @@ $ledger = array_slice($ledger_all, $offset, $limit);
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
@ -210,7 +285,90 @@ $(document).ready(function() {
dir: 'rtl',
dropdownParent: $('#journalModal')
});
$('.accountSelectEdit').select2({
theme: 'bootstrap-5',
dir: 'rtl',
dropdownParent: $('#editJournalModal')
});
<?php if (isset($message)): ?>
Swal.fire({
icon: 'success',
title: 'نجاح!',
text: '<?= addslashes($message) ?>',
confirmButtonColor: '#3085d6',
confirmButtonText: 'حسناً'
});
<?php endif; ?>
<?php if (isset($error)): ?>
Swal.fire({
icon: 'error',
title: 'خطأ!',
text: '<?= addslashes($error) ?>',
confirmButtonColor: '#d33',
confirmButtonText: 'حسناً'
});
<?php endif; ?>
$('.delete-btn').on('click', function() {
var form = $(this).closest('form');
Swal.fire({
title: 'هل أنت متأكد؟',
text: 'سيتم حذف القيد من جميع الحسابات المرتبطة بشكل نهائي.',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#6c757d',
confirmButtonText: 'نعم، احذف!',
cancelButtonText: 'إلغاء'
}).then((result) => {
if (result.isConfirmed) {
form.submit();
}
});
});
});
function openEditModal(id) {
$.ajax({
url: 'api/get_journal_entry.php?id=' + id,
type: 'GET',
dataType: 'json',
success: function(response) {
if (response.success) {
var data = response.data;
$('#edit_id').val(data.id);
$('#edit_date').val(data.date);
$('#edit_reference').val(data.reference);
$('#edit_description').val(data.description);
$('#edit_debit_account').val(data.debit_account).trigger('change');
$('#edit_credit_account').val(data.credit_account).trigger('change');
$('#edit_amount').val(data.amount);
var editModal = new bootstrap.Modal(document.getElementById('editJournalModal'));
editModal.show();
} else {
Swal.fire({
icon: 'error',
title: 'خطأ',
text: 'حدث خطأ أثناء جلب بيانات القيد.',
confirmButtonColor: '#3085d6',
confirmButtonText: 'حسناً'
});
}
},
error: function() {
Swal.fire({
icon: 'error',
title: 'خطأ',
text: 'حدث خطأ في الاتصال بالخادم.',
confirmButtonColor: '#3085d6',
confirmButtonText: 'حسناً'
});
}
});
}
</script>
<?php require_once 'includes/footer.php'; ?>

View File

@ -13,26 +13,32 @@ if (!$stmt->fetch()) {
exit;
}
$message = null;
$messageType = 'success';
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['add_account'])) {
$name = $_POST['name'];
$type = $_POST['type'];
$stmt = db()->prepare("INSERT INTO accounting_accounts (name, type) VALUES (?, ?)");
$stmt->execute([$name, $type]);
$message = "تم إضافة الحساب بنجاح.";
if($stmt->execute([$name, $type])) {
$message = "تم إضافة الحساب بنجاح.";
}
} elseif (isset($_POST['delete_account'])) {
$id = $_POST['id'];
$stmt = db()->prepare("DELETE FROM accounting_accounts WHERE id = ?");
$stmt->execute([$id]);
$message = "تم حذف الحساب.";
if($stmt->execute([$id])) {
$message = "تم حذف الحساب.";
}
} elseif (isset($_POST['edit_account'])) {
$id = $_POST['id'];
$name = $_POST['name'];
$type = $_POST['type'];
$stmt = db()->prepare("UPDATE accounting_accounts SET name = ?, type = ? WHERE id = ?");
$stmt->execute([$name, $type, $id]);
$message = "تم تحديث الحساب بنجاح.";
if($stmt->execute([$name, $type, $id])) {
$message = "تم تحديث الحساب بنجاح.";
}
}
}
@ -65,24 +71,38 @@ $typeMap = [
];
?>
<div class="container mt-4" dir="rtl">
<h2 class="text-right">دليل الحسابات</h2>
<?php if (isset($message)) echo "<div class='alert alert-success'>$message</div>"; ?>
<!-- SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<div class="card mb-4">
<div class="card-header">إضافة/تعديل حساب</div>
<div class="card-body">
<style>
/* Reduce row height for a more compact table */
.table-compact td, .table-compact th {
padding: 0.4rem 0.6rem;
vertical-align: middle;
font-size: 0.95rem;
}
.table-compact .btn-sm {
padding: 0.2rem 0.4rem;
font-size: 0.8rem;
}
</style>
<div class="container mt-4" dir="rtl">
<h2 class="text-right mb-4">دليل الحسابات</h2>
<div class="card mb-4 shadow-sm border-0">
<div class="card-header bg-primary text-white">إضافة/تعديل حساب</div>
<div class="card-body bg-light">
<form method="POST" id="accountForm">
<input type="hidden" name="add_account" value="1" id="formAction">
<input type="hidden" name="id" id="editId">
<div class="row">
<div class="col-md-5">
<label>اسم الحساب</label>
<div class="col-md-5 mb-2">
<label class="font-weight-bold">اسم الحساب</label>
<input type="text" name="name" class="form-control" id="editName" required>
</div>
<div class="col-md-5">
<label>نوع الحساب</label>
<div class="col-md-5 mb-2">
<label class="font-weight-bold">نوع الحساب</label>
<select name="type" class="form-control" id="editType" required>
<option value="أصول">أصول</option>
<option value="خصوم">خصوم</option>
@ -91,54 +111,130 @@ $typeMap = [
<option value="مصروفات">مصروفات</option>
</select>
</div>
<div class="col-md-2 d-flex align-items-end">
<button type="submit" class="btn btn-primary" id="formButton">إضافة</button>
<div class="col-md-2 d-flex align-items-end mb-2">
<button type="submit" class="btn btn-primary w-100 shadow-sm" id="formButton">
<i class="fas fa-plus"></i> إضافة
</button>
</div>
</div>
</form>
</div>
</div>
<table class="table table-bordered text-right">
<thead><tr><th>الاسم</th><th>النوع</th><th>إجراءات</th></tr></thead>
<tbody>
<?php foreach ($accounts as $account): ?>
<tr>
<td><?= htmlspecialchars($account['name']) ?></td>
<td><?= htmlspecialchars($typeMap[$account['type']] ?? $account['type']) ?></td>
<td>
<button class="btn btn-sm btn-info" onclick="editAccount(<?= $account['id'] ?>, '<?= htmlspecialchars($account['name']) ?>', '<?= $account['type'] ?>')">
<i class="fas fa-pencil-alt"></i>
</button>
<form method="POST" onsubmit="return confirm('هل أنت متأكد؟');" style="display:inline;">
<input type="hidden" name="delete_account" value="1">
<input type="hidden" name="id" value="<?= $account['id'] ?>">
<button type="submit" class="btn btn-danger btn-sm"><i class="fas fa-trash-alt"></i></button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="card shadow-sm border-0">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered table-striped table-hover table-compact text-right mb-0">
<thead class="thead-dark">
<tr>
<th>الاسم</th>
<th>النوع</th>
<th style="width: 120px; text-align: center;">إجراءات</th>
</tr>
</thead>
<tbody>
<?php foreach ($accounts as $account): ?>
<tr>
<td><?= htmlspecialchars($account['name']) ?></td>
<td>
<span class="badge badge-info px-2 py-1" style="color: black;">
<?= htmlspecialchars($typeMap[$account['type']] ?? $account['type']) ?>
</span>
</td>
<td class="text-center">
<button class="btn btn-warning text-white btn-sm shadow-sm mx-1" onclick="editAccount(<?= $account['id'] ?>, '<?= htmlspecialchars($account['name'], ENT_QUOTES) ?>', '<?= htmlspecialchars($account['type'], ENT_QUOTES) ?>')" title="تعديل">
<i class="fas fa-pencil-alt"></i>
</button>
<form method="POST" style="display:inline;" class="delete-form">
<input type="hidden" name="delete_account" value="1">
<input type="hidden" name="id" value="<?= $account['id'] ?>">
<button type="button" class="btn btn-danger btn-sm shadow-sm mx-1" onclick="confirmDelete(this)" title="حذف">
<i class="fas fa-trash-alt"></i>
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($accounts)): ?>
<tr>
<td colspan="3" class="text-center py-3 text-muted">لا توجد حسابات مضافة بعد.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<nav>
<ul class="pagination">
<?php if ($totalPages > 1): ?>
<nav class="mt-4">
<ul class="pagination justify-content-center">
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
<li class="page-item <?= $i == $page ? 'active' : '' ?>"><a class="page-link" href="?p=<?= $i ?>"><?= $i ?></a></li>
<li class="page-item <?= $i == $page ? 'active' : '' ?>">
<a class="page-link" href="?p=<?= $i ?>"><?= $i ?></a>
</li>
<?php endfor; ?>
</ul>
</nav>
<?php endif; ?>
</div>
<script>
// SweetAlert Success Message from PHP
<?php if ($message): ?>
document.addEventListener('DOMContentLoaded', function() {
Swal.fire({
icon: 'success',
title: 'نجاح!',
text: '<?= htmlspecialchars($message) ?>',
confirmButtonText: 'حسناً',
confirmButtonColor: '#28a745',
timer: 3000,
timerProgressBar: true
});
});
<?php endif; ?>
function editAccount(id, name, type) {
document.getElementById('formAction').name = 'edit_account';
document.getElementById('editId').value = id;
document.getElementById('editName').value = name;
document.getElementById('editType').value = type;
document.getElementById('formButton').innerText = 'تعديل';
const formBtn = document.getElementById('formButton');
formBtn.innerHTML = '<i class="fas fa-save"></i> حفظ التعديلات';
formBtn.classList.remove('btn-primary');
formBtn.classList.add('btn-success');
// Animate scroll to form
window.scrollTo({top: 0, behavior: 'smooth'});
// Highlight form briefly to show it's in edit mode
const cardBody = document.querySelector('.card-body');
cardBody.style.transition = 'background-color 0.5s';
cardBody.style.backgroundColor = '#fff3cd'; // warning light
setTimeout(() => {
cardBody.style.backgroundColor = '';
}, 1000);
}
function confirmDelete(button) {
Swal.fire({
title: 'هل أنت متأكد؟',
text: "لن تتمكن من استعادة هذا الحساب لاحقاً!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#dc3545',
cancelButtonColor: '#6c757d',
confirmButtonText: '<i class="fas fa-trash-alt"></i> نعم، احذفه!',
cancelButtonText: 'إلغاء',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
button.closest('.delete-form').submit();
}
});
}
</script>
<?php require_once 'includes/footer.php'; ?>
<?php require_once 'includes/footer.php'; ?>

15
api/get_journal_entry.php Normal file
View File

@ -0,0 +1,15 @@
<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../includes/accounting_functions.php';
header('Content-Type: application/json');
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id > 0) {
$data = get_journal_entry_details($id);
if ($data) {
echo json_encode(['success' => true, 'data' => $data]);
exit;
}
}
echo json_encode(['success' => false, 'error' => 'Entry not found.']);

View File

@ -11,7 +11,7 @@ $data = json_decode(file_get_contents('php://input'), true);
$theme = $data['theme'] ?? 'light';
// Validate theme
$allowed_themes = ['light', 'dark', 'midnight', 'forest'];
$allowed_themes = ['light', 'dark', 'midnight', 'forest', 'ocean', 'sunset', 'royal'];
if (!in_array($theme, $allowed_themes)) {
echo json_encode(['success' => false, 'error' => 'مظهر غير صالح']);
exit;

View File

@ -1,12 +1,204 @@
body {
background-color: #f8f9fa;
color: #212529;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background-color: var(--bs-body-bg);
color: var(--bs-body-color);
font-family: 'Cairo', 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-size: 14px;
margin: 0;
min-height: 100vh;
}
/* Fix RTL spacing */
.me-2 { margin-left: 0.5rem !important; margin-right: 0 !important; }
.ms-auto { margin-right: auto !important; margin-left: 0 !important; }
/*
THEME DEFINITIONS
We leverage Bootstrap 5 CSS variables to create different themes.
Light and Dark are built-in, but we can tweak them too if we want.
*/
/* 1. Midnight Theme (Deep Blue) */
[data-bs-theme="midnight"] {
--bs-body-bg: #0f172a;
--bs-body-color: #f1f5f9;
--bs-heading-color: #f1f5f9;
--bs-body-bg-rgb: 15, 23, 42;
--bs-tertiary-bg: #1e293b;
--bs-secondary-bg: #334155;
--bs-border-color: #334155;
--bs-link-color: #60a5fa;
--bs-link-hover-color: #93c5fd;
--bs-card-bg: #1e293b;
--bs-card-border-color: #334155;
}
/* 2. Forest Theme (Deep Green) */
[data-bs-theme="forest"] {
--bs-body-bg: #052e16;
--bs-body-color: #ecfdf5;
--bs-heading-color: #ecfdf5;
--bs-body-bg-rgb: 5, 46, 22;
--bs-tertiary-bg: #064e3b;
--bs-secondary-bg: #065f46;
--bs-border-color: #047857;
--bs-link-color: #34d399;
--bs-link-hover-color: #6ee7b7;
--bs-card-bg: #064e3b;
--bs-card-border-color: #047857;
}
/* 3. Ocean Theme (Deep Teal/Blue) */
[data-bs-theme="ocean"] {
--bs-body-bg: #0c4a6e;
--bs-body-color: #f0f9ff;
--bs-heading-color: #f0f9ff;
--bs-body-bg-rgb: 12, 74, 110;
--bs-tertiary-bg: #075985;
--bs-secondary-bg: #0369a1;
--bs-border-color: #0284c7;
--bs-link-color: #38bdf8;
--bs-link-hover-color: #7dd3fc;
--bs-card-bg: #075985;
--bs-card-border-color: #0284c7;
}
/* 4. Sunset Theme (Warm Dark) */
[data-bs-theme="sunset"] {
--bs-body-bg: #431407;
--bs-body-color: #fff7ed;
--bs-heading-color: #fff7ed;
--bs-body-bg-rgb: 67, 20, 7;
--bs-tertiary-bg: #7c2d12;
--bs-secondary-bg: #9a3412;
--bs-border-color: #c2410c;
--bs-link-color: #fdba74;
--bs-link-hover-color: #ffedd5;
--bs-card-bg: #7c2d12;
--bs-card-border-color: #c2410c;
}
/* 5. Royal Theme (Deep Purple) */
[data-bs-theme="royal"] {
--bs-body-bg: #2e1065;
--bs-body-color: #faf5ff;
--bs-heading-color: #faf5ff;
--bs-body-bg-rgb: 46, 16, 101;
--bs-tertiary-bg: #4c1d95;
--bs-secondary-bg: #5b21b6;
--bs-border-color: #6d28d9;
--bs-link-color: #c084fc;
--bs-link-hover-color: #e9d5ff;
--bs-card-bg: #4c1d95;
--bs-card-border-color: #6d28d9;
}
/*
Shared overrides for ALL dark themes
This ensures standard Bootstrap classes like .text-dark don't cause visibility issues.
*/
[data-bs-theme="midnight"],
[data-bs-theme="forest"],
[data-bs-theme="ocean"],
[data-bs-theme="sunset"],
[data-bs-theme="royal"] {
color-scheme: dark;
}
/* Text color overrides */
[data-bs-theme="midnight"] .text-dark,
[data-bs-theme="forest"] .text-dark,
[data-bs-theme="ocean"] .text-dark,
[data-bs-theme="sunset"] .text-dark,
[data-bs-theme="royal"] .text-dark {
color: #f8f9fa !important;
}
[data-bs-theme="midnight"] .text-muted,
[data-bs-theme="forest"] .text-muted,
[data-bs-theme="ocean"] .text-muted,
[data-bs-theme="sunset"] .text-muted,
[data-bs-theme="royal"] .text-muted {
color: rgba(255, 255, 255, 0.6) !important;
}
[data-bs-theme="midnight"] .text-secondary,
[data-bs-theme="forest"] .text-secondary,
[data-bs-theme="ocean"] .text-secondary,
[data-bs-theme="sunset"] .text-secondary,
[data-bs-theme="royal"] .text-secondary {
color: rgba(255, 255, 255, 0.75) !important;
}
/* Background overrides for hardcoded bg-light/bg-white classes */
[data-bs-theme="midnight"] .bg-light,
[data-bs-theme="forest"] .bg-light,
[data-bs-theme="ocean"] .bg-light,
[data-bs-theme="sunset"] .bg-light,
[data-bs-theme="royal"] .bg-light {
background-color: var(--bs-tertiary-bg) !important;
color: var(--bs-body-color) !important;
}
[data-bs-theme="midnight"] .bg-white,
[data-bs-theme="forest"] .bg-white,
[data-bs-theme="ocean"] .bg-white,
[data-bs-theme="sunset"] .bg-white,
[data-bs-theme="royal"] .bg-white {
background-color: var(--bs-card-bg) !important;
color: var(--bs-body-color) !important;
}
[data-bs-theme="midnight"] .table th,
[data-bs-theme="forest"] .table th,
[data-bs-theme="ocean"] .table th,
[data-bs-theme="sunset"] .table th,
[data-bs-theme="royal"] .table th {
color: rgba(255, 255, 255, 0.8);
}
/* Ensure cards and tables inherit theme colors correctly */
[data-bs-theme="midnight"] .card,
[data-bs-theme="forest"] .card,
[data-bs-theme="ocean"] .card,
[data-bs-theme="sunset"] .card,
[data-bs-theme="royal"] .card {
background-color: var(--bs-card-bg);
border-color: var(--bs-card-border-color);
color: var(--bs-body-color);
}
[data-bs-theme="midnight"] .table,
[data-bs-theme="forest"] .table,
[data-bs-theme="ocean"] .table,
[data-bs-theme="sunset"] .table,
[data-bs-theme="royal"] .table {
color: var(--bs-body-color);
--bs-table-color: var(--bs-body-color);
--bs-table-bg: transparent;
--bs-table-border-color: var(--bs-border-color);
--bs-table-striped-bg: rgba(255, 255, 255, 0.05);
--bs-table-hover-bg: rgba(255, 255, 255, 0.1);
}
[data-bs-theme="midnight"] .modal-content,
[data-bs-theme="forest"] .modal-content,
[data-bs-theme="ocean"] .modal-content,
[data-bs-theme="sunset"] .modal-content,
[data-bs-theme="royal"] .modal-content {
background-color: var(--bs-tertiary-bg);
border-color: var(--bs-border-color);
color: var(--bs-body-color);
}
/* Sidebar overrides for specific themes */
[data-bs-theme="midnight"] .sidebar { background-color: #1e293b !important; border-left: 1px solid #334155; }
[data-bs-theme="forest"] .sidebar { background-color: #064e3b !important; border-left: 1px solid #065f46; }
[data-bs-theme="ocean"] .sidebar { background-color: #075985 !important; border-left: 1px solid #0369a1; }
[data-bs-theme="sunset"] .sidebar { background-color: #7c2d12 !important; border-left: 1px solid #9a3412; }
[data-bs-theme="royal"] .sidebar { background-color: #4c1d95 !important; border-left: 1px solid #5b21b6; }
.main-wrapper {
display: flex;
align-items: center;
@ -34,8 +226,8 @@ body {
.chat-container {
width: 100%;
max-width: 600px;
background: #ffffff;
border: 1px solid rgba(0, 0, 0, 0.1);
background: var(--bs-body-bg);
border: 1px solid var(--bs-border-color);
border-radius: 20px;
display: flex;
flex-direction: column;
@ -46,13 +238,14 @@ body {
.chat-header {
padding: 1.5rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
background: #f8f9fa;
border-bottom: 1px solid var(--bs-border-color);
background: var(--bs-tertiary-bg);
font-weight: 700;
font-size: 1.1rem;
display: flex;
justify-content: space-between;
align-items: center;
color: var(--bs-body-color);
}
.chat-messages {
@ -78,6 +271,15 @@ body {
border-radius: 10px;
}
[data-bs-theme="dark"] ::-webkit-scrollbar-thumb,
[data-bs-theme="midnight"] ::-webkit-scrollbar-thumb,
[data-bs-theme="forest"] ::-webkit-scrollbar-thumb,
[data-bs-theme="ocean"] ::-webkit-scrollbar-thumb,
[data-bs-theme="sunset"] ::-webkit-scrollbar-thumb,
[data-bs-theme="royal"] ::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, 0.2);
}
@ -106,15 +308,16 @@ body {
.message.bot {
align-self: flex-start;
background: #f1f3f5;
color: #212529;
background: var(--bs-tertiary-bg); /* Use theme bg */
color: var(--bs-body-color);
border-bottom-left-radius: 4px;
border: 1px solid var(--bs-border-color);
}
.chat-input-area {
padding: 1.25rem;
background: #fff;
border-top: 1px solid rgba(0, 0, 0, 0.05);
background: var(--bs-body-bg);
border-top: 1px solid var(--bs-border-color);
}
.chat-input-area form {
@ -124,11 +327,12 @@ body {
.chat-input-area input {
flex: 1;
border: 1px solid rgba(0, 0, 0, 0.1);
border: 1px solid var(--bs-border-color);
border-radius: 12px;
padding: 0.75rem 1rem;
outline: none;
background: #fff;
background: var(--bs-body-bg);
color: var(--bs-body-color);
transition: all 0.3s ease;
}
@ -173,17 +377,18 @@ body {
max-width: 900px;
margin: 2rem auto;
padding: 2rem;
background: #fff;
background: var(--bs-body-bg);
border-radius: 16px;
box-shadow: 0 5px 20px rgba(0,0,0,0.05);
border: 1px solid rgba(0, 0, 0, 0.05);
border: 1px solid var(--bs-border-color);
position: relative;
z-index: 1;
color: var(--bs-body-color);
}
.admin-container h1 {
margin-top: 0;
color: #212529;
color: var(--bs-heading-color, var(--bs-body-color)); /* Use variable or fallback */
font-weight: 700;
}
@ -192,13 +397,14 @@ body {
border-collapse: separate;
border-spacing: 0 8px;
margin-top: 1.5rem;
color: var(--bs-body-color);
}
.table th {
background: transparent;
border: none;
padding: 1rem;
color: #6c757d;
color: #6c757d; /* Keep subtle for headers, but overridden for dark themes */
font-weight: 600;
text-transform: uppercase;
font-size: 0.75rem;
@ -206,14 +412,15 @@ body {
}
.table td {
background: #fff;
background: var(--bs-body-bg);
padding: 1rem;
border-top: 1px solid #f1f3f5;
border-bottom: 1px solid #f1f3f5;
border-top: 1px solid var(--bs-border-color);
border-bottom: 1px solid var(--bs-border-color);
color: var(--bs-body-color);
}
.table tr td:first-child { border-left: 1px solid #f1f3f5; border-radius: 8px 0 0 8px; }
.table tr td:last-child { border-right: 1px solid #f1f3f5; border-radius: 0 8px 8px 0; }
.table tr td:first-child { border-left: 1px solid var(--bs-border-color); border-radius: 8px 0 0 8px; }
.table tr td:last-child { border-right: 1px solid var(--bs-border-color); border-radius: 0 8px 8px 0; }
.form-group {
margin-bottom: 1.25rem;
@ -224,14 +431,16 @@ body {
margin-bottom: 0.5rem;
font-weight: 600;
font-size: 0.9rem;
color: var(--bs-body-color);
}
.form-control {
width: 100%;
padding: 0.75rem 1rem;
border: 1px solid rgba(0, 0, 0, 0.1);
border: 1px solid var(--bs-border-color);
border-radius: 8px;
background: #fff;
background: var(--bs-body-bg);
color: var(--bs-body-color);
transition: all 0.3s ease;
box-sizing: border-box;
}
@ -240,4 +449,14 @@ body {
outline: none;
border-color: #0d6efd;
box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.1);
background: var(--bs-body-bg);
color: var(--bs-body-color);
}
/* Compact Table Class */
.table-compact td, .table-compact th {
padding: 0.5rem 0.75rem !important;
font-size: 0.9rem;
}
.table-compact tr td:first-child { border-radius: 4px 0 0 4px; }
.table-compact tr td:last-child { border-radius: 0 4px 4px 0; }

View File

@ -1,5 +1,5 @@
<?php
require_once 'db/config.php';
require_once __DIR__ . '/../db/config.php';
function get_journal_entries() {
$db = db();
@ -114,4 +114,62 @@ function delete_journal_entry($id) {
return false;
}
}
function get_journal_entry_details($id) {
$db = db();
$stmt = $db->prepare("SELECT * FROM accounting_journal WHERE id = ?");
$stmt->execute([$id]);
$journal = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$journal) return null;
$stmt = $db->prepare("SELECT * FROM accounting_entries WHERE journal_id = ? ORDER BY id ASC");
$stmt->execute([$id]);
$entries = $stmt->fetchAll(PDO::FETCH_ASSOC);
$debit_account = '';
$credit_account = '';
$amount = 0;
foreach ($entries as $e) {
if ($e['debit'] > 0) {
$debit_account = $e['account_name'];
$amount = $e['debit'];
} elseif ($e['credit'] > 0) {
$credit_account = $e['account_name'];
if ($amount == 0) $amount = $e['credit'];
}
}
return [
'id' => $journal['id'],
'date' => $journal['date'],
'description' => $journal['description'],
'reference' => $journal['reference'],
'debit_account' => $debit_account,
'credit_account' => $credit_account,
'amount' => $amount
];
}
function edit_journal_entry($id, $date, $description, $reference, $entries) {
$db = db();
$db->beginTransaction();
try {
$stmt = $db->prepare("UPDATE accounting_journal SET date = ?, description = ?, reference = ? WHERE id = ?");
$stmt->execute([$date, $description, $reference, $id]);
$stmt = $db->prepare("DELETE FROM accounting_entries WHERE journal_id = ?");
$stmt->execute([$id]);
$stmt = $db->prepare("INSERT INTO accounting_entries (journal_id, account_name, debit, credit) VALUES (?, ?, ?, ?)");
foreach ($entries as $entry) {
$stmt->execute([$id, $entry['account'], $entry['debit'], $entry['credit']]);
}
$db->commit();
return true;
} catch (Exception $e) {
$db->rollBack();
return false;
}
}
?>

View File

@ -209,63 +209,6 @@ if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename(
.ms-auto { margin-right: auto !important; margin-left: 0 !important; }
.me-auto { margin-left: auto !important; margin-right: 0 !important; }
/* Theme Switcher Styles */
.theme-switch-wrapper {
display: flex;
align-items: center;
}
.theme-switch {
display: inline-block;
height: 24px;
position: relative;
width: 48px;
}
.theme-switch input { display: none; }
.slider {
background-color: #ccc;
bottom: 0;
cursor: pointer;
left: 0;
position: absolute;
right: 0;
top: 0;
transition: .4s;
border-radius: 34px;
}
.slider:before {
background-color: #fff;
bottom: 4px;
content: "";
height: 16px;
left: 4px;
position: absolute;
transition: .4s;
width: 16px;
border-radius: 50%;
}
input:checked + .slider { background-color: #0d6efd; }
input:checked + .slider:before { transform: translateX(24px); }
.slider .fa-sun {
position: absolute;
left: 6px;
top: 4px;
font-size: 12px;
color: #ffc107;
opacity: 1;
transition: .4s;
}
.slider .fa-moon {
position: absolute;
right: 6px;
top: 4px;
font-size: 12px;
color: #f8f9fa;
opacity: 0;
transition: .4s;
}
input:checked + .slider .fa-sun { opacity: 0; }
input:checked + .slider .fa-moon { opacity: 1; }
/* RTL specific tweaks */
[dir="rtl"] .dropdown-menu { text-align: right; }
[dir="rtl"] .ms-2 { margin-right: 0.5rem !important; margin-left: 0 !important; }
@ -276,8 +219,7 @@ if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename(
function toggleSidebar() {
document.getElementById('sidebar').classList.toggle('show');
}
function toggleTheme(checkbox) {
const theme = checkbox.checked ? 'dark' : 'light';
function setTheme(theme) {
document.documentElement.setAttribute('data-bs-theme', theme);
fetch('api/update_theme.php', {
method: 'POST',
@ -417,15 +359,22 @@ if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename(
</button>
<div class="ms-auto d-flex align-items-center">
<!-- Theme Switcher -->
<div class="theme-switch-wrapper me-3">
<label class="theme-switch" for="checkbox">
<input type="checkbox" id="checkbox" <?= $user_theme === 'dark' ? 'checked' : '' ?> onchange="toggleTheme(this)">
<div class="slider">
<i class="fas fa-sun"></i>
<i class="fas fa-moon"></i>
</div>
</label>
<!-- Theme Dropdown -->
<div class="dropdown me-3">
<button class="btn btn-outline-secondary dropdown-toggle d-flex align-items-center gap-2" type="button" id="themeDropdown" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fas fa-palette"></i>
<span class="d-none d-md-inline">المظهر</span>
</button>
<ul class="dropdown-menu dropdown-menu-end shadow border-0" aria-labelledby="themeDropdown">
<li><button class="dropdown-item d-flex align-items-center" onclick="setTheme('light')"><i class="fas fa-sun me-2 text-warning"></i> فاتح (Light)</button></li>
<li><button class="dropdown-item d-flex align-items-center" onclick="setTheme('dark')"><i class="fas fa-moon me-2 text-dark"></i> داكن (Dark)</button></li>
<li><button class="dropdown-item d-flex align-items-center" onclick="setTheme('midnight')"><i class="fas fa-star me-2 text-primary"></i> منتصف الليل (Midnight)</button></li>
<li><button class="dropdown-item d-flex align-items-center" onclick="setTheme('forest')"><i class="fas fa-tree me-2 text-success"></i> غابة (Forest)</button></li>
<li><button class="dropdown-item d-flex align-items-center" onclick="setTheme('ocean')"><i class="fas fa-water me-2 text-info"></i> محيط (Ocean)</button></li>
<li><button class="dropdown-item d-flex align-items-center" onclick="setTheme('sunset')"><i class="fas fa-cloud-sun me-2 text-danger"></i> غروب (Sunset)</button></li>
<li><button class="dropdown-item d-flex align-items-center" onclick="setTheme('royal')"><i class="fas fa-crown me-2 text-secondary"></i> ملكي (Royal)</button></li>
</ul>
</div>
<div class="dropdown">

View File

@ -14,7 +14,8 @@ $modules = [
'internal' => 'البريد الداخلي',
'users' => 'إدارة المستخدمين',
'settings' => 'الإعدادات',
'reports' => 'التقارير'
'reports' => 'التقارير',
'accounting' => 'المحاسبة'
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {