Update profile pages design

This commit is contained in:
2026-07-25 13:54:21 +02:00
parent 2b1a967065
commit 5af1c3c447
17 changed files with 1031 additions and 362 deletions
@@ -1,101 +1,108 @@
<div>
<div class="mx-auto max-w-5xl px-4 space-y-6">
<!-- Filters -->
<div class="p-4 bg-white/40 dark:bg-neutral-950/40 backdrop-blur rounded-xl shadow flex flex-col sm:flex-row gap-3">
<!-- Search -->
<div class="space-y-5">
{{-- Filters --}}
<div class="rounded-2xl border border-neutral-200/70 bg-white/80 p-4 shadow-sm backdrop-blur-xl dark:border-neutral-800/70 dark:bg-neutral-950/70">
<div class="flex flex-col sm:flex-row gap-3">
{{-- Search --}}
<div class="relative flex-1">
<input
wire:model.live.debounce.500ms="commentSearch"
type="search"
placeholder="Search comments..."
class="w-full pl-10 pr-4 py-3 rounded-lg border-neutral-300 dark:text-neutral-300 bg-white/80 dark:bg-neutral-900/50 dark:border-neutral-700 focus:outline-none focus:ring-2 focus:ring-rose-600 focus:border-rose-700 transition"
>
<div class="pointer-events-none absolute inset-y-0 left-0 pl-3 flex items-center">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
<svg class="w-4 h-4 text-gray-400 dark:text-gray-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
</svg>
</div>
<input
wire:model.live.debounce.500ms="commentSearch"
type="search"
placeholder="Search comments..."
class="w-full pl-10 pr-4 py-2.5 rounded-xl border-neutral-300 dark:text-neutral-300 bg-white dark:bg-neutral-900 dark:border-neutral-700 focus:outline-none focus:ring-2 focus:ring-rose-600 focus:border-rose-700 transition"
>
</div>
<!-- Order -->
<select
wire:model.live="order"
class="px-4 py-3 rounded-lg border-neutral-300 dark:text-gray-300 bg-white/80 dark:bg-neutral-900/50 dark:border-neutral-700 min-w-[128px]"
>
<option value="created_at_desc">Newest</option>
<option value="created_at_asc">Oldest</option>
</select>
{{-- Order --}}
<div class="relative">
<i class="fa-solid fa-sort pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-neutral-400"></i>
<select
wire:model.live="order"
class="appearance-none pl-10 pr-8 py-2.5 rounded-xl border-neutral-300 dark:text-gray-300 bg-white dark:bg-neutral-900 dark:border-neutral-700 min-w-[128px]"
>
<option value="created_at_desc">Newest</option>
<option value="created_at_asc">Oldest</option>
</select>
</div>
</div>
</div>
<!-- Comments -->
<div class="space-y-4">
@forelse ($comments as $comment)
{{-- Comments --}}
<div class="space-y-3">
@forelse ($comments as $comment)
@php
$model = $comment->commentable;
$episode = $model instanceof \App\Models\Episode
? $model
: $model->episodes->first();
@php
$model = $comment->commentable;
$episode = $model instanceof \App\Models\Episode
? $model
: $model->episodes->first();
$url = route('hentai.index', ['title' => $model->slug]);
@endphp
$url = route('hentai.index', ['title' => $model->slug]);
@endphp
<a href="{{ $url }}#comment-{{ $comment->id }}"
wire:key="comment-{{ $comment->id }}"
class="block group">
<a href="{{ $url }}#comment-{{ $comment->id }}"
wire:key="comment-{{ $comment->id }}"
class="block group">
<div class="bg-white/40 dark:bg-neutral-950/40 backdrop-blur rounded-xl shadow hover:shadow-lg transition overflow-hidden">
<div class="rounded-xl bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow-sm ring-1 ring-black/5 dark:ring-white/5 hover:shadow-md hover:ring-rose-300/50 dark:hover:ring-rose-700/30 transition-all duration-200 overflow-hidden">
<div class="flex flex-col sm:flex-row">
<div class="flex flex-col sm:flex-row">
<!-- Thumbnail -->
<div class="sm:w-48 shrink-0">
<img
src="{{ $episode->gallery->first()->thumbnail_url }}"
alt=""
class="w-full h-40 sm:h-full object-cover"
>
{{-- Thumbnail --}}
<div class="sm:w-44 shrink-0">
<img
src="{{ $episode->gallery->first()->thumbnail_url }}"
alt="{{ $episode->title ?? '' }}"
class="w-full h-36 sm:h-full object-cover"
loading="lazy"
>
</div>
{{-- Content --}}
<div class="flex-1 p-4 flex flex-col justify-between min-w-0">
{{-- Episode Title --}}
<p class="text-xs font-medium text-rose-600 dark:text-rose-400 truncate mb-1">
{{ $episode->title ?? 'Episode' }}
</p>
{{-- Comment --}}
<div class="text-sm text-gray-700 dark:text-gray-300 line-clamp-2 leading-relaxed">
{!! $comment->presenter()->markdownBody() !!}
</div>
<!-- Content -->
<div class="flex-1 p-4 flex flex-col justify-between">
<!-- Comment -->
<div class="text-gray-800 dark:text-gray-200 text-sm line-clamp-3">
{!! $comment->presenter()->markdownBody() !!}
</div>
<!-- Meta -->
<div class="flex items-center justify-between mt-3 text-xs text-gray-700 dark:text-gray-400">
<span>
{{ $comment->presenter()->relativeCreatedAt() }}
</span>
<span class="text-rose-600 font-medium group-hover:underline">
View comment
</span>
</div>
{{-- Meta --}}
<div class="flex items-center justify-between mt-2.5 text-xs text-gray-500 dark:text-gray-400">
<span class="flex items-center gap-1">
<i class="fa-solid fa-clock text-[10px]"></i>
{{ $comment->presenter()->relativeCreatedAt() }}
</span>
<span class="text-rose-600 dark:text-rose-400 font-medium group-hover:underline">
View comment
</span>
</div>
</div>
</div>
</a>
@empty
<div class="flex bg-white/40 dark:bg-neutral-950/40 backdrop-blur rounded-xl shadow hover:shadow-lg transition overflow-hidden">
<div class="text-gray-800 dark:text-gray-200 text-center w-full p-4">
<p class="text-lg">No results</p>
<p class="text-sm opacity-70">(╥﹏╥)</p>
</div>
</div>
@endforelse
</div>
<!-- Pagination -->
<div>
{{ $comments->links('pagination::tailwind') }}
</div>
</a>
@empty
<div class="rounded-2xl bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow-sm ring-1 ring-black/5 dark:ring-white/5 p-12 text-center">
<div class="inline-flex h-20 w-20 items-center justify-center rounded-full bg-gray-100 dark:bg-neutral-800 mb-4">
<i class="fa-solid fa-comment-slash text-3xl text-gray-400 dark:text-gray-500"></i>
</div>
<h3 class="text-lg font-semibold text-gray-700 dark:text-gray-300">No comments found</h3>
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">You haven't commented on anything yet.</p>
</div>
@endforelse
</div>
{{-- Pagination --}}
<div>
{{ $comments->links('pagination::tailwind') }}
</div>
</div>
+127 -15
View File
@@ -1,27 +1,139 @@
<div>
<div class="md:ml-8 my-8 md:my-0 space-y-6 max-w-[100%] xl:max-w-[95%] 2xl:max-w-[95%]">
@include('livewire.partials.search-filter')
</div>
<input type="hidden" id="ts_reference" value="{{ Carbon\Carbon::now()->timestamp }}" />
<div class="relative md:ml-8 pt-5 mx-auto space-y-6 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[95%]" wire:keydown.right.window="nextPage" wire:keydown.left.window="previousPage">
{{ $episodes->appends(['tags' => $selectedtags])->links('pagination::tailwind') }}
<div class="flex items-center justify-center">
<div class="flex justify-center">
<div class="space-y-5">
{{-- Slim Profile Filter --}}
<div class="rounded-2xl border border-neutral-200/70 bg-white/80 p-4 shadow-sm backdrop-blur-xl dark:border-neutral-800/70 dark:bg-neutral-950/70">
<div class="flex flex-col sm:flex-row gap-3">
{{-- Search --}}
<div class="relative flex-1">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-4">
<svg class="h-4 w-4 text-neutral-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
</div>
<input
wire:model.live.debounce.400ms="search"
type="search"
placeholder="Search liked episodes..."
class="w-full rounded-xl border border-neutral-300 bg-white py-2.5 pl-11 pr-4 text-sm text-neutral-900 shadow-sm transition focus:border-rose-500 focus:outline-none focus:ring-2 focus:ring-rose-500/20 dark:border-neutral-700 dark:bg-neutral-900 dark:text-white dark:placeholder-neutral-500"
/>
</div>
{{-- Order --}}
<div class="relative">
<i class="fa-solid fa-sort pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-neutral-400"></i>
<select
wire:model.live="order"
class="w-full appearance-none rounded-xl border border-neutral-300 bg-white py-2.5 pl-10 pr-10 text-sm text-neutral-900 shadow-sm transition focus:border-rose-500 focus:outline-none focus:ring-2 focus:ring-rose-500/20 dark:border-neutral-700 dark:bg-neutral-900 dark:text-white"
>
<option value="az">A-Z</option>
<option value="za">Z-A</option>
<option value="recently-uploaded">{{ __('home.recently-uploaded') }}</option>
<option value="recently-released">{{ __('home.recently-released') }}</option>
<option value="oldest-uploads">{{ __('search.oldest-uploads') }}</option>
<option value="oldest-releases">{{ __('search.oldest-releases') }}</option>
<option value="view-count">{{ __('search.view-count') }}</option>
</select>
</div>
{{-- View --}}
<div class="relative">
<i class="fa-solid fa-list pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-neutral-400"></i>
<select
wire:model.live="view"
class="w-full appearance-none rounded-xl border border-neutral-300 bg-white py-2.5 pl-10 pr-10 text-sm text-neutral-900 shadow-sm transition focus:border-rose-500 focus:outline-none focus:ring-2 focus:ring-rose-500/20 dark:border-neutral-700 dark:bg-neutral-900 dark:text-white"
>
<option value="thumbnail">Thumbnail</option>
<option value="poster">Poster</option>
</select>
</div>
{{-- Filter Buttons --}}
<div class="flex gap-2">
<button
type="button"
data-te-toggle="modal"
data-te-target="#modalGenres"
class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-3.5 py-2.5 text-xs font-medium text-neutral-600 shadow-sm transition hover:border-rose-400 hover:bg-rose-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 dark:hover:bg-neutral-800"
>
<i class="fa-solid fa-sliders text-[10px]"></i>
Genres
@if($tagcount > 0)
<span class="inline-flex h-4 min-w-[16px] items-center justify-center rounded-full bg-rose-600 px-1 text-[9px] font-bold text-white">{{ $tagcount }}</span>
@endif
</button>
<button
type="button"
data-te-toggle="modal"
data-te-target="#modalBlacklist"
class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-3.5 py-2.5 text-xs font-medium text-neutral-600 shadow-sm transition hover:border-rose-400 hover:bg-rose-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 dark:hover:bg-neutral-800"
>
<i class="fa-solid fa-shield text-[10px]"></i>
Blacklist
@if($blacklistcount > 0)
<span class="inline-flex h-4 min-w-[16px] items-center justify-center rounded-full bg-rose-600 px-1 text-[9px] font-bold text-white">{{ $blacklistcount }}</span>
@endif
</button>
<button
type="button"
data-te-toggle="modal"
data-te-target="#modalStudios"
class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-3.5 py-2.5 text-xs font-medium text-neutral-600 shadow-sm transition hover:border-rose-400 hover:bg-rose-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 dark:hover:bg-neutral-800"
>
<i class="fa-solid fa-microphone-lines text-[10px]"></i>
Studios
@if($studiocount > 0)
<span class="inline-flex h-4 min-w-[16px] items-center justify-center rounded-full bg-rose-600 px-1 text-[9px] font-bold text-white">{{ $studiocount }}</span>
@endif
</button>
</div>
{{-- Hide Watched --}}
@auth
<label class="flex cursor-pointer items-center gap-2 rounded-xl border border-neutral-300 bg-white px-3.5 py-2.5 text-xs font-medium text-neutral-600 shadow-sm transition hover:border-rose-400 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 whitespace-nowrap">
<input
id="checkBoxHideWatched"
type="checkbox"
wire:model.live="hideWatched"
class="h-4 w-4 rounded border-neutral-300 text-rose-600 focus:ring-rose-500 dark:border-neutral-700 dark:bg-neutral-800"
/>
<span>Hide watched</span>
</label>
@endauth
</div>
</div>
{{-- Modals --}}
@include('modals.filter-genres')
@include('modals.filter-studios')
@include('modals.filter-blacklist')
<input type="hidden" id="ts_reference" value="{{ Carbon\Carbon::now()->timestamp }}" />
{{-- Results --}}
<div wire:keydown.right.window="nextPage" wire:keydown.left.window="previousPage">
{{ $episodes->appends(['tags' => $selectedtags])->links('pagination::tailwind') }}
<div class="mt-4">
@if ($view == 'thumbnail')
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-4 gap-2">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">
@else
<div class="grid grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-8 gap-2">
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-3">
@endif
@forelse($episodes as $episode)
@include('livewire.partials.search-result')
@empty
<div class="col-span-full">
<p class="text-2xl w-52 pt-6">No results (╥﹏╥)</p>
</div>
<div class="col-span-full">
<div class="rounded-2xl bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow-sm ring-1 ring-black/5 dark:ring-white/5 p-12 text-center">
<div class="inline-flex h-20 w-20 items-center justify-center rounded-full bg-gray-100 dark:bg-neutral-800 mb-4">
<i class="fa-solid fa-heart-crack text-3xl text-gray-400 dark:text-gray-500"></i>
</div>
<h3 class="text-lg font-semibold text-gray-700 dark:text-gray-300">No liked episodes</h3>
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Start exploring and like what you enjoy!</p>
</div>
</div>
@endforelse
</div>
</div>
{{ $episodes->appends(['tags' => $selectedtags])->links('pagination::tailwind') }}
</div>
{{ $episodes->appends(['tags' => $selectedtags])->links('pagination::tailwind') }}
</div>
</div
</div>
+43 -20
View File
@@ -1,28 +1,51 @@
<div>
<div class="relative mx-auto sm:px-6 lg:px-8 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[90%]"
wire:keydown.right.window="nextPage" wire:keydown.left.window="previousPage">
<ol class="border-l border-neutral-300 dark:border-neutral-500">
<div wire:keydown.right.window="nextPage" wire:keydown.left.window="previousPage" class="text-gray-900 dark:text-white">
<div class="relative">
{{-- Timeline --}}
<ol class="relative border-l-2 border-neutral-300/70 dark:border-neutral-600/70 ml-3 sm:ml-4">
@foreach ($watchedGrouped as $day => $episodes)
<li>
<div class="flex items-center pt-3 flex-start">
<div class="-ml-[5px] mr-3 h-[9px] w-[9px] rounded-full bg-neutral-300 dark:bg-neutral-500">
</div>
<p class="text-sm text-neutral-500 dark:text-neutral-300">
<li class="mb-10 ml-6 sm:ml-8 last:mb-0">
{{-- Timeline Dot --}}
<span class="absolute flex items-center justify-center w-6 h-6 rounded-full -left-3 ring-2 ring-white dark:ring-neutral-950 bg-rose-600 dark:bg-rose-500">
<i class="fa-solid fa-circle text-[6px] text-white"></i>
</span>
{{-- Date Header --}}
<div class="mb-4">
<time class="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-semibold text-gray-600 dark:text-gray-300 bg-gray-100/70 dark:bg-neutral-800/70">
<i class="fa-solid fa-calendar text-[10px] text-rose-500"></i>
{{ $episodes->first()->created_at->diffForHumans(['parts' => 1]) }}
</p>
</time>
<span class="ml-2 text-xs text-gray-400 dark:text-gray-500">
{{ $episodes->count() }} {{ Str::plural('episode', $episodes->count()) }}
</span>
</div>
<div class="flex justify-center">
<div class="grid grid-cols-1 gap-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-4">
@foreach ($episodes as $episode)
<div class="mt-2 mb-6 ml-4">
<x-episode-cover :episode="$episode->episode" view="thumbnail" />
</div>
@endforeach
</div>
{{-- Episodes Grid --}}
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">
@foreach ($episodes as $episode)
<x-episode-cover :episode="$episode->episode" view="thumbnail" />
@endforeach
</div>
</li>
@endforeach
</ol>
{{ $watched->links('pagination::tailwind') }}
{{-- Pagination --}}
@if($watched->hasPages())
<div class="mt-8">
{{ $watched->links('pagination::tailwind') }}
</div>
@endif
{{-- Empty State --}}
@if($watched->isEmpty())
<div class="rounded-2xl bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow-sm ring-1 ring-black/5 dark:ring-white/5 p-12 text-center">
<div class="inline-flex h-20 w-20 items-center justify-center rounded-full bg-gray-100 dark:bg-neutral-800 mb-4">
<i class="fa-solid fa-eye-slash text-3xl text-gray-400 dark:text-gray-500"></i>
</div>
<h3 class="text-lg font-semibold text-gray-700 dark:text-gray-300">No watch history</h3>
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Start watching and your history will appear here.</p>
</div>
@endif
</div>
</div>
</div>