|
1 | 1 | @php |
2 | 2 | /** @var array<int,array{slug:string,title:string}> $items */ |
| 3 | + /** @var string $active */ |
3 | 4 |
|
4 | | - // Group items by category for better organization |
5 | | - $groupedItems = collect($items)->groupBy(function ($item) { |
| 5 | + // 1. Determine Current Context |
| 6 | + $activeParts = explode('/', $active ?? ''); |
| 7 | + $currentContext = count($activeParts) > 1 ? $activeParts[0] : 'General'; |
| 8 | +
|
| 9 | + // 2. Filter Items for Context |
| 10 | + $contextItems = collect($items)->filter(function ($item) use ($currentContext) { |
6 | 11 | $parts = explode('/', $item['slug']); |
7 | | - return count($parts) > 1 ? $parts[0] : 'Getting Started'; |
| 12 | + $itemContext = count($parts) > 1 ? $parts[0] : 'General'; |
| 13 | + return $itemContext === $currentContext; |
| 14 | + }); |
| 15 | +
|
| 16 | + // 3. Group by Sub-category (if exists) or fallback to 'Main' |
| 17 | + $groupedItems = $contextItems->groupBy(function ($item) use ($currentContext) { |
| 18 | + // Remove context from slug to find sub-category |
| 19 | + $relSlug = $currentContext === 'General' ? $item['slug'] : substr($item['slug'], strlen($currentContext) + 1); |
| 20 | + |
| 21 | + if (empty($relSlug)) { |
| 22 | + return 'Main'; |
| 23 | + } |
| 24 | +
|
| 25 | + $parts = explode('/', $relSlug); |
| 26 | + |
| 27 | + return (count($parts) > 1 && !empty($parts[0])) ? $parts[0] : 'Main'; |
| 28 | + }); |
| 29 | +
|
| 30 | + // Sort groups: 'Main' first, then alphabetical or bespoke order |
| 31 | + $groupedItems = $groupedItems->sortBy(function ($items, $key) { |
| 32 | + return $key === 'Main' ? '000' : $key; |
8 | 33 | }); |
9 | 34 |
|
10 | 35 | $locale = app()->getLocale(); |
11 | 36 | $isRtl = in_array($locale, config('pertuk.rtl_locales', ['ar', 'ckb'])); |
| 37 | + $routePrefix = config('pertuk.route_prefix', 'docs'); |
12 | 38 | @endphp |
13 | 39 |
|
14 | | -<nav class="space-y-6"> |
| 40 | +<nav class="space-y-6" x-data="{ search: '' }"> |
| 41 | + <!-- Sidebar Search --> |
| 42 | + <div class="mb-4"> |
| 43 | + <div class="relative"> |
| 44 | + <div class="absolute inset-y-0 start-0 ps-3 flex items-center pointer-events-none"> |
| 45 | + <svg class="h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 46 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/> |
| 47 | + </svg> |
| 48 | + </div> |
| 49 | + <input type="text" |
| 50 | + x-model="search" |
| 51 | + placeholder="{{ __('Filter navigation...') }}" |
| 52 | + class="w-full rounded-md border border-gray-300 bg-white px-3 py-1.5 ps-9 text-sm text-gray-900 focus:border-orange-500 focus:outline-none focus:ring-1 focus:ring-orange-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:focus:ring-orange-500/50" |
| 53 | + > |
| 54 | + </div> |
| 55 | + </div> |
| 56 | + |
15 | 57 | @foreach ($groupedItems as $category => $categoryItems) |
16 | | - <div class="space-y-3"> |
17 | | - @if ($category !== 'Getting Started' || $groupedItems->count() > 1) |
18 | | - <h3 class="text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400 px-3"> |
| 58 | + <div class="space-y-2" x-show="!search || $el.textContent.toLowerCase().includes(search.toLowerCase())"> |
| 59 | + @if ($category !== 'Main' || $groupedItems->count() > 1) |
| 60 | + <h3 class="text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400 px-3 truncate" title="{{ str_replace('-', ' ', ucfirst($category)) }}"> |
19 | 61 | {{ str_replace('-', ' ', ucfirst($category)) }} |
20 | 62 | </h3> |
21 | 63 | @endif |
22 | 64 |
|
23 | | - <ul class="space-y-1"> |
| 65 | + <ul class="space-y-0.5"> |
24 | 66 | @foreach ($categoryItems as $item) |
25 | 67 | @php |
26 | 68 | $isActive = ($active ?? '') === $item['slug']; |
27 | 69 | $displayTitle = $item['title']; |
28 | 70 |
|
29 | | - // Clean up title if it contains category prefix |
| 71 | + // Cleanup title: remove context/category prefixes for cleaner sidebar |
30 | 72 | if (str_contains($item['title'], ':')) { |
31 | | - $displayTitle = trim(explode(':', $item['title'], 2)[1] ?? $item['title']); |
| 73 | + $parts = explode(':', $item['title']); |
| 74 | + $displayTitle = trim(end($parts)); |
32 | 75 | } |
33 | 76 | @endphp |
34 | 77 |
|
35 | | - <li> |
36 | | - <a href="{{ url('/' . config('pertuk.route_prefix', 'docs') . '/' . $locale . '/' . $item['slug']) }}" |
37 | | - class="group flex items-center rounded-md px-3 py-2 text-sm font-medium transition-colors duration-200 @if ($isActive) bg-orange-50 text-orange-700 dark:bg-orange-900/20 dark:text-orange-400 @else text-gray-700 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-white @endif" |
| 78 | + <li x-show="!search || '{{ strtolower($displayTitle) }}'.includes(search.toLowerCase())"> |
| 79 | + <a href="{{ url('/' . $routePrefix . '/' . $locale . '/' . $item['slug']) }}" |
| 80 | + class="group flex items-center rounded-md px-3 py-1.5 text-sm font-medium transition-colors duration-200 border-l-2 {{ $isActive ? 'border-orange-500 bg-orange-50 text-orange-700 dark:bg-orange-900/20 dark:text-orange-400' : 'border-transparent text-gray-600 hover:text-gray-900 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200' }}" |
38 | 81 | @if ($isActive) aria-current="page" @endif> |
39 | | - @if ($isActive) |
40 | | - <svg class=" h-2 w-2 flex-shrink-0 text-orange-500" fill="currentColor" viewBox="0 0 8 8"> |
41 | | - <circle cx="4" cy="4" r="3" /> |
42 | | - </svg> |
43 | | - @endif |
44 | | - |
| 82 | + |
45 | 83 | <span class="truncate">{{ $displayTitle }}</span> |
46 | | - |
47 | | - @if ($isActive) |
48 | | - <svg class="{{ $isRtl ? 'mr-auto rotate-180' : 'ml-auto' }} h-4 w-4 flex-shrink-0 text-orange-500" |
49 | | - fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
50 | | - <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" |
51 | | - d="M9 5l7 7-7 7" /> |
52 | | - </svg> |
53 | | - @endif |
54 | 84 | </a> |
55 | 85 | </li> |
56 | 86 | @endforeach |
57 | 87 | </ul> |
58 | 88 | </div> |
59 | 89 | @endforeach |
60 | | - |
61 | | - <!-- Quick Links Section --> |
62 | | - <div class="border-t border-gray-200 dark:border-gray-700 pt-6 space-y-3"> |
63 | | - <h3 class="text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400 px-3"> |
64 | | - Quick Links |
65 | | - </h3> |
66 | | - |
67 | | - <ul class="space-y-1"> |
68 | | - <li> |
69 | | - <a href="https://github.com/your-repo" target="_blank" rel="noopener noreferrer" |
70 | | - class="group flex items-center rounded-md px-3 py-2 text-sm font-medium text-gray-700 transition-colors duration-200 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-white"> |
71 | | - <svg class=" h-4 w-4 flex-shrink-0 text-gray-400 group-hover:text-gray-500" fill="currentColor" |
72 | | - viewBox="0 0 24 24"> |
73 | | - <path |
74 | | - d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.30.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" /> |
75 | | - </svg> |
76 | | - <span>GitHub</span> |
77 | | - </a> |
78 | | - </li> |
79 | | - </ul> |
| 90 | + |
| 91 | + <div x-show="search && $el.previousElementSibling.children.length === 0" class="px-3 text-sm text-gray-500 dark:text-gray-400 text-center py-4"> |
| 92 | + {{ __('No results found') }} |
80 | 93 | </div> |
81 | 94 | </nav> |
0 commit comments