ifnex/04_Laravel/resources/views/filament/hooks/head.blade.php
Kazem Alghasi 91984dbde3 feat(ui): redesign admin dashboard with layered grid and custom branding
Implement a comprehensive overhaul of the Filament admin dashboard,
introducing a structured 12-column responsive grid layout and enhanced
visual identity.

Key changes include:
- Redesigned Dashboard layout with a 4-layer progressive disclosure
  architecture (KPIs, Exchange Rates, Data Tables, and Trends).
- Introduced custom IFNEX design tokens via CSS, including branded
  stat cards, status badges, and improved sidebar typography.
- Enhanced FinanceOverviewWidget with real-time trend analysis and
  sparkline-ready data structures.
- Refactored RecentShipments and RecentTransactions widgets to use
  custom Blade templates for a more polished, consistent UI.
- Integrated brand assets including the company logo and custom
  authentication pages.
- Added global number formatting helpers and integrated them into
  financial widgets.
- Updated AdminPanelProvider to support custom login pages and
  brand-specific header/footer hooks.
2026-10-03 11:08:50 +03:30

498 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- فونت وزیرمتن برای فارسی -->
<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: #f8fafc !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;
}
/* ─── زیرمنوها: متن سفید پیش‌فرض، سفیدِ کامل در هاور، کهربایی برای آیتم فعال ─── */
.fi-sidebar-item a .fi-sidebar-item-label {
color: #e2e8f0 !important;
}
.fi-sidebar-item a .fi-icon {
color: #cbd5e1 !important;
}
/* هاور زیرمنو: پس‌زمینه روشن می‌شود → متن تیره برای خوانایی */
.fi-sidebar-item a:hover .fi-sidebar-item-label {
color: #1e293b !important;
}
.fi-sidebar-item a:hover .fi-icon {
color: #1e293b !important;
}
/* در دارک‌مود پس‌زمینه هاور تیره می‌ماند → متن سفید */
.dark .fi-sidebar-item a:hover .fi-sidebar-item-label,
.dark .fi-sidebar-item a:hover .fi-icon {
color: #ffffff !important;
}
/* آیتم فعال همان کهربایی برند می‌ماند (بعد از قواعد سفید تا اولویت بگیرد) */
.fi-sidebar-item-active > a .fi-sidebar-item-label {
color: #f59e0b !important;
}
.fi-sidebar-item-active > a .fi-icon {
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: #f1f5f9;
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;
}
/* ─── IFNEX Dashboard redesign — card / badge / trend design tokens ─── */
/* Base card: rounded-2xl, soft multi-layer shadow, 1px gray-200 border */
.ifnex-card-shadow,
.ifnex-card {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.08),
0 1px 2px rgba(0, 0, 0, 0.04) !important;
}
/* Stat card base — used by StatsOverviewWidget cards */
.fi-wi-stats-overview-stat.ifnex-stat-card {
border-radius: 16px !important;
border: 1px solid #e5e7eb !important;
padding: 1.25rem !important;
background: #FAF9F6 !important;
}
.dark .fi-wi-stats-overview-stat.ifnex-stat-card {
background: rgb(30 41 59) !important;
border-color: rgb(51 65 85) !important;
}
.ifnex-stat-card {
border-radius: 16px !important;
border: 1px solid #e5e7eb !important;
padding: 1.25rem !important;
background: #FAF9F6 !important;
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.08),
0 1px 2px rgba(0, 0, 0, 0.04) !important;
transition: transform 0.25s ease, box-shadow 0.25s ease !important;
}
.ifnex-stat-card:hover {
transform: translateY(-2px);
box-shadow:
0 10px 25px rgba(0, 0, 0, 0.10),
0 4px 6px rgba(0, 0, 0, 0.05) !important;
}
/* Stat icon — colored soft circle (40×40), centered heroicon */
.ifnex-stat-icon {
width: 40px;
height: 40px;
border-radius: 12px;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.ifnex-stat-icon-amber { background: #fef3c7; color: #d97706; }
.ifnex-stat-icon-green { background: #d1fae5; color: #059669; }
.ifnex-stat-icon-red { background: #fee2e2; color: #dc2626; }
.ifnex-stat-icon-blue { background: #dbeafe; color: #2563eb; }
.ifnex-stat-icon-gray { background: #f1f5f9; color: #475569; }
.dark .ifnex-stat-icon-amber { background: rgba(245,158,11,.18); color: #fbbf24; }
.dark .ifnex-stat-icon-green { background: rgba(16,185,129,.18); color: #34d399; }
.dark .ifnex-stat-icon-red { background: rgba(239,68,68,.18); color: #f87171; }
.dark .ifnex-stat-icon-blue { background: rgba(59,130,246,.18); color: #60a5fa; }
.dark .ifnex-stat-icon-gray { background: rgba(148,163,184,.18); color: #cbd5e1; }
/* Big number typography */
.ifnex-stat-number {
font-family: 'Vazirmatn', sans-serif !important;
font-size: 28px;
line-height: 1.2;
font-weight: 800;
color: #111827;
letter-spacing: -0.5px;
}
.dark .ifnex-stat-number { color: #f9fafb; }
/* Stat label */
.ifnex-stat-label {
font-family: 'Vazirmatn', sans-serif !important;
font-size: 12px;
font-weight: 500;
color: #6b7280;
}
.dark .ifnex-stat-label { color: #9ca3af; }
/* Trend indicators */
.ifnex-stat-trend-up {
color: #10b981;
font-weight: 600;
font-size: 12px;
}
.ifnex-stat-trend-down {
color: #ef4444;
font-weight: 600;
font-size: 12px;
}
.ifnex-stat-trend-flat {
color: #9ca3af;
font-weight: 600;
font-size: 12px;
}
/* ─── Brand status badges ─── */
.ifnex-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 0.125rem 0.625rem;
border-radius: 9999px;
font-size: 11.5px;
font-weight: 600;
line-height: 1.4;
white-space: nowrap;
}
.ifnex-badge-success { background: #d1fae5; color: #047857; }
.ifnex-badge-warning { background: #fef3c7; color: #b45309; }
.ifnex-badge-danger { background: #fee2e2; color: #b91c1c; }
.ifnex-badge-info { background: #dbeafe; color: #1d4ed8; }
.ifnex-badge-gray { background: #f1f5f9; color: #475569; }
.dark .ifnex-badge-success { background: rgba(16,185,129,.18); color: #6ee7b7; }
.dark .ifnex-badge-warning { background: rgba(245,158,11,.18); color: #fcd34d; }
.dark .ifnex-badge-danger { background: rgba(239,68,68,.18); color: #fca5a5; }
.dark .ifnex-badge-info { background: rgba(59,130,246,.18); color: #93c5fd; }
.dark .ifnex-badge-gray { background: rgba(148,163,184,.18); color: #cbd5e1; }
/* ─── Table row hover (Layer 3 tables) ─── */
.ifnex-table-row-hover:hover {
background-color: #fffbeb !important;
}
.dark .ifnex-table-row-hover:hover {
background-color: rgba(245, 158, 11, 0.08) !important;
}
/* Compact table cells + headers used by ifnex widgets */
.ifnex-th {
padding: 0.625rem 0.75rem;
font-size: 11.5px;
font-weight: 600;
text-transform: none;
}
.ifnex-td {
padding: 0.625rem 0.75rem;
vertical-align: middle;
}
/* Inline link (e.g. "مشاهده همه ←") */
.ifnex-link-inline {
display: inline-flex;
align-items: center;
gap: 2px;
}
/* ─── Stat card icon color tinting for IFNEX KPIs ─── */
.fi-wi-stats-overview-stat .fi-icon,
.fi-stat-icon {
border-radius: 12px !important;
}
</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');
}
}
// ⚠️ کلیک روی عنوان گروه را خود فیلامنت به‌صورت بومی هندل می‌کند
// (x-on:click روی .fi-sidebar-group-button در vendor) — هندلر اضافه اینجا
// باعث toggle دوباره و در نتیجه «هیچ اتفاقی نمی‌افتد» می‌شد؛ حذف شد.
// دکمه «بستن/باز کردن همه» بالای سایدبار
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>