|
| 1 | +@extends('feature-requests::layouts.public') |
| 2 | + |
| 3 | +@section('title', 'Feature Requests Roadmap') |
| 4 | + |
| 5 | +@section('content') |
| 6 | +<div class="min-h-screen bg-gray-50"> |
| 7 | + <!-- Header --> |
| 8 | + <div class="bg-white shadow-sm border-b"> |
| 9 | + <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> |
| 10 | + <div class="py-6"> |
| 11 | + <div class="flex items-center justify-between"> |
| 12 | + <div> |
| 13 | + <h1 class="text-3xl font-bold text-gray-900">Feature Requests Roadmap</h1> |
| 14 | + <p class="mt-2 text-gray-600">Track the progress of feature requests from idea to completion</p> |
| 15 | + </div> |
| 16 | + <div class="flex space-x-3"> |
| 17 | + <a href="{{ route('feature-requests.index') }}" |
| 18 | + class="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
| 19 | + <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 20 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"></path> |
| 21 | + </svg> |
| 22 | + All Requests |
| 23 | + </a> |
| 24 | + <a href="{{ route('feature-requests.create') }}" |
| 25 | + class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
| 26 | + <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 27 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path> |
| 28 | + </svg> |
| 29 | + Submit Request |
| 30 | + </a> |
| 31 | + </div> |
| 32 | + </div> |
| 33 | + </div> |
| 34 | + </div> |
| 35 | + </div> |
| 36 | + |
| 37 | + <!-- Filters --> |
| 38 | + <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6"> |
| 39 | + <div class="bg-white rounded-lg shadow-sm border p-6 mb-6"> |
| 40 | + <form method="GET" action="{{ route('feature-requests.roadmap') }}" class="flex flex-wrap gap-4"> |
| 41 | + <div class="flex-1 min-w-64"> |
| 42 | + <label for="search" class="block text-sm font-medium text-gray-700 mb-2">Search</label> |
| 43 | + <input type="text" |
| 44 | + name="search" |
| 45 | + id="search" |
| 46 | + value="{{ request('search') }}" |
| 47 | + placeholder="Search feature requests..." |
| 48 | + class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
| 49 | + </div> |
| 50 | + <div class="min-w-48"> |
| 51 | + <label for="category_id" class="block text-sm font-medium text-gray-700 mb-2">Category</label> |
| 52 | + <select name="category_id" |
| 53 | + id="category_id" |
| 54 | + class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
| 55 | + <option value="">All Categories</option> |
| 56 | + @foreach($categories as $category) |
| 57 | + <option value="{{ $category->id }}" {{ request('category_id') == $category->id ? 'selected' : '' }}> |
| 58 | + {{ $category->name }} ({{ $category->feature_requests_count }}) |
| 59 | + </option> |
| 60 | + @endforeach |
| 61 | + </select> |
| 62 | + </div> |
| 63 | + <div class="flex items-end"> |
| 64 | + <button type="submit" |
| 65 | + class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500"> |
| 66 | + Filter |
| 67 | + </button> |
| 68 | + @if(request()->hasAny(['search', 'category_id'])) |
| 69 | + <a href="{{ route('feature-requests.roadmap') }}" |
| 70 | + class="ml-2 px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-500"> |
| 71 | + Clear |
| 72 | + </a> |
| 73 | + @endif |
| 74 | + </div> |
| 75 | + </form> |
| 76 | + </div> |
| 77 | + |
| 78 | + <!-- Roadmap Columns --> |
| 79 | + <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> |
| 80 | + @php |
| 81 | + $statusConfig = [ |
| 82 | + 'pending' => ['title' => 'Pending', 'color' => 'gray', 'icon' => 'clock'], |
| 83 | + 'under_review' => ['title' => 'Under Review', 'color' => 'yellow', 'icon' => 'eye'], |
| 84 | + 'in_progress' => ['title' => 'In Progress', 'color' => 'blue', 'icon' => 'play'] |
| 85 | + ]; |
| 86 | + @endphp |
| 87 | + |
| 88 | + @foreach($statusConfig as $status => $config) |
| 89 | + <div class="bg-white rounded-lg shadow-sm border"> |
| 90 | + <!-- Column Header --> |
| 91 | + <div class="p-4 border-b bg-{{ $config['color'] }}-50"> |
| 92 | + <div class="flex items-center justify-between"> |
| 93 | + <h3 class="text-lg font-semibold text-{{ $config['color'] }}-800"> |
| 94 | + {{ $config['title'] }} |
| 95 | + </h3> |
| 96 | + <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-{{ $config['color'] }}-100 text-{{ $config['color'] }}-800"> |
| 97 | + {{ $featureRequests[$status]->count() }} |
| 98 | + </span> |
| 99 | + </div> |
| 100 | + </div> |
| 101 | + |
| 102 | + <!-- Feature Requests --> |
| 103 | + <div class="p-4 space-y-3 min-h-96"> |
| 104 | + @forelse($featureRequests[$status] as $request) |
| 105 | + <div class="bg-gray-50 rounded-lg p-4 hover:bg-gray-100 transition-colors cursor-pointer group" |
| 106 | + onclick="window.location.href='{{ route('feature-requests.show', $request->slug) }}'"> |
| 107 | + |
| 108 | + <!-- Title --> |
| 109 | + <h4 class="font-medium text-gray-900 group-hover:text-blue-600 transition-colors mb-2"> |
| 110 | + {{ $request->title }} |
| 111 | + </h4> |
| 112 | + |
| 113 | + <!-- Description --> |
| 114 | + <p class="text-sm text-gray-600 mb-3 line-clamp-2"> |
| 115 | + {{ Str::limit($request->description, 100) }} |
| 116 | + </p> |
| 117 | + |
| 118 | + <!-- Meta Information --> |
| 119 | + <div class="flex items-center justify-between text-xs text-gray-500"> |
| 120 | + <div class="flex items-center space-x-3"> |
| 121 | + <!-- Votes --> |
| 122 | + <div class="flex items-center space-x-1"> |
| 123 | + <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 124 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 11l3-3 3 3m0 0l3-3 3 3m-3-3v8"></path> |
| 125 | + </svg> |
| 126 | + <span>{{ ($request->up_votes ?? 0) - ($request->down_votes ?? 0) }}</span> |
| 127 | + </div> |
| 128 | + |
| 129 | + <!-- Comments --> |
| 130 | + <div class="flex items-center space-x-1"> |
| 131 | + <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 132 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"></path> |
| 133 | + </svg> |
| 134 | + <span>{{ $request->comment_count ?? 0 }}</span> |
| 135 | + </div> |
| 136 | + </div> |
| 137 | + |
| 138 | + <!-- Date --> |
| 139 | + <span>{{ $request->created_at->diffForHumans() }}</span> |
| 140 | + </div> |
| 141 | + |
| 142 | + <!-- Category --> |
| 143 | + @if($request->category) |
| 144 | + <div class="mt-2"> |
| 145 | + <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800"> |
| 146 | + {{ $request->category->name }} |
| 147 | + </span> |
| 148 | + </div> |
| 149 | + @endif |
| 150 | + </div> |
| 151 | + @empty |
| 152 | + <div class="text-center py-8 text-gray-500"> |
| 153 | + <svg class="w-12 h-12 mx-auto mb-3 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 154 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path> |
| 155 | + </svg> |
| 156 | + <p class="text-sm">No {{ strtolower($config['title']) }} requests</p> |
| 157 | + </div> |
| 158 | + @endforelse |
| 159 | + </div> |
| 160 | + </div> |
| 161 | + @endforeach |
| 162 | + </div> |
| 163 | + |
| 164 | + <!-- Statistics --> |
| 165 | + <div class="mt-8 bg-white rounded-lg shadow-sm border p-6"> |
| 166 | + <h3 class="text-lg font-semibold text-gray-900 mb-4">Roadmap Statistics</h3> |
| 167 | + <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> |
| 168 | + <div class="text-center"> |
| 169 | + <div class="text-2xl font-bold text-gray-900">{{ $statistics['total'] ?? 0 }}</div> |
| 170 | + <div class="text-sm text-gray-600">Total Requests</div> |
| 171 | + </div> |
| 172 | + <div class="text-center"> |
| 173 | + <div class="text-2xl font-bold text-blue-600">{{ $statistics['in_progress'] ?? 0 }}</div> |
| 174 | + <div class="text-sm text-gray-600">In Progress</div> |
| 175 | + </div> |
| 176 | + <div class="text-center"> |
| 177 | + <div class="text-2xl font-bold text-green-600">{{ $statistics['completed'] ?? 0 }}</div> |
| 178 | + <div class="text-sm text-gray-600">Completed</div> |
| 179 | + </div> |
| 180 | + <div class="text-center"> |
| 181 | + <div class="text-2xl font-bold text-gray-600">{{ $statistics['total_votes'] ?? 0 }}</div> |
| 182 | + <div class="text-sm text-gray-600">Total Votes</div> |
| 183 | + </div> |
| 184 | + </div> |
| 185 | + </div> |
| 186 | + </div> |
| 187 | +</div> |
| 188 | +@endsection |
0 commit comments