fix: add dark mode variants to light-only views

Forms, upvote button, modal, notifications and several pages had no
dark: classes and rendered as white blocks in dark mode.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Doar Mihai
2026-10-17 16:24:26 +03:00
co-authored by Claude Sonnet 5.5
parent 06ac14c5e6
commit 2a37695d78
17 changed files with 275 additions and 275 deletions
+50 -50
View File
@@ -3,19 +3,19 @@
@section('content')
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">Submit a Product</h1>
<p class="mt-2 text-sm text-gray-600">Share your EU-based tech product with the community</p>
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Submit a Product</h1>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Share your EU-based tech product with the community</p>
</div>
<div class="bg-white shadow-sm rounded-lg">
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg">
<div class="px-4 py-5 sm:p-6">
<form method="POST" action="{{ route('products.store') }}" enctype="multipart/form-data" class="space-y-6">
@csrf
<!-- Title -->
<div>
<label for="title" class="block text-sm font-medium text-gray-700">
Product Title <span class="text-red-600">*</span>
<label for="title" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Product Title <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<input type="text"
@@ -25,18 +25,18 @@
required
maxlength="255"
placeholder="e.g., My Awesome Product"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('title') border-red-300 text-red-900 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('title') border-red-300 text-red-900 dark:text-red-200 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">
@error('title')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">A catchy, descriptive title for your product.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">A catchy, descriptive title for your product.</p>
</div>
</div>
<!-- Description -->
<div>
<label for="description" class="block text-sm font-medium text-gray-700">
Description <span class="text-red-600">*</span>
<label for="description" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Description <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<textarea id="description"
@@ -44,18 +44,18 @@
rows="5"
required
placeholder="Tell us about your product..."
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('description') border-red-300 text-red-900 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror">{{ old('description') }}</textarea>
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('description') border-red-300 text-red-900 dark:text-red-200 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">{{ old('description') }}</textarea>
@error('description')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Provide a detailed description of your product (what it does, key features, etc.).</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Provide a detailed description of your product (what it does, key features, etc.).</p>
</div>
</div>
<!-- Website URL -->
<div>
<label for="website_url" class="block text-sm font-medium text-gray-700">
Website URL <span class="text-red-600">*</span>
<label for="website_url" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Website URL <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<input type="url"
@@ -64,24 +64,24 @@
value="{{ old('website_url') }}"
required
placeholder="https://example.com"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('website_url') border-red-300 text-red-900 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('website_url') border-red-300 text-red-900 dark:text-red-200 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">
@error('website_url')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">The full URL to your product's website or landing page.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">The full URL to your product's website or landing page.</p>
</div>
</div>
<!-- Category -->
<div>
<label for="category_id" class="block text-sm font-medium text-gray-700">
Category <span class="text-red-600">*</span>
<label for="category_id" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Category <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<select id="category_id"
name="category_id"
required
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('category_id') border-red-300 text-red-900 focus:ring-red-500 focus:border-red-500 @enderror">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('category_id') border-red-300 text-red-900 dark:text-red-200 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">
<option value="">Select a category...</option>
@foreach($categories as $category)
<option value="{{ $category->id }}" {{ old('category_id') == $category->id ? 'selected' : '' }}>
@@ -90,64 +90,64 @@
@endforeach
</select>
@error('category_id')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Choose the category that best fits your product.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Choose the category that best fits your product.</p>
</div>
</div>
<!-- Tags -->
@if($tags->count() > 0)
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Tags
</label>
<div class="mt-1 space-y-2">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
@foreach($tags as $tag)
<label class="relative flex items-start p-3 border border-gray-300 rounded-md cursor-pointer hover:bg-gray-50 transition-colors">
<label class="relative flex items-start p-3 border border-gray-300 dark:border-gray-600 rounded-md cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
<div class="flex items-center h-5">
<input type="checkbox"
name="tags[]"
value="{{ $tag->id }}"
{{ is_array(old('tags')) && in_array($tag->id, old('tags')) ? 'checked' : '' }}
class="focus:ring-primary-500 h-4 w-4 text-primary-600 border-gray-300 rounded">
class="focus:ring-primary-500 h-4 w-4 text-primary-600 dark:text-primary-400 border-gray-300 dark:border-gray-600 rounded">
</div>
<div class="ml-3 flex-1">
<div class="flex items-center gap-2">
<span class="inline-block w-3 h-3 rounded-full" style="background-color: {{ $tag->color }}"></span>
<span class="text-sm font-medium text-gray-900">{{ $tag->name }}</span>
<span class="text-sm font-medium text-gray-900 dark:text-white">{{ $tag->name }}</span>
</div>
@if($tag->description)
<p class="text-xs text-gray-500 mt-1">{{ $tag->description }}</p>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">{{ $tag->description }}</p>
@endif
</div>
</label>
@endforeach
</div>
@error('tags')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Select all tags that apply to your product.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Select all tags that apply to your product.</p>
</div>
</div>
@endif
<!-- Badges -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Badges
</label>
<div class="mt-1 grid grid-cols-2 sm:grid-cols-4 gap-3">
@foreach(\App\Models\Product::BADGES as $key => $label)
<label class="flex items-center p-3 border border-gray-300 rounded-md">
<label class="flex items-center p-3 border border-gray-300 dark:border-gray-600 rounded-md">
<input type="hidden" name="{{ $key }}" value="0">
<input type="checkbox"
name="{{ $key }}"
value="1"
{{ old($key, false) ? 'checked' : '' }}
class="focus:ring-primary-500 h-4 w-4 text-primary-600 border-gray-300 rounded">
<span class="ml-2 text-sm text-gray-900">{{ $label }}</span>
class="focus:ring-primary-500 h-4 w-4 text-primary-600 dark:text-primary-400 border-gray-300 dark:border-gray-600 rounded">
<span class="ml-2 text-sm text-gray-900 dark:text-white">{{ $label }}</span>
</label>
@endforeach
</div>
@@ -155,7 +155,7 @@
<!-- Thumbnail -->
<div>
<label for="thumbnail" class="block text-sm font-medium text-gray-700">
<label for="thumbnail" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Product Thumbnail
</label>
<div class="mt-1">
@@ -163,25 +163,25 @@
id="thumbnail"
name="thumbnail"
accept="image/*"
class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100 @error('thumbnail') border-red-300 @enderror">
class="block w-full text-sm text-gray-500 dark:text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100 @error('thumbnail') border-red-300 dark:border-red-700 @enderror">
@error('thumbnail')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Upload a product screenshot or logo (JPEG, PNG, or GIF, max 2MB).</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Upload a product screenshot or logo (JPEG, PNG, or GIF, max 2MB).</p>
</div>
</div>
<!-- Image Preview -->
<div id="imagePreview" class="hidden">
<label class="block text-sm font-medium text-gray-700 mb-2">Preview:</label>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Preview:</label>
<div class="mt-1">
<img id="preview" src="#" alt="Thumbnail preview" class="max-w-xs rounded-lg border border-gray-300 shadow-sm">
<img id="preview" src="#" alt="Thumbnail preview" class="max-w-xs rounded-lg border border-gray-300 dark:border-gray-600 shadow-sm">
</div>
</div>
<!-- Screenshots -->
<div x-data="{ previews: [] }">
<label for="screenshots" class="block text-sm font-medium text-gray-700">
<label for="screenshots" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Screenshots
</label>
<div class="mt-1">
@@ -191,17 +191,17 @@
accept="image/*"
multiple
@change="previews = Array.from($event.target.files).map(f => URL.createObjectURL(f))"
class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100">
class="block w-full text-sm text-gray-500 dark:text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100">
@error('screenshots')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
@foreach($errors->get('screenshots.*') as $messages)
<p class="mt-2 text-sm text-red-600">{{ $messages[0] }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $messages[0] }}</p>
@endforeach
<p class="mt-2 text-sm text-gray-500">Add several images (JPEG, PNG, or GIF, max 2MB each).</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Add several images (JPEG, PNG, or GIF, max 2MB each).</p>
<div class="mt-3 flex flex-wrap gap-2" x-show="previews.length" style="display: none">
<template x-for="src in previews" :key="src">
<img :src="src" alt="" class="h-20 w-28 object-cover rounded border border-gray-300">
<img :src="src" alt="" class="h-20 w-28 object-cover rounded border border-gray-300 dark:border-gray-600">
</template>
</div>
</div>
@@ -212,7 +212,7 @@
<x-product.team-form />
<!-- Info Alert -->
<div class="rounded-md bg-blue-50 p-4">
<div class="rounded-md bg-blue-50 dark:bg-blue-900/20 p-4">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-blue-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
@@ -220,7 +220,7 @@
</svg>
</div>
<div class="ml-3 flex-1">
<p class="text-sm text-blue-700">
<p class="text-sm text-blue-700 dark:text-blue-300">
<strong>Note:</strong> Your product will be reviewed by our moderators before it appears on the site.
</p>
</div>
@@ -228,9 +228,9 @@
</div>
<!-- Submit Buttons -->
<div class="flex items-center justify-between pt-5 border-t border-gray-200">
<div class="flex items-center justify-between pt-5 border-t border-gray-200 dark:border-gray-700">
<a href="{{ route('products.index') }}"
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
class="inline-flex items-center px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Cancel
</a>
<button type="submit"
+57 -57
View File
@@ -3,11 +3,11 @@
@section('content')
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">Edit Product</h1>
<p class="mt-2 text-sm text-gray-600">Update your product information and details</p>
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Edit Product</h1>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Update your product information and details</p>
</div>
<div class="bg-white shadow-sm rounded-lg">
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg">
<div class="px-4 py-5 sm:p-6">
<form method="POST" action="{{ route('products.update', $product) }}" enctype="multipart/form-data" class="space-y-6">
@csrf
@@ -15,8 +15,8 @@
<!-- Title -->
<div>
<label for="title" class="block text-sm font-medium text-gray-700">
Product Title <span class="text-red-600">*</span>
<label for="title" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Product Title <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<input type="text"
@@ -26,18 +26,18 @@
required
maxlength="255"
placeholder="e.g., My Awesome Product"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('title') border-red-300 text-red-900 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('title') border-red-300 text-red-900 dark:text-red-200 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">
@error('title')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">A catchy, descriptive title for your product.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">A catchy, descriptive title for your product.</p>
</div>
</div>
<!-- Description -->
<div>
<label for="description" class="block text-sm font-medium text-gray-700">
Description <span class="text-red-600">*</span>
<label for="description" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Description <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<textarea id="description"
@@ -45,18 +45,18 @@
rows="5"
required
placeholder="Tell us about your product..."
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('description') border-red-300 text-red-900 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror">{{ old('description', $product->description) }}</textarea>
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('description') border-red-300 text-red-900 dark:text-red-200 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">{{ old('description', $product->description) }}</textarea>
@error('description')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Provide a detailed description of your product (what it does, key features, etc.).</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Provide a detailed description of your product (what it does, key features, etc.).</p>
</div>
</div>
<!-- Website URL -->
<div>
<label for="website_url" class="block text-sm font-medium text-gray-700">
Website URL <span class="text-red-600">*</span>
<label for="website_url" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Website URL <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<input type="url"
@@ -65,24 +65,24 @@
value="{{ old('website_url', $product->website_url) }}"
required
placeholder="https://example.com"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('website_url') border-red-300 text-red-900 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('website_url') border-red-300 text-red-900 dark:text-red-200 placeholder-red-300 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">
@error('website_url')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">The full URL to your product's website or landing page.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">The full URL to your product's website or landing page.</p>
</div>
</div>
<!-- Category -->
<div>
<label for="category_id" class="block text-sm font-medium text-gray-700">
Category <span class="text-red-600">*</span>
<label for="category_id" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Category <span class="text-red-600 dark:text-red-400">*</span>
</label>
<div class="mt-1">
<select id="category_id"
name="category_id"
required
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('category_id') border-red-300 text-red-900 focus:ring-red-500 focus:border-red-500 @enderror">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm @error('category_id') border-red-300 text-red-900 dark:text-red-200 focus:ring-red-500 focus:border-red-500 @enderror dark:bg-gray-700">
<option value="">Select a category...</option>
@foreach($categories as $category)
<option value="{{ $category->id }}" {{ old('category_id', $product->category_id) == $category->id ? 'selected' : '' }}>
@@ -91,16 +91,16 @@
@endforeach
</select>
@error('category_id')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Choose the category that best fits your product.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Choose the category that best fits your product.</p>
</div>
</div>
<!-- Tags -->
@if($tags->count() > 0)
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Tags
</label>
<div class="mt-1 space-y-2">
@@ -111,30 +111,30 @@
? in_array($tag->id, old('tags'))
: $product->tags->contains($tag->id);
@endphp
<label class="relative flex items-start p-3 border border-gray-300 rounded-md cursor-pointer hover:bg-gray-50 transition-colors">
<label class="relative flex items-start p-3 border border-gray-300 dark:border-gray-600 rounded-md cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
<div class="flex items-center h-5">
<input type="checkbox"
name="tags[]"
value="{{ $tag->id }}"
{{ $isChecked ? 'checked' : '' }}
class="focus:ring-primary-500 h-4 w-4 text-primary-600 border-gray-300 rounded">
class="focus:ring-primary-500 h-4 w-4 text-primary-600 dark:text-primary-400 border-gray-300 dark:border-gray-600 rounded">
</div>
<div class="ml-3 flex-1">
<div class="flex items-center gap-2">
<span class="inline-block w-3 h-3 rounded-full" style="background-color: {{ $tag->color }}"></span>
<span class="text-sm font-medium text-gray-900">{{ $tag->name }}</span>
<span class="text-sm font-medium text-gray-900 dark:text-white">{{ $tag->name }}</span>
</div>
@if($tag->description)
<p class="text-xs text-gray-500 mt-1">{{ $tag->description }}</p>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">{{ $tag->description }}</p>
@endif
</div>
</label>
@endforeach
</div>
@error('tags')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Select all tags that apply to your product.</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Select all tags that apply to your product.</p>
</div>
</div>
@endif
@@ -145,43 +145,43 @@
<!-- Badges -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Badges
</label>
<div class="mt-1 grid grid-cols-2 sm:grid-cols-4 gap-3">
@foreach(\App\Models\Product::BADGES as $key => $label)
<label class="flex items-center p-3 border border-gray-300 rounded-md">
<label class="flex items-center p-3 border border-gray-300 dark:border-gray-600 rounded-md">
<input type="hidden" name="{{ $key }}" value="0">
<input type="checkbox"
name="{{ $key }}"
value="1"
{{ old($key, $product->{$key}) ? 'checked' : '' }}
{{ $badgesLocked ? 'disabled' : '' }}
class="focus:ring-primary-500 h-4 w-4 text-primary-600 border-gray-300 rounded">
<span class="ml-2 text-sm text-gray-900">{{ $label }}</span>
class="focus:ring-primary-500 h-4 w-4 text-primary-600 dark:text-primary-400 border-gray-300 dark:border-gray-600 rounded">
<span class="ml-2 text-sm text-gray-900 dark:text-white">{{ $label }}</span>
</label>
@endforeach
</div>
@if($badgesLocked)
<p class="mt-2 text-sm text-gray-500">Locked after approval</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Locked after approval</p>
@endif
</div>
<!-- Current Thumbnail -->
@if($product->thumbnail_url)
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Current Thumbnail:</label>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Current Thumbnail:</label>
<div class="mt-1">
<img src="{{ $product->thumbnail_url }}"
alt="{{ $product->title }}"
class="max-w-xs rounded-lg border border-gray-300 shadow-sm">
class="max-w-xs rounded-lg border border-gray-300 dark:border-gray-600 shadow-sm">
</div>
</div>
@endif
<!-- New Thumbnail -->
<div>
<label for="thumbnail" class="block text-sm font-medium text-gray-700">
<label for="thumbnail" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
{{ $product->thumbnail_url ? 'Replace Thumbnail' : 'Product Thumbnail' }}
</label>
<div class="mt-1">
@@ -189,32 +189,32 @@
id="thumbnail"
name="thumbnail"
accept="image/*"
class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100 @error('thumbnail') border-red-300 @enderror">
class="block w-full text-sm text-gray-500 dark:text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100 @error('thumbnail') border-red-300 dark:border-red-700 @enderror">
@error('thumbnail')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
<p class="mt-2 text-sm text-gray-500">Upload a product screenshot or logo (JPEG, PNG, or GIF, max 2MB).</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Upload a product screenshot or logo (JPEG, PNG, or GIF, max 2MB).</p>
</div>
</div>
<!-- Image Preview -->
<div id="imagePreview" class="hidden">
<label class="block text-sm font-medium text-gray-700 mb-2">New Preview:</label>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">New Preview:</label>
<div class="mt-1">
<img id="preview" src="#" alt="Thumbnail preview" class="max-w-xs rounded-lg border border-gray-300 shadow-sm">
<img id="preview" src="#" alt="Thumbnail preview" class="max-w-xs rounded-lg border border-gray-300 dark:border-gray-600 shadow-sm">
</div>
</div>
@if($product->screenshots->isNotEmpty())
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Current Screenshots:</label>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Current Screenshots:</label>
<div class="mt-1 grid grid-cols-2 sm:grid-cols-4 gap-3">
@foreach($product->screenshots as $shot)
<label class="block">
<img src="{{ $shot->url }}" alt="" class="h-24 w-full object-cover rounded border border-gray-300">
<span class="mt-1 flex items-center text-sm text-gray-700">
<img src="{{ $shot->url }}" alt="" class="h-24 w-full object-cover rounded border border-gray-300 dark:border-gray-600">
<span class="mt-1 flex items-center text-sm text-gray-700 dark:text-gray-300">
<input type="checkbox" name="remove_screenshots[]" value="{{ $shot->id }}"
class="h-4 w-4 text-primary-600 border-gray-300 rounded">
class="h-4 w-4 text-primary-600 dark:text-primary-400 border-gray-300 dark:border-gray-600 rounded">
<span class="ml-2">Remove</span>
</span>
</label>
@@ -225,7 +225,7 @@
<!-- Screenshots -->
<div x-data="{ previews: [] }">
<label for="screenshots" class="block text-sm font-medium text-gray-700">
<label for="screenshots" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
Screenshots
</label>
<div class="mt-1">
@@ -235,17 +235,17 @@
accept="image/*"
multiple
@change="previews = Array.from($event.target.files).map(f => URL.createObjectURL(f))"
class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100">
class="block w-full text-sm text-gray-500 dark:text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100">
@error('screenshots')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
@enderror
@foreach($errors->get('screenshots.*') as $messages)
<p class="mt-2 text-sm text-red-600">{{ $messages[0] }}</p>
<p class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $messages[0] }}</p>
@endforeach
<p class="mt-2 text-sm text-gray-500">Add several images (JPEG, PNG, or GIF, max 2MB each).</p>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">Add several images (JPEG, PNG, or GIF, max 2MB each).</p>
<div class="mt-3 flex flex-wrap gap-2" x-show="previews.length" style="display: none">
<template x-for="src in previews" :key="src">
<img :src="src" alt="" class="h-20 w-28 object-cover rounded border border-gray-300">
<img :src="src" alt="" class="h-20 w-28 object-cover rounded border border-gray-300 dark:border-gray-600">
</template>
</div>
</div>
@@ -256,7 +256,7 @@
<x-product.team-form :members="$product->members" :readonly="! (auth()->id() === $product->user_id || auth()->user()->isAdmin())" />
<!-- Info Alert -->
<div class="rounded-md bg-blue-50 p-4">
<div class="rounded-md bg-blue-50 dark:bg-blue-900/20 p-4">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-blue-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
@@ -264,7 +264,7 @@
</svg>
</div>
<div class="ml-3 flex-1">
<p class="text-sm text-blue-700">
<p class="text-sm text-blue-700 dark:text-blue-300">
<strong>Note:</strong> Changes to your product may need to be reviewed by moderators before appearing on the site.
</p>
</div>
@@ -272,9 +272,9 @@
</div>
<!-- Submit Buttons -->
<div class="flex items-center justify-between pt-5 border-t border-gray-200">
<div class="flex items-center justify-between pt-5 border-t border-gray-200 dark:border-gray-700">
<a href="{{ route('products.show', $product) }}"
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
class="inline-flex items-center px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Cancel
</a>
<button type="submit"
+26 -26
View File
@@ -6,13 +6,13 @@
@section('content')
<!-- Hero Section -->
<div class="bg-gradient-to-br from-primary-50 via-white to-accent-50 border-b border-gray-200">
<div class="bg-gradient-to-br from-primary-50 via-white to-accent-50 border-b border-gray-200 dark:border-gray-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 sm:py-16">
<div class="text-center max-w-3xl mx-auto">
<h1 class="text-4xl sm:text-5xl font-bold text-gray-900 mb-4">
<h1 class="text-4xl sm:text-5xl font-bold text-gray-900 dark:text-white mb-4">
Discover the best tech from Europe
</h1>
<p class="text-lg text-gray-600 mb-8">
<p class="text-lg text-gray-600 dark:text-gray-400 mb-8">
Find amazing products built by European makers and companies
</p>
@@ -24,7 +24,7 @@
name="search"
value="{{ request('search') }}"
placeholder="Search for products..."
class="w-full px-6 py-4 text-lg border-2 border-gray-300 rounded-full focus:border-primary-500 focus:ring-2 focus:ring-primary-200 transition-all duration-200">
class="w-full px-6 py-4 text-lg border-2 border-gray-300 dark:border-gray-600 rounded-full focus:border-primary-500 focus:ring-2 focus:ring-primary-200 transition-all duration-200 dark:bg-gray-700 dark:text-white">
<button type="submit"
class="absolute right-2 top-1/2 -translate-y-1/2 bg-primary-600 text-white px-6 py-2 rounded-full hover:bg-primary-700 transition-colors">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -50,7 +50,7 @@
type="button"
class="w-full inline-flex items-center justify-between px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm text-sm font-medium rounded-md text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
<span class="flex items-center">
<svg class="mr-2 h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="mr-2 h-5 w-5 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"></path>
</svg>
Filters & Sort
@@ -66,21 +66,21 @@
class="lg:flex lg:items-end lg:gap-4 grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-4">
<!-- Search (hidden on desktop as it's in hero) -->
<div class="lg:hidden sm:col-span-2">
<label for="mobile-search" class="block text-sm font-medium text-gray-700 mb-2">Search</label>
<label for="mobile-search" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Search</label>
<input type="text"
id="mobile-search"
name="search"
value="{{ request('search') }}"
placeholder="Search products..."
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm dark:bg-gray-700 dark:text-white">
</div>
<!-- Category Filter -->
<div class="lg:flex-1">
<label for="category" class="block text-sm font-medium text-gray-700 mb-2">Category</label>
<label for="category" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Category</label>
<select name="category"
id="category"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm dark:bg-gray-700 dark:text-white">
<option value="">All Categories</option>
@foreach($categories as $category)
<option value="{{ $category->id }}" {{ request('category') == $category->id ? 'selected' : '' }}>
@@ -92,10 +92,10 @@
<!-- Date Range Filter -->
<div class="lg:flex-1">
<label for="date_range" class="block text-sm font-medium text-gray-700 mb-2">Time Period</label>
<label for="date_range" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Time Period</label>
<select name="date_range"
id="date_range"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm dark:bg-gray-700 dark:text-white">
<option value="">All Time</option>
<option value="today" {{ request('date_range') === 'today' ? 'selected' : '' }}>Today</option>
<option value="week" {{ request('date_range') === 'week' ? 'selected' : '' }}>This Week</option>
@@ -106,10 +106,10 @@
<!-- Sort By -->
<div class="lg:flex-1">
<label for="sort" class="block text-sm font-medium text-gray-700 mb-2">Sort By</label>
<label for="sort" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Sort By</label>
<select name="sort"
id="sort"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm">
class="appearance-none block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm dark:bg-gray-700 dark:text-white">
<option value="newest" {{ request('sort') === 'newest' || !request('sort') ? 'selected' : '' }}>Newest</option>
<option value="popular" {{ request('sort') === 'popular' ? 'selected' : '' }}>Most Popular</option>
<option value="oldest" {{ request('sort') === 'oldest' ? 'selected' : '' }}>Oldest</option>
@@ -137,28 +137,28 @@
<!-- Active Filters Tags -->
@if(request()->hasAny(['search', 'category', 'date_range', 'sort']))
<div class="flex flex-wrap gap-2 pt-4 border-t border-gray-200">
<span class="text-sm font-medium text-gray-700">Active filters:</span>
<div class="flex flex-wrap gap-2 pt-4 border-t border-gray-200 dark:border-gray-700">
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Active filters:</span>
@if(request('search'))
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 text-primary-800">
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200">
Search: "{{ request('search') }}"
<a href="{{ route('products.index', request()->except('search')) }}" class="ml-2 hover:text-primary-900">×</a>
</span>
@endif
@if(request('category'))
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 text-primary-800">
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200">
{{ $categories->find(request('category'))->name ?? 'Unknown' }}
<a href="{{ route('products.index', request()->except('category')) }}" class="ml-2 hover:text-primary-900">×</a>
</span>
@endif
@if(request('date_range'))
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 text-primary-800">
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200">
{{ ucfirst(request('date_range')) }}
<a href="{{ route('products.index', request()->except('date_range')) }}" class="ml-2 hover:text-primary-900">×</a>
</span>
@endif
@if(request('sort') && request('sort') !== 'newest')
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 text-primary-800">
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200">
{{ ucfirst(request('sort')) }}
<a href="{{ route('products.index', request()->except('sort')) }}" class="ml-2 hover:text-primary-900">×</a>
</span>
@@ -172,10 +172,10 @@
<!-- Results Summary -->
@if($products->total() > 0)
<div class="mb-6">
<p class="text-sm text-gray-600">
Showing <span class="font-semibold text-gray-900">{{ $products->firstItem() }}</span> to
<span class="font-semibold text-gray-900">{{ $products->lastItem() }}</span> of
<span class="font-semibold text-gray-900">{{ $products->total() }}</span> products
<p class="text-sm text-gray-600 dark:text-gray-400">
Showing <span class="font-semibold text-gray-900 dark:text-white">{{ $products->firstItem() }}</span> to
<span class="font-semibold text-gray-900 dark:text-white">{{ $products->lastItem() }}</span> of
<span class="font-semibold text-gray-900 dark:text-white">{{ $products->total() }}</span> products
</p>
</div>
@endif
@@ -188,11 +188,11 @@
<!-- Empty State -->
<div class="col-span-full">
<div class="text-center py-16">
<svg class="mx-auto h-16 w-16 text-gray-400 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="mx-auto h-16 w-16 text-gray-400 dark:text-gray-500 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<h3 class="text-lg font-medium text-gray-900 mb-2">No products found</h3>
<p class="text-gray-600 mb-6">
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">No products found</h3>
<p class="text-gray-600 dark:text-gray-400 mb-6">
@if(request()->hasAny(['search', 'category', 'date_range']))
Try adjusting your search or filters to find what you're looking for.
@else
+28 -28
View File
@@ -4,17 +4,17 @@
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<!-- Header -->
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">Product Management</h1>
<p class="mt-2 text-sm text-gray-600">Review and manage submitted products</p>
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Product Management</h1>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Review and manage submitted products</p>
</div>
<!-- Status Filter -->
<div class="bg-white rounded-lg shadow-sm border border-gray-200 mb-6">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 mb-6">
<div class="px-6 py-4">
<h2 class="text-lg font-medium text-gray-900 mb-4">Filter by Status</h2>
<h2 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Filter by Status</h2>
<div class="flex flex-wrap gap-3">
<a href="{{ route('products.manage') }}"
class="inline-flex items-center px-4 py-2 rounded-md text-sm font-medium {{ !request('status') || request('status') == 'pending' ? 'bg-yellow-100 text-yellow-800 ring-2 ring-yellow-600' : 'bg-white text-gray-700 ring-1 ring-gray-300 hover:bg-gray-50' }}">
class="inline-flex items-center px-4 py-2 rounded-md text-sm font-medium {{ !request('status') || request('status') == 'pending' ? 'bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-200 ring-2 ring-yellow-600' : 'bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 ring-1 ring-gray-300 dark:ring-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700' }}">
<svg class="mr-2 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
@@ -25,7 +25,7 @@
</a>
<a href="{{ route('products.manage', ['status' => 'approved']) }}"
class="inline-flex items-center px-4 py-2 rounded-md text-sm font-medium {{ request('status') == 'approved' ? 'bg-green-100 text-green-800 ring-2 ring-green-600' : 'bg-white text-gray-700 ring-1 ring-gray-300 hover:bg-gray-50' }}">
class="inline-flex items-center px-4 py-2 rounded-md text-sm font-medium {{ request('status') == 'approved' ? 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 ring-2 ring-green-600' : 'bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 ring-1 ring-gray-300 dark:ring-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700' }}">
<svg class="mr-2 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
@@ -36,7 +36,7 @@
</a>
<a href="{{ route('products.manage', ['status' => 'rejected']) }}"
class="inline-flex items-center px-4 py-2 rounded-md text-sm font-medium {{ request('status') == 'rejected' ? 'bg-red-100 text-red-800 ring-2 ring-red-600' : 'bg-white text-gray-700 ring-1 ring-gray-300 hover:bg-gray-50' }}">
class="inline-flex items-center px-4 py-2 rounded-md text-sm font-medium {{ request('status') == 'rejected' ? 'bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200 ring-2 ring-red-600' : 'bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 ring-1 ring-gray-300 dark:ring-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700' }}">
<svg class="mr-2 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
@@ -53,7 +53,7 @@
@if($products->count() > 0)
<div class="space-y-4">
@foreach($products as $product)
<div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden hover:shadow-md transition-shadow">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden hover:shadow-md transition-shadow">
<div class="p-6">
<div class="flex items-start gap-4">
<!-- Thumbnail -->
@@ -61,10 +61,10 @@
@if($product->thumbnail_url)
<img src="{{ $product->thumbnail_url }}"
alt="{{ $product->title }}"
class="w-20 h-20 rounded-lg object-cover border border-gray-200">
class="w-20 h-20 rounded-lg object-cover border border-gray-200 dark:border-gray-700">
@else
<div class="w-20 h-20 rounded-lg bg-gradient-to-br from-gray-100 to-gray-200 flex items-center justify-center border border-gray-200">
<svg class="h-8 w-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<div class="w-20 h-20 rounded-lg bg-gradient-to-br from-gray-100 to-gray-200 flex items-center justify-center border border-gray-200 dark:border-gray-700">
<svg class="h-8 w-8 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
</div>
@@ -75,19 +75,19 @@
<div class="flex-1 min-w-0">
<div class="flex items-start justify-between">
<div class="flex-1">
<h3 class="text-lg font-semibold text-gray-900">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
<a href="{{ route('products.show', $product) }}" class="hover:text-primary-600">
{{ $product->title }}
</a>
</h3>
<p class="mt-1 text-sm text-gray-600 line-clamp-2">{{ $product->description }}</p>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400 line-clamp-2">{{ $product->description }}</p>
<div class="mt-3 flex flex-wrap items-center gap-4 text-sm">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-md bg-primary-100 text-primary-800 font-medium">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200 font-medium">
{{ $product->category->name }}
</span>
<span class="inline-flex items-center text-gray-500">
<span class="inline-flex items-center text-gray-500 dark:text-gray-400">
<svg class="mr-1.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
</svg>
@@ -96,30 +96,30 @@
</a>
</span>
<span class="inline-flex items-center text-gray-500">
<span class="inline-flex items-center text-gray-500 dark:text-gray-400">
<svg class="mr-1.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
{{ $product->created_at->format('M j, Y') }}
</span>
<span class="text-gray-400">•</span>
<span class="text-gray-500">{{ $product->created_at->diffForHumans() }}</span>
<span class="text-gray-400 dark:text-gray-500">•</span>
<span class="text-gray-500 dark:text-gray-400">{{ $product->created_at->diffForHumans() }}</span>
</div>
</div>
<!-- Status Badge -->
<div class="ml-4 flex-shrink-0">
@if($product->isPending())
<span class="inline-flex items-center px-3 py-1 rounded-md text-sm font-medium bg-yellow-100 text-yellow-800">
<span class="inline-flex items-center px-3 py-1 rounded-md text-sm font-medium bg-yellow-100 text-yellow-800 dark:text-yellow-200">
Pending
</span>
@elseif($product->isApproved())
<span class="inline-flex items-center px-3 py-1 rounded-md text-sm font-medium bg-green-100 text-green-800">
<span class="inline-flex items-center px-3 py-1 rounded-md text-sm font-medium bg-green-100 text-green-800 dark:text-green-200">
Approved
</span>
@elseif($product->isRejected())
<span class="inline-flex items-center px-3 py-1 rounded-md text-sm font-medium bg-red-100 text-red-800">
<span class="inline-flex items-center px-3 py-1 rounded-md text-sm font-medium bg-red-100 text-red-800 dark:text-red-200">
Rejected
</span>
@endif
@@ -152,7 +152,7 @@
</form>
@endif
<a href="{{ route('products.show', $product) }}" class="inline-flex items-center px-3 py-1.5 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
<a href="{{ route('products.show', $product) }}" class="inline-flex items-center px-3 py-1.5 border border-gray-300 dark:border-gray-600 text-sm font-medium rounded-md text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
<svg class="mr-1.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
@@ -161,7 +161,7 @@
</a>
@can('edit-product', $product)
<a href="{{ route('products.edit', $product) }}" class="inline-flex items-center px-3 py-1.5 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
<a href="{{ route('products.edit', $product) }}" class="inline-flex items-center px-3 py-1.5 border border-gray-300 dark:border-gray-600 text-sm font-medium rounded-md text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
<svg class="mr-1.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
@@ -173,7 +173,7 @@
<form action="{{ route('products.destroy', $product) }}" method="POST" onsubmit="return confirm('Are you sure you want to delete this product permanently?');">
@csrf
@method('DELETE')
<button type="submit" class="inline-flex items-center px-3 py-1.5 border border-red-300 text-sm font-medium rounded-md text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500">
<button type="submit" class="inline-flex items-center px-3 py-1.5 border border-red-300 dark:border-red-700 text-sm font-medium rounded-md text-red-700 dark:text-red-300 bg-white dark:bg-gray-800 hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500">
<svg class="mr-1.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
@@ -196,12 +196,12 @@
</div>
@endif
@else
<div class="text-center py-12 bg-gray-50 rounded-lg border border-gray-200">
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<div class="text-center py-12 bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700">
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
</svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">No products found</h3>
<p class="mt-1 text-sm text-gray-500">
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-white">No products found</h3>
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
No products with status: <strong>{{ request('status', 'pending') }}</strong>
</p>
</div>