menu fix
This commit is contained in:
parent
cc7bbafb63
commit
3948dde2e7
6 changed files with 114 additions and 66 deletions
|
|
@ -131,25 +131,12 @@ textarea {
|
|||
.primary-nav {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.nav-group {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.nav-group + .nav-group {
|
||||
padding-left: 10px;
|
||||
border-left: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
padding: 9px 10px;
|
||||
border-radius: 6px;
|
||||
|
|
@ -163,6 +150,60 @@ textarea {
|
|||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
.account-menu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.account-menu summary {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.account-menu summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.account-menu summary::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 7px;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-top: 5px solid currentColor;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.account-menu-panel {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: calc(100% + 10px);
|
||||
min-width: 210px;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius);
|
||||
background: rgba(8, 18, 33, 0.98);
|
||||
box-shadow: var(--shadow);
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.account-menu-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 40px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 6px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.account-menu-link:hover,
|
||||
.account-menu-link.is-active {
|
||||
color: var(--text);
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
|
@ -723,6 +764,7 @@ textarea {
|
|||
.primary-nav {
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
row-gap: 8px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
|
|
@ -786,29 +828,36 @@ textarea {
|
|||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.nav-group,
|
||||
.nav-group + .nav-group {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
justify-items: stretch;
|
||||
gap: 4px;
|
||||
padding-left: 0;
|
||||
padding-top: 8px;
|
||||
border-left: 0;
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.nav-group:first-child {
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
min-height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.account-menu {
|
||||
border-top: 1px solid var(--line);
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.account-menu summary {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.account-menu-panel {
|
||||
position: static;
|
||||
min-width: 0;
|
||||
margin-top: 6px;
|
||||
padding: 4px 0 0 12px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.account-menu-link {
|
||||
min-height: 42px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
grid-column: 1 / -1;
|
||||
display: none;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const toggle = document.querySelector('[data-nav-toggle]');
|
||||
const menu = document.querySelector('[data-nav-menu]');
|
||||
const actions = document.querySelector('[data-header-actions]');
|
||||
const accountMenu = document.querySelector('[data-account-menu]');
|
||||
|
||||
if (!toggle || !menu) {
|
||||
return;
|
||||
|
|
@ -14,5 +15,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
if (actions) {
|
||||
actions.classList.toggle('is-open', !expanded);
|
||||
}
|
||||
if (accountMenu && window.matchMedia('(max-width: 820px)').matches) {
|
||||
accountMenu.open = !expanded;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -436,15 +436,14 @@ function website_table_exists(string $tableName): bool
|
|||
return false;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('SHOW TABLES LIKE ?');
|
||||
if (!$stmt) {
|
||||
$escapedTableName = $db->real_escape_string($tableName);
|
||||
$result = @$db->query("SHOW TABLES LIKE '{$escapedTableName}'");
|
||||
if (!$result instanceof mysqli_result) {
|
||||
return false;
|
||||
}
|
||||
$stmt->bind_param('s', $tableName);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$exists = $result instanceof mysqli_result && $result->num_rows > 0;
|
||||
$stmt->close();
|
||||
|
||||
$exists = $result->num_rows > 0;
|
||||
$result->free();
|
||||
return $exists;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||
$activePage = $activePage ?? '';
|
||||
$currentUser = website_current_user();
|
||||
$cartCount = website_cart_count();
|
||||
$publicLinks = [
|
||||
$primaryLinks = [
|
||||
['key' => 'home', 'label' => 'Home', 'href' => website_url('index.php')],
|
||||
['key' => 'servers', 'label' => 'Game Servers', 'href' => website_url('serverlist.php')],
|
||||
['key' => 'pricing', 'label' => 'Pricing', 'href' => website_url('pricing.php')],
|
||||
|
|
@ -19,18 +19,22 @@ if ($currentUser) {
|
|||
['key' => 'orders', 'label' => 'My Orders', 'href' => website_url('my_orders.php')],
|
||||
['key' => 'servers', 'label' => 'My Servers', 'href' => website_url('my_servers.php')],
|
||||
['key' => 'cart', 'label' => 'Cart' . ($cartCount > 0 ? ' (' . $cartCount . ')' : ''), 'href' => website_cart_url()],
|
||||
['key' => 'logout', 'label' => 'Logout', 'href' => website_url('logout.php')],
|
||||
];
|
||||
if (website_current_user_is_staff()) {
|
||||
$accountLinks[] = ['key' => 'staff', 'label' => 'Staff Dashboard', 'href' => website_url('staff.php')];
|
||||
}
|
||||
$accountLinks[] = ['key' => 'logout', 'label' => 'Logout', 'href' => website_url('logout.php')];
|
||||
$accountLabel = 'Account';
|
||||
} else {
|
||||
$accountLinks = [
|
||||
['key' => 'account', 'label' => 'Login', 'href' => website_login_url()],
|
||||
['key' => 'register', 'label' => 'Create Account', 'href' => website_register_url()],
|
||||
['key' => 'cart', 'label' => 'Cart' . ($cartCount > 0 ? ' (' . $cartCount . ')' : ''), 'href' => website_cart_url()],
|
||||
];
|
||||
$accountLabel = 'Account';
|
||||
}
|
||||
$staffLinks = ($currentUser && website_current_user_is_staff()) ? [
|
||||
['key' => 'staff', 'label' => 'Staff Dashboard', 'href' => website_url('staff.php')],
|
||||
] : [];
|
||||
$accountActiveKeys = array_column($accountLinks, 'key');
|
||||
$accountIsActive = in_array($activePage, $accountActiveKeys, true);
|
||||
?>
|
||||
<header class="site-header">
|
||||
<div class="container header-shell">
|
||||
|
|
@ -50,29 +54,21 @@ $staffLinks = ($currentUser && website_current_user_is_staff()) ? [
|
|||
</button>
|
||||
|
||||
<nav class="primary-nav" id="primary-nav" data-nav-menu aria-label="Primary navigation">
|
||||
<div class="nav-group nav-group-public">
|
||||
<?php foreach ($publicLinks as $link): ?>
|
||||
<?php foreach ($primaryLinks as $link): ?>
|
||||
<a class="nav-link<?= $activePage === $link['key'] ? ' is-active' : '' ?>" href="<?= website_escape($link['href']) ?>">
|
||||
<?= website_escape($link['label']) ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="nav-group nav-group-account" aria-label="Account navigation">
|
||||
<details class="account-menu" data-account-menu>
|
||||
<summary class="nav-link<?= $accountIsActive ? ' is-active' : '' ?>"><?= website_escape($accountLabel) ?></summary>
|
||||
<div class="account-menu-panel">
|
||||
<?php foreach ($accountLinks as $link): ?>
|
||||
<a class="nav-link<?= $activePage === $link['key'] ? ' is-active' : '' ?>" href="<?= website_escape($link['href']) ?>">
|
||||
<a class="account-menu-link<?= $activePage === $link['key'] ? ' is-active' : '' ?>" href="<?= website_escape($link['href']) ?>">
|
||||
<?= website_escape($link['label']) ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if (!empty($staffLinks)): ?>
|
||||
<div class="nav-group nav-group-staff" aria-label="Staff navigation">
|
||||
<?php foreach ($staffLinks as $link): ?>
|
||||
<a class="nav-link<?= $activePage === $link['key'] ? ' is-active' : '' ?>" href="<?= website_escape($link['href']) ?>">
|
||||
<?= website_escape($link['label']) ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</details>
|
||||
</nav>
|
||||
|
||||
<div class="header-actions" data-header-actions>
|
||||
|
|
|
|||
|
|
@ -77,12 +77,11 @@ Website footer account links are state-aware:
|
|||
- logged in: `My Account`, `Order a Server`, `Control Panel`, `My Servers`, `Log Out`
|
||||
- staff-only links appear only for Panel admin users and still enforce website staff authorization server-side
|
||||
|
||||
The shared header groups navigation by purpose:
|
||||
The shared header uses one responsive navigation bar:
|
||||
|
||||
- public: Home, Game Servers, Pricing, Locations, Documentation, Support
|
||||
- account: Login/Create Account/Cart or My Account/My Orders/My Servers/Cart/Logout
|
||||
- staff: Staff Dashboard, only for authorized website staff
|
||||
- actions: Custom Projects and Control Panel
|
||||
- primary links: Home, Game Servers, Pricing, Locations, Documentation, Support
|
||||
- account menu: Login/Create Account/Cart or My Account/My Orders/My Servers/Cart/Staff Dashboard/Logout
|
||||
- action buttons: Custom Projects and Control Panel
|
||||
|
||||
Control Panel links point directly to the configured Panel domain. `My Servers`
|
||||
opens a website customer page that summarizes website orders and links to the
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ Check:
|
|||
- expected catalog columns exist or can be added by the idempotent migration runner
|
||||
- `remote_servers` schema is the current Panel schema
|
||||
- the page is not assuming `remote_servers.enabled` exists
|
||||
- `website_table_exists()` is not using `SHOW TABLES LIKE ?`; MySQL does not support binding the table pattern in that statement through mysqli prepared placeholders
|
||||
|
||||
The current helper treats missing `remote_servers.enabled` as enabled for display and lets staff assign locations from current Panel remote-server rows.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue