Update series page

This commit is contained in:
DariusIII
2026-07-11 11:40:39 +02:00
parent 60c85e2e63
commit 254faf3050
3 changed files with 116 additions and 144 deletions
+1
View File
@@ -39,6 +39,7 @@ const lazyComponentMap = {
'copyToClipboard': () => import('./components/profile-edit.js'), // same file
'cartPage': () => import('./components/cart-page.js'),
'releaseMultiOps': () => import('./components/cart-page.js'), // same file
'seriesSeasonLoader': () => import('./components/series-season-loader.js'),
'authPage': () => import('./components/auth-page.js'),
'otpInput': () => import('./components/auth-page.js'), // same file
'loginMode': () => import('./components/login-mode.js'),
+18 -108
View File
@@ -198,9 +198,10 @@
</div>
<!-- Episodes by Season - Tabbed Interface -->
@if(!empty($seasons))
@if(!empty($seasonTabs))
<div id="series-episodes" x-data="seriesSeasonLoader" data-series-season-loader>
<form id="nzb_multi_operations_form" method="get" x-data="releaseMultiOps">
<div class="series-episodes-card bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-sm" x-data="seasonSwitcher">
<div class="series-episodes-card bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-sm">
<div class="px-4 py-3 bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600">
<div class="flex items-center justify-between">
<h5 class="text-lg font-semibold text-gray-800 dark:text-white">
@@ -233,125 +234,35 @@
<label for="chkSelectAll" class="text-sm text-gray-700 dark:text-gray-300 cursor-pointer">Select All</label>
</div>
<nav class="flex flex-wrap -mb-px px-4" aria-label="Tabs">
@foreach($seasons as $seasonNumber => $episodes)
<button type="button"
class="season-tab whitespace-nowrap py-4 px-6 border-b-2 font-medium text-sm transition-colors duration-200"
:class="activeSeason === '{{ $seasonNumber }}' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-300 hover:border-gray-300'"
data-season="{{ $seasonNumber }}">
Season {{ $seasonNumber }}
<span class="ml-2 px-2 py-0.5 rounded-full text-xs"
:class="activeSeason === '{{ $seasonNumber }}' ? 'bg-blue-100 text-blue-800' : 'bg-gray-100 dark:bg-gray-800 text-gray-600'">
{{ count($episodes) }}
@foreach($seasonTabs as $tab)
<a href="{{ $tab['url'] }}"
class="series-season-tab whitespace-nowrap py-4 px-6 border-b-2 font-medium text-sm transition-colors duration-200 {{ $tab['active'] ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-300 hover:border-gray-300' }}"
data-season="{{ $tab['season'] }}"
data-series-season-link
@if($tab['active']) aria-current="page" @endif>
Season {{ $tab['season'] }}
<span class="ml-2 px-2 py-0.5 rounded-full text-xs {{ $tab['active'] ? 'bg-blue-100 text-blue-800' : 'bg-gray-100 dark:bg-gray-800 text-gray-600' }}">
{{ $tab['count'] }}
</span>
</button>
</a>
@endforeach
</nav>
</div>
<!-- Season Content -->
<div class="p-4">
@foreach($seasons as $seasonNumber => $episodes)
<div class="season-content" data-season="{{ $seasonNumber }}" x-show="activeSeason === '{{ $seasonNumber }}'">
@foreach($episodes as $episodeNumber => $releases)
<div class="mb-4 pb-4 border-b border-gray-200 dark:border-gray-700 last:border-b-0">
<h6 class="font-semibold text-gray-700 dark:text-gray-300 mb-2">
Episode {{ $episodeNumber }}
</h6>
<div class="space-y-2">
@foreach($releases as $release)
<div class="series-episode-card flex items-center gap-3 bg-gray-50 dark:bg-gray-900 rounded-lg p-3 hover:bg-gray-100 dark:hover:bg-gray-800">
<div class="shrink-0">
<input type="checkbox" class="chkRelease rounded border-gray-300 dark:border-gray-600 text-blue-600 dark:text-blue-500 focus:ring-blue-500 dark:focus:ring-blue-400 dark:bg-gray-700" name="release[]" value="{{ $release->guid }}" @change="onCheckboxChange()">
</div>
<div class="flex-1">
<div class="flex items-center gap-2 flex-wrap">
<a href="{{ url('/details/' . $release->guid) }}"
class="text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 font-medium wrap-break-word break-all">
{{ $release->searchname }}
</a>
@if(($release->failed_count ?? 0) > 0)
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800"
title="{{ $release->failed_count }} user(s) reported download failure">
<i class="fas fa-exclamation-triangle mr-1"></i> Failed ({{ $release->failed_count }})
</span>
@endif
</div>
<div class="text-xs text-gray-500 mt-1 flex flex-wrap gap-2">
<span class="mr-3">
<i class="fa fa-hdd-o mr-1"></i>{{ formatBytes($release->size) }}
</span>
<span>
<i class="fa fa-clock-o mr-1"></i>Added: {{ userDateDiffForHumans($release->adddate) }}
</span>
@if(!empty($release->postdate))
<span>
<i class="fas fa-calendar mr-1"></i> Posted: {{ userDate($release->postdate, 'M d, Y H:i') }}
</span>
@endif
@if(!empty($release->fromname))
<span class="inline-flex items-center px-2 py-0.5 rounded bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 font-mono">
<i class="fas fa-user mr-1"></i>{{ $release->fromname }}
</span>
@endif
</div>
</div>
<div class="flex gap-2">
<a href="{{ url('/getnzb?id=' . $release->guid) }}"
class="download-nzb px-3 py-1 bg-green-600 dark:bg-green-700 text-white rounded hover:bg-green-700 dark:hover:bg-green-800 text-sm"
title="Download NZB">
<i class="fa fa-download"></i>
</a>
<a href="{{ url('/details/' . $release->guid) }}"
class="px-3 py-1 bg-blue-600 dark:bg-blue-700 text-white rounded hover:bg-blue-700 dark:hover:bg-blue-800 text-sm"
title="View Details">
<i class="fa fa-info-circle"></i>
</a>
<a href="#" class="add-to-cart px-3 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-300 text-sm"
data-guid="{{ $release->guid }}"
title="Add to cart">
<i class="icon_cart fa fa-shopping-basket"></i>
</a>
</div>
</div>
{{-- Season switcher functionality moved to csp-safe.js --}}
@endforeach
</div>
</div>
@endforeach
</div>
@endforeach
</div>
@include('series.partials.season-content')
</div>
</form>
<div data-series-pagination-container>
@include('series.partials.season-pagination')
</div>
</div>
@else
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 text-blue-800">
<i class="fa fa-info-circle mr-2"></i>
No episodes/releases found for this series.
</div>
@endif
@if(!empty($pagination['per_page']) && $pagination['per_page'] > 0 && ($pagination['total_pages'] ?? 1) > 1)
<div class="series-stat-card mt-6 flex items-center justify-between bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
<div class="text-sm text-gray-600 dark:text-gray-300">
Page {{ $pagination['current_page'] }} of {{ $pagination['total_pages'] }}
<span class="ml-2 text-xs text-gray-500">({{ number_format($pagination['total_rows']) }} total releases)</span>
</div>
<div class="flex gap-2">
@php
$prevPage = max($pagination['current_page'] - 1, 1);
$nextPage = min($pagination['current_page'] + 1, $pagination['total_pages']);
@endphp
<a href="{{ $pagination['current_page'] > 1 ? request()->fullUrlWithQuery(['page' => $prevPage]) : '#' }}"
class="px-4 py-2 rounded-lg text-sm font-medium {{ $pagination['current_page'] > 1 ? 'bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700' : 'bg-gray-200 dark:bg-gray-700 text-gray-400 cursor-not-allowed' }}">
<i class="fas fa-arrow-left mr-2"></i>Previous
</a>
<a href="{{ $pagination['current_page'] < $pagination['total_pages'] ? request()->fullUrlWithQuery(['page' => $nextPage]) : '#' }}"
class="px-4 py-2 rounded-lg text-sm font-medium {{ $pagination['current_page'] < $pagination['total_pages'] ? 'bg-blue-600 text-white hover:bg-blue-700' : 'bg-gray-200 dark:bg-gray-700 text-gray-400 cursor-not-allowed' }}">
Next<i class="fas fa-arrow-right ml-2"></i>
</a>
</div>
</div>
@endif
@endif
</div>
</div>
@@ -360,4 +271,3 @@
@push('scripts')
@include('partials.cart-script')
@endpush