ifnex/04_Laravel/resources/views/filament/hooks/head.blade.php
Kazem Alghasi c54530d8da refactor(admin): optimize dashboard layout and enhance sidebar UX
Refactor the Filament admin dashboard by decoupling the recent shipments
logic into a dedicated widget and improving the sidebar navigation
experience. Additionally, implement several improvements to the
WordPress theme for better client-side usability.

Laravel/Filament:
- Extract `RecentShipmentsWidget` from `DashboardInfoWidget` to improve
  modularization and dashboard performance.
- Update widget sorting and layout to accommodate the new structure.
- Inject custom CSS and Alpine.js logic into the admin head to provide
  sidebar group toggling and a "collapse all" utility.
- Improve sidebar group label visibility and hover states.

WordPress:
- Implement `ifnex_login_url()` to support Polylang-aware, language-specific
  login pages.
- Hide the WordPress admin bar for non-administrator users to provide a
  cleaner client interface.
- Add conditional rendering for the registration link in the login
  template based on WordPress user registration settings.
2026-10-03 07:01:54 +03:30

318 lines
10 KiB
PHP

<!-- فونت وزیرمتن برای فارسی -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<style>
/* ─── تنظیمات پایه RTL ─── */
html {
direction: rtl;
font-family: 'Vazirmatn', 'IranYekan', Tahoma, sans-serif !important;
}
body {
font-family: 'Vazirmatn', 'IranYekan', Tahoma, sans-serif !important;
}
/* ─── Sidebar استایل سفارشی ─── */
.fi-sidebar {
background: linear-gradient(180deg, #1a1a2e 0%, #16213e 100%) !important;
}
.fi-sidebar-item a {
transition: all 0.25s cubic-bezier(.4,0,.2,1);
}
.fi-sidebar-item-active > a {
background: rgba(245, 158, 11, 0.15) !important;
border-right: 3px solid #f59e0b !important;
}
.fi-sidebar-item-active > a .fi-sidebar-item-label {
color: #f59e0b !important;
font-weight: 700;
}
.fi-sidebar-item-active > a .fi-icon {
color: #f59e0b !important;
}
/* ─── دکمه‌ها ─── */
.fi-btn.fi-btn-color-primary {
box-shadow: 0 8px 20px rgba(245, 158, 11, 0.35);
}
/* ─── کارت‌های Stat ─── */
.fi-wi-stats-overview-stat {
border-radius: 16px !important;
border: 1px solid #e5e7eb;
}
/* ─── Logo استایل ─── */
.fi-brand {
font-family: 'Vazirmatn', sans-serif;
font-weight: 900;
letter-spacing: -0.5px;
}
.fi-brand-name {
font-family: 'Vazirmatn', sans-serif !important;
font-weight: 900 !important;
}
/* ─── اعداد فارسی ─── */
.fi-wi-stats-overview-stat-value,
.fi-tables-column-type-numeric {
font-family: 'Vazirmatn', sans-serif !important;
}
/* ─── Dark Mode بهبودها ─── */
.dark .fi-sidebar {
background: linear-gradient(180deg, #0f172a 0%, #1a1a2e 100%) !important;
}
.dark .fi-sidebar-item-active > a {
background: rgba(245, 158, 11, 0.2) !important;
}
/* ─── Notifications badge ─── */
.fi-badge {
font-family: 'Vazirmatn', sans-serif !important;
}
/* ─── Tables RTL fix ─── */
.fi-ta-ctn {
direction: rtl;
}
.fi-ta-header-heading {
font-family: 'Vazirmatn', sans-serif;
font-weight: 700;
}
/* ─── Forms RTL ─── */
.fi-input-wrp {
direction: rtl;
}
.fi-input-wrp-input {
text-align: right;
}
/* ─── Login Page بهبود ─── */
.fi-auth-layout {
background: linear-gradient(135deg, #1a0a00 0%, #3d1a00 30%, #7c3100 60%, #d97706 85%, #f59e0b 100%);
}
.fi-auth-card {
backdrop-filter: blur(20px);
background: rgba(255, 255, 255, 0.97) !important;
border-radius: 20px !important;
box-shadow: 0 25px 80px rgba(0, 0, 0, 0.25) !important;
}
.fi-login-heading {
font-family: 'Vazirmatn', sans-serif;
font-weight: 800;
color: #111827;
}
/* ─── Scrollbar سفارشی ─── */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #f1f5f9;
}
::-webkit-scrollbar-thumb {
background: #f59e0b;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #d97706;
}
/* ─── Page transitions ─── */
.fi-section {
transition: all 0.3s ease;
}
/* ─── Fix برای اعداد فارسی ─── */
.fi-wi-stats-overview-stat-description,
.fi-wi-stats-overview-stat-label {
font-family: 'Vazirmatn', sans-serif;
}
/* ─── Stats card hover ─── */
.fi-wi-stats-overview-stat:hover {
transform: translateY(-4px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
/* ─── Badge colors ─── */
.fi-badge.fi-badge-color-success {
background: #d1fae5 !important;
color: #065f46 !important;
}
.fi-badge.fi-badge-color-danger {
background: #fee2e2 !important;
color: #991b1b !important;
}
.fi-badge.fi-badge-color-warning {
background: #fef3c7 !important;
color: #92400e !important;
}
/* ─── فشرده‌سازی جداول فیلمنت (فونت کوچک‌تر + padding کمتر) ─── */
.fi-ta-text,
.fi-ta-text-content {
font-size: 0.8125rem !important; /* 13px به‌جای 14px پیش‌فرض */
line-height: 1.4 !important;
}
.fi-ta-header-heading {
font-size: 0.75rem !important; /* سرست 12px */
font-weight: 600 !important;
}
.fi-ta-cell,
.fi-ta-header-cell {
padding: 0.5rem 0.625rem !important; /* فشرده‌تر */
}
.fi-ta-text-wrap {
gap: 0.125rem !important;
}
/* ─── عناوین گروه‌های سایدبار: سفید روی پس‌زمینه تیره ─── */
.fi-sidebar-group-label {
color: #e2e8f0 !important;
font-weight: 600 !important;
}
.fi-sidebar-group-icon {
color: #cbd5e1 !important;
}
.fi-sidebar-group-collapse-button {
color: #cbd5e1 !important;
}
.fi-sidebar-group-button:hover .fi-sidebar-group-label,
.fi-sidebar-group-button:hover .fi-sidebar-group-icon,
.fi-sidebar-group-button:hover .fi-sidebar-group-collapse-button {
color: #f59e0b !important;
}
/* ─── دکمه بستن/باز کردن همه منوها ─── */
.ifnex-sidebar-collapse-all {
display: block;
width: calc(100% - 16px);
margin: 4px 8px 8px;
padding: 7px 10px;
font-size: 11.5px;
font-family: inherit;
color: #cbd5e1;
background: rgba(255, 255, 255, .06);
border: 1px solid rgba(255, 255, 255, .14);
border-radius: 8px;
cursor: pointer;
text-align: center;
transition: all .2s;
}
.ifnex-sidebar-collapse-all:hover {
background: rgba(245, 158, 11, .15);
border-color: rgba(245, 158, 11, .35);
color: #f59e0b;
}
</style>
<script>
/* ─── گروه‌های سایدبار: پیش‌فرض بسته + کلیک روی عنوان + دکمه بستن/باز کردن همه ───
از استور بومی Alpine فیلامنت (sidebar.collapsedGroups) استفاده می‌کند؛
بنابراین وضعیت هر گروه در localStorage فیلامنت حفظ می‌شود. */
(function () {
function groupLabels() {
return Array.from(document.querySelectorAll('.fi-sidebar-group-label'))
.map(function (el) { return el.textContent.trim(); })
.filter(Boolean);
}
function collapseAll(store) {
groupLabels().forEach(function (label) { store.collapseGroup(label); });
}
function expandAll(store) {
groupLabels().forEach(function (label) {
if (store.groupIsCollapsed(label)) store.toggleCollapsedGroup(label);
});
}
// بار اول برای هر مرورگر: همه منوها بسته باشند؛ بعد از آن انتخاب کاربر محترم است
function initDefaultCollapsed() {
if (!window.Alpine) return;
var store = window.Alpine.store('sidebar');
if (!store || typeof store.collapseGroup !== 'function') return;
if (!localStorage.getItem('ifnex-sidebar-default-collapsed')) {
collapseAll(store);
localStorage.setItem('ifnex-sidebar-default-collapsed', '1');
}
}
// کلیک روی ردیف عنوان گروه = باز/بسته کردن گروه (علاوه بر دکمه فلش)
document.addEventListener('click', function (e) {
var btn = e.target.closest('.fi-sidebar-group-button');
if (!btn || e.target.closest('.fi-sidebar-group-collapse-button')) return;
if (!window.Alpine) return;
var store = window.Alpine.store('sidebar');
if (!store) return;
var labelEl = btn.querySelector('.fi-sidebar-group-label');
// در حالت جمع‌شدهٔ کناری (فقط آیکون)، عنوان مخفی است — نادیده بگیر
if (!labelEl || labelEl.offsetParent === null) return;
var label = labelEl.textContent.trim();
if (label) store.toggleCollapsedGroup(label);
});
// دکمه «بستن/باز کردن همه» بالای سایدبار
function injectToggle() {
if (!document.querySelector('.fi-main-sidebar') || document.querySelector('.ifnex-sidebar-collapse-all')) return;
var nav = document.querySelector('.fi-main-sidebar .fi-sidebar-nav');
if (!nav) return;
var b = document.createElement('button');
b.type = 'button';
b.className = 'ifnex-sidebar-collapse-all';
b.textContent = 'بستن همه منوها ⌃';
b.dataset.mode = 'collapse';
b.addEventListener('click', function () {
if (!window.Alpine) return;
var store = window.Alpine.store('sidebar');
if (!store) return;
if (b.dataset.mode === 'collapse') {
collapseAll(store);
b.textContent = 'باز کردن همه منوها ⌄';
b.dataset.mode = 'expand';
} else {
expandAll(store);
b.textContent = 'بستن همه منوها ⌃';
b.dataset.mode = 'collapse';
}
});
nav.insertBefore(b, nav.firstChild);
}
function boot() { initDefaultCollapsed(); injectToggle(); }
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
// SPA: بعد از هر ناوبری لایووایر، اگر سایدبار تازه رندر شده دکمه را تزریق کن
document.addEventListener('livewire:navigated', injectToggle);
})();
</script>