Files
wms-app/app/include_topbar.php
T
2026-05-13 15:11:24 +07:00

257 lines
11 KiB
PHP

<?php
// Redirect to login if the user has not completed full authentication.
// login_company_id is only written by login_confirm.php after OTP is verified —
// using it (not "otp") ensures half-logged-in sessions are also redirected.
if(empty($_SESSION["login_company_id"])){
header('Location: '.$server_url.'login/index.php');
exit;
}
require 'preset.php';
// ── User display data from session ────────────────────────────────────────────
$topbar_name = htmlspecialchars(trim(($_SESSION['login_name'] ?? '') . ' ' . ($_SESSION['login_surname'] ?? '')), ENT_QUOTES, 'UTF-8');
$topbar_username = htmlspecialchars($_SESSION['login_username'] ?? '', ENT_QUOTES, 'UTF-8');
$topbar_picture = $_SESSION['login_profile_picture'] ?? '';
$topbar_avatar_src = $topbar_picture
? htmlspecialchars($server_url . 'uploads/profile/' . $topbar_picture, ENT_QUOTES, 'UTF-8')
: htmlspecialchars($server_url . 'assets/images/avatar-1.jpg', ENT_QUOTES, 'UTF-8');
// ── App switcher ──────────────────────────────────────────────────────────────
$topbar_app_access = $_SESSION['login_app_access'] ?? 'wms';
// Detect which app this page belongs to.
// Master-data pages (/accounting/, /inventory/, /contact/, /setting/) are neutral — don't change the session.
$_wms_paths = ['/dashboard/', '/ics/', '/order/', '/po/', '/reports/'];
$_ac_paths = ['/ac_dashboard/', '/revenue/', '/expense/', '/finance/', '/journal/'];
$topbar_current_app = null; // null = neutral page (master data / setting)
foreach ($_wms_paths as $_p) {
if (str_contains($_SERVER['PHP_SELF'], $_p)) { $topbar_current_app = 'wms'; break; }
}
if (!$topbar_current_app) {
foreach ($_ac_paths as $_p) {
if (str_contains($_SERVER['PHP_SELF'], $_p)) { $topbar_current_app = 'accounting'; break; }
}
}
// Only persist to session when on a definitive app page
if ($topbar_current_app) {
$_SESSION['login_current_app'] = $topbar_current_app;
}
// Default session on first visit or neutral pages
if (empty($_SESSION['login_current_app'])) {
$_SESSION['login_current_app'] = ($topbar_app_access === 'accounting') ? 'accounting' : 'wms';
}
$topbar_show_wms = in_array($topbar_app_access, ['all', 'wms']);
$topbar_show_accounting = in_array($topbar_app_access, ['all', 'accounting']);
?>
<div id="overlay" class="overlay"></div>
<!-- Global Variables -->
<div id="session-context"
data-company-id="<?php echo htmlspecialchars($_SESSION['login_company_id'] ?? 0, ENT_QUOTES, 'UTF-8'); ?>"
data-otp="<?php echo htmlspecialchars($_SESSION['otp'] ?? '', ENT_QUOTES, 'UTF-8'); ?>"
data-role="<?php echo htmlspecialchars($_SESSION['login_role'] ?? 'viewer', ENT_QUOTES, 'UTF-8'); ?>">
</div>
<!-- Switch Branch Modal -->
<div class="modal fade" id="switchBranchModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" style="max-width: 360px;">
<div class="modal-content">
<div class="modal-header border-dashed">
<h6 class="modal-title mb-0"><i class="ti ti-building me-2"></i>Switch Branch</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body p-0">
<div id="branch_list" class="d-flex flex-column">
<div class="text-center text-muted small py-4">Loading...</div>
</div>
</div>
</div>
</div>
</div>
<!-- TOPBAR -->
<nav id="topbar" class="navbar bg-white border-bottom fixed-top topbar px-3">
<button id="toggleBtn" class="d-none d-lg-inline-flex btn btn-light btn-icon btn-sm ">
<i class="ti ti-layout-sidebar-left-expand"></i>
</button>
<!-- MOBILE -->
<button id="mobileBtn" class="btn btn-light btn-icon btn-sm d-lg-none me-2">
<i class="ti ti-layout-sidebar-left-expand"></i>
</button>
<div>
<!-- Navbar nav -->
<ul class="list-unstyled d-flex align-items-center mb-0 gap-1">
<!-- App switcher -->
<?php if ($topbar_show_wms && $topbar_show_accounting): ?>
<li class="dropdown">
<a class="position-relative btn-icon btn-sm btn-light btn rounded-circle" data-bs-toggle="dropdown"
aria-expanded="false" href="#" role="button" title="Switch App">
<i class="ti ti-layout-grid" style="font-size:18px;"></i>
</a>
<div class="dropdown-menu dropdown-menu-end p-2" style="min-width:170px;">
<?php $_sess_app = $_SESSION['login_current_app'] ?? 'wms'; ?>
<a href="<?php echo $server_url?>dashboard/index.php"
class="dropdown-item rounded d-flex align-items-center gap-2 py-2 <?php echo $_sess_app === 'wms' ? 'active' : ''; ?>">
<i class="ti ti-box"></i>
<span>WMS</span>
<?php if ($_sess_app === 'wms'): ?>
<i class="ti ti-check ms-auto text-success"></i>
<?php endif; ?>
</a>
<a href="<?php echo $server_url?>ac_dashboard/index.php"
class="dropdown-item rounded d-flex align-items-center gap-2 py-2 <?php echo $_sess_app === 'accounting' ? 'active' : ''; ?>">
<i class="ti ti-calculator"></i>
<span>Accounting</span>
<?php if ($_sess_app === 'accounting'): ?>
<i class="ti ti-check ms-auto text-success"></i>
<?php endif; ?>
</a>
</div>
</li>
<?php endif; ?>
<!-- Bell icon -->
<li>
<a class="position-relative btn-icon btn-sm btn-light btn rounded-circle" data-bs-toggle="dropdown"
aria-expanded="false" href="#" role="button">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"
class="icon icon-tabler icons-tabler-outline icon-tabler-bell">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6" />
<path d="M9 17v1a3 3 0 0 0 6 0v-1" />
</svg>
</a>
<div class="dropdown-menu dropdown-menu-end dropdown-menu-md p-0">
<ul class="list-unstyled p-0 m-0">
<li class="px-4 py-3 text-center text-muted small">No notifications</li>
</ul>
</div>
</li>
<!-- User dropdown -->
<li class="ms-3 dropdown">
<a class="position-relative btn-icon btn-sm btn-primary btn rounded-circle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"/>
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"/>
</svg>
</a>
<div class="dropdown-menu dropdown-menu-end p-0" style="min-width: 200px;">
<div>
<div class="d-flex gap-3 align-items-center border-dashed border-bottom px-3 py-3">
<img src="<?php echo $topbar_avatar_src; ?>" alt=""
class="avatar avatar-md rounded-circle" />
<div>
<h4 class="mb-0 small"><?php echo $topbar_name; ?></h4>
<p class="mb-0 small">@<?php echo $topbar_username; ?></p>
</div>
</div>
<div class="p-3 d-flex flex-column gap-1 small lh-lg">
<a href="javascript:;" onclick="switch_branch();">
<span>Switch Branch</span>
</a>
<a href="<?php echo $server_url?>setting/profile.php">
<span>Setting</span>
</a>
<a href="<?php echo $server_url?>inventory/product.php">
<span>Master Data</span>
</a>
<a href="javascript:;" onclick="log_out();">
<span>Log Out</span>
</a>
</div>
</div>
</div>
</li>
</ul>
</div>
</nav>
<!-- top bar script -->
<script>
// Global Variables
var server_url = '<?php echo $server_url; ?>';
var prop_limit = '<?php echo $prop['limit']; ?>';
var user_role = document.getElementById('session-context')?.dataset.role || 'viewer';
// ── Log out ───────────────────────────────────────────────────────────────────
function log_out() {
return ajax_request({
url: server_url + 'login/api/engine/back.php',
autoPrepare: true,
checkRequired: 0,
action: 'read',
onSuccess: function(res) {
window.location.href = server_url + 'index.php';
}
});
}
// ── Switch Branch ─────────────────────────────────────────────────────────────
function switch_branch() {
$('#switchBranchModal').modal('show');
ajax_request({
url: server_url + 'setting/api/engine/switch_branch.php',
autoPrepare: true,
checkRequired: 0,
action: 'read',
onSuccess: function(res) {
var current = res.current;
var companies = res.output || [];
if (companies.length <= 1) {
$('#branch_list').html(
'<div class="text-center text-muted small py-4">You only belong to one branch.</div>'
);
return;
}
var html = '';
companies.forEach(function(c) {
var is_active = c.company_id == current;
html += '<a href="javascript:;" class="d-flex align-items-center gap-3 px-3 py-2 border-bottom ' +
(is_active ? 'bg-light' : '') + '" onclick="do_switch_branch(' + c.company_id + ')">' +
'<span class="d-flex align-items-center justify-content-center rounded-circle bg-label-primary flex-shrink-0" style="width:36px;height:36px;">' +
'<i class="ti ti-building small"></i></span>' +
'<div class="flex-grow-1 overflow-hidden">' +
'<p class="mb-0 small fw-semibold text-truncate">' + $('<span>').text(c.channel_name).html() + '</p>' +
'<p class="mb-0 x-small text-muted">' + $('<span>').text(c.company_name).html() + $('<span>').text(c.branch || c.role).html() + '</p>' +
'</div>' +
(is_active ? '<i class="ti ti-check text-success ms-auto"></i>' : '') +
'</a>';
});
$('#branch_list').html(html);
}
});
}
function do_switch_branch(company_id) {
ajax_request({
url: server_url + 'setting/api/engine/switch_branch.php',
autoPrepare: true,
checkRequired: 0,
action: 'update',
company_id: company_id,
onSuccess: function(res) {
window.location.reload();
}
});
}
</script>