242 lines
18 KiB
PHP
242 lines
18 KiB
PHP
<!-- Sidebar -->
|
|
<aside :class="sidebarOpen ? 'translate-x-0' : (is_rtl() ? '-translate-x-full' : 'translate-x-full')"
|
|
class="fixed inset-y-0 start-0 w-64 bg-white border-e border-gray-200 z-30 transform transition-transform duration-300 ease-in-out lg:translate-x-0 overflow-y-auto"
|
|
@media.min-width.lg="{ sidebarOpen: true }">
|
|
|
|
<!-- Logo -->
|
|
<div class="h-16 flex items-center gap-3 px-4 border-b border-gray-200">
|
|
<div class="w-8 h-8 bg-teal-600 rounded-lg flex items-center justify-center">
|
|
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
|
|
</svg>
|
|
</div>
|
|
<span class="text-lg font-bold text-gray-900">Vernova</span>
|
|
</div>
|
|
|
|
<!-- Navigation -->
|
|
<nav class="p-3 space-y-1">
|
|
|
|
{{-- Dashboard --}}
|
|
@php $isDashboardActive = request()->routeIs('dashboard*') || request()->is('/'); @endphp
|
|
<a href="{{ route('dashboard') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isDashboardActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
|
|
</svg>
|
|
<span>{{ __('nav.dashboard') }}</span>
|
|
</a>
|
|
|
|
{{-- Projects --}}
|
|
@php $isProjectsActive = request()->routeIs('projects.*'); @endphp
|
|
<a href="{{ route('projects.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isProjectsActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
|
|
</svg>
|
|
<span>{{ __('nav.projects') }}</span>
|
|
</a>
|
|
|
|
{{-- Tasks with sub-menu --}}
|
|
@php $isTasksActive = request()->routeIs('tasks.*'); @endphp
|
|
<div x-data="{ open: {{ $isTasksActive ? 'true' : 'false' }} }">
|
|
<button @click="open = !open"
|
|
class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isTasksActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/>
|
|
</svg>
|
|
<span class="flex-1 text-start">{{ __('nav.tasks') }}</span>
|
|
<svg class="w-4 h-4 transition-transform duration-200" :class="open ? 'rotate-90' : ''" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
|
</svg>
|
|
</button>
|
|
<div x-show="open" x-transition class="ms-6 mt-1 space-y-1">
|
|
<a href="{{ route('tasks.index') }}"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors duration-150
|
|
{{ request()->routeIs('tasks.index') ? 'bg-teal-50 text-teal-700 font-medium' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<span class="w-1.5 h-1.5 rounded-full {{ request()->routeIs('tasks.index') ? 'bg-teal-500' : 'bg-gray-400' }}"></span>
|
|
{{ __('task.listView') }}
|
|
</a>
|
|
<a href="{{ route('tasks.kanban') }}"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors duration-150
|
|
{{ request()->routeIs('tasks.kanban') ? 'bg-teal-50 text-teal-700 font-medium' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<span class="w-1.5 h-1.5 rounded-full {{ request()->routeIs('tasks.kanban') ? 'bg-teal-500' : 'bg-gray-400' }}"></span>
|
|
{{ __('task.kanban') }}
|
|
</a>
|
|
<a href="{{ route('tasks.gantt') }}"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors duration-150
|
|
{{ request()->routeIs('tasks.gantt') ? 'bg-teal-50 text-teal-700 font-medium' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<span class="w-1.5 h-1.5 rounded-full {{ request()->routeIs('tasks.gantt') ? 'bg-teal-500' : 'bg-gray-400' }}"></span>
|
|
{{ __('task.gantt') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Expenses --}}
|
|
@php $isExpensesActive = request()->routeIs('expenses.*'); @endphp
|
|
<a href="{{ route('expenses.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isExpensesActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z"/>
|
|
</svg>
|
|
<span>{{ __('nav.expenses') }}</span>
|
|
</a>
|
|
|
|
{{-- Employees --}}
|
|
@php $isEmployeesActive = request()->routeIs('employees.*'); @endphp
|
|
<a href="{{ route('employees.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isEmployeesActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
|
|
</svg>
|
|
<span>{{ __('nav.employees') }}</span>
|
|
</a>
|
|
|
|
{{-- Petty Cash --}}
|
|
@php $isPettyCashActive = request()->routeIs('petty-cashes.*'); @endphp
|
|
<a href="{{ route('petty-cashes.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isPettyCashActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"/>
|
|
</svg>
|
|
<span>{{ __('nav.pettyCash') }}</span>
|
|
</a>
|
|
|
|
{{-- Warehouse with sub-menu --}}
|
|
@php $isWarehouseActive = request()->routeIs('inventory.*'); @endphp
|
|
<div x-data="{ open: {{ $isWarehouseActive ? 'true' : 'false' }} }">
|
|
<button @click="open = !open"
|
|
class="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isWarehouseActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/>
|
|
</svg>
|
|
<span class="flex-1 text-start">{{ __('nav.warehouse') }}</span>
|
|
<svg class="w-4 h-4 transition-transform duration-200" :class="open ? 'rotate-90' : ''" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
|
</svg>
|
|
</button>
|
|
<div x-show="open" x-transition class="ms-6 mt-1 space-y-1">
|
|
<a href="{{ route('inventory.index') }}"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors duration-150
|
|
{{ request()->routeIs('inventory.index') ? 'bg-teal-50 text-teal-700 font-medium' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<span class="w-1.5 h-1.5 rounded-full {{ request()->routeIs('inventory.index') ? 'bg-teal-500' : 'bg-gray-400' }}"></span>
|
|
{{ __('inventory.dashboard') ?? 'داشبورد' }}
|
|
</a>
|
|
<a href="{{ route('inventory.items') }}"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors duration-150
|
|
{{ request()->routeIs('inventory.items') ? 'bg-teal-50 text-teal-700 font-medium' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<span class="w-1.5 h-1.5 rounded-full {{ request()->routeIs('inventory.items') ? 'bg-teal-500' : 'bg-gray-400' }}"></span>
|
|
{{ __('inventory.items') }}
|
|
</a>
|
|
<a href="{{ route('inventory.warehouses') }}"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors duration-150
|
|
{{ request()->routeIs('inventory.warehouses') ? 'bg-teal-50 text-teal-700 font-medium' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<span class="w-1.5 h-1.5 rounded-full {{ request()->routeIs('inventory.warehouses') ? 'bg-teal-500' : 'bg-gray-400' }}"></span>
|
|
{{ __('inventory.warehouses') }}
|
|
</a>
|
|
<a href="{{ route('inventory.transactions') }}"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors duration-150
|
|
{{ request()->routeIs('inventory.transactions') ? 'bg-teal-50 text-teal-700 font-medium' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<span class="w-1.5 h-1.5 rounded-full {{ request()->routeIs('inventory.transactions') ? 'bg-teal-500' : 'bg-gray-400' }}"></span>
|
|
{{ __('inventory.transactions') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Letters --}}
|
|
@php $isLettersActive = request()->routeIs('letters.*'); @endphp
|
|
<a href="{{ route('letters.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isLettersActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
|
|
</svg>
|
|
<span>{{ __('nav.letters') }}</span>
|
|
</a>
|
|
|
|
{{-- Documents --}}
|
|
@php $isDocumentsActive = request()->routeIs('documents.*'); @endphp
|
|
<a href="{{ route('documents.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isDocumentsActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/>
|
|
</svg>
|
|
<span>{{ __('nav.documents') }}</span>
|
|
</a>
|
|
|
|
{{-- Payroll --}}
|
|
@php $isPayrollActive = request()->routeIs('payroll.*'); @endphp
|
|
<a href="{{ route('payroll.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isPayrollActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z"/>
|
|
</svg>
|
|
<span>{{ __('nav.payroll') }}</span>
|
|
</a>
|
|
|
|
{{-- Reports --}}
|
|
@php $isReportsActive = request()->routeIs('reports.*'); @endphp
|
|
<a href="{{ route('reports.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isReportsActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
|
</svg>
|
|
<span>{{ __('nav.reports') }}</span>
|
|
</a>
|
|
|
|
{{-- Divider --}}
|
|
<div class="border-t border-gray-100 my-2"></div>
|
|
|
|
{{-- Settings --}}
|
|
@php $isSettingsActive = request()->routeIs('settings.*'); @endphp
|
|
<a href="{{ route('settings.index') }}"
|
|
class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors duration-150
|
|
{{ $isSettingsActive ? 'bg-teal-50 text-teal-700 border border-teal-200' : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900' }}">
|
|
<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
|
</svg>
|
|
<span>{{ __('nav.settings') }}</span>
|
|
</a>
|
|
</nav>
|
|
|
|
<!-- User Info -->
|
|
@auth
|
|
<div class="absolute bottom-0 start-0 end-0 p-3 border-t border-gray-200 bg-white">
|
|
<div class="flex items-center gap-3 px-3 py-2">
|
|
<div class="w-9 h-9 bg-teal-100 text-teal-700 rounded-full flex items-center justify-center text-sm font-semibold">
|
|
{{ mb_strtoupper(mb_substr(auth()->user()->name, 0, 1)) }}
|
|
</div>
|
|
<div class="flex-1 min-w-0">
|
|
<p class="text-sm font-medium text-gray-900 truncate">{{ auth()->user()->name }}</p>
|
|
<p class="text-xs text-gray-500 truncate">{{ auth()->user()->email }}</p>
|
|
</div>
|
|
<form method="POST" action="{{ route('logout') }}" class="inline">
|
|
@csrf
|
|
<button type="submit" class="p-1.5 text-gray-400 hover:text-red-500 transition-colors" title="{{ __('auth.logout') }}">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/>
|
|
</svg>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endauth
|
|
</aside>
|
|
|
|
<!-- Mobile Overlay -->
|
|
<div x-show="sidebarOpen" x-transition:enter="transition-opacity ease-linear duration-300"
|
|
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
|
|
x-transition:leave="transition-opacity ease-linear duration-300"
|
|
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
|
@click="sidebarOpen = false"
|
|
class="fixed inset-0 bg-gray-900/50 z-20 lg:hidden"></div>
|