Init
This commit is contained in:
95
resources/views/livewire/admin-user-search.blade.php
Normal file
95
resources/views/livewire/admin-user-search.blade.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<div>
|
||||
<div class="relative pt-5 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[90%]" wire:keydown.right.window="nextPage" wire:keydown.left.window="previousPage">
|
||||
<div class="flex items-center justify-center">
|
||||
<div class="relative overflow-x-auto rounded-lg w-3/6">
|
||||
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-white">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-pink-700 dark:text-neutral-200 ">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-3">
|
||||
Discord-ID
|
||||
<input
|
||||
class="w-4 h-4 ml-2 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
type="checkbox"
|
||||
wire:model.live="filtered"
|
||||
value="true"
|
||||
>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">
|
||||
Username
|
||||
<input
|
||||
wire:model.live.debounce.600ms="search"
|
||||
type="search"
|
||||
id="live-search"
|
||||
class="ml-2 w-32 h-7 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
||||
placeholder="Search..."
|
||||
>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">
|
||||
Patreon
|
||||
<input
|
||||
class="w-4 h-4 ml-2 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
type="checkbox"
|
||||
wire:model.live="patreon"
|
||||
value="true"
|
||||
>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">
|
||||
Banned
|
||||
<input
|
||||
class="w-4 h-4 ml-2 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
type="checkbox"
|
||||
wire:model.live="banned"
|
||||
value="true"
|
||||
>
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">
|
||||
Created at
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">
|
||||
Updated at
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3">
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($users as $user)
|
||||
<tr wire:key="user-{{ $user->id }}" class="bg-white border-t dark:bg-neutral-800 dark:border-pink-700">
|
||||
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
{{ $user->id }}
|
||||
</th>
|
||||
<td class="px-6 py-4">
|
||||
{{ $user->global_name ?? $user->username }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
{{ $user->is_patreon ? 'Yes' : 'No' }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
{{ $user->is_banned ? 'Yes' : 'No' }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
{{ $user->created_at->format('Y-m-d') }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
{{ $user->updated_at->format('Y-m-d') }}
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<form method="POST" action="{{ route('admin.user.update') }}">
|
||||
@csrf
|
||||
<input type="hidden" value="{{ $user->id }}" name="id">
|
||||
<input type="hidden" value="{{ $user->is_banned ? 'unban' : 'ban' }}" name="action">
|
||||
<button type="submit" class="inline-block rounded bg-rose-600 pl-[4px] pr-[4px] p-[1px] text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600">
|
||||
{{ $user->is_banned ? 'Unban' : 'Ban' }}
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{{ $users->links('pagination::tailwind') }}
|
||||
</div>
|
||||
</div>
|
95
resources/views/livewire/background-images.blade.php
Normal file
95
resources/views/livewire/background-images.blade.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<div>
|
||||
<!-- Table -->
|
||||
<div class="relative pt-5 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[90%]">
|
||||
<div class="flex items-center justify-center">
|
||||
<div class="relative overflow-x-auto rounded-lg w-3/6">
|
||||
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-white">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-pink-700 dark:text-neutral-200">
|
||||
<tr>
|
||||
<th class="px-6 py-3">Image</th>
|
||||
<th class="px-6 py-3">Data
|
||||
<select wire:model.live="filter" class="ml-2 p-[2px] w-20 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
<option value="all">All</option>
|
||||
<option value="active">Active</option>
|
||||
<option value="inactive">Inactive</option>
|
||||
</select>
|
||||
</th>
|
||||
<th class="px-6 py-3">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($images as $image)
|
||||
<tr wire:key="{{ $image->id }}" class="bg-white border-t dark:bg-neutral-800 dark:border-pink-700">
|
||||
<td class="px-6 py-4 h-[100px]">
|
||||
<img src="/images/background/{{ $image->id }}-640p.webp" class="rounded-lg" style="width: 200px;" />
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<form method="POST" action="{{ route('admin.background.update') }}">
|
||||
@csrf
|
||||
@method('put')
|
||||
<input type="hidden" value="{{ $image->id }}" name="id">
|
||||
<div class="flex">
|
||||
<div class="p-4">
|
||||
<label class="leading-tight text-gray-800 dark:text-gray-200 w-full" for="date_start">Start Date:</label>
|
||||
<input
|
||||
class="block text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
||||
type="date"
|
||||
name="date_start"
|
||||
id="date_start"
|
||||
value="{{ \Carbon\Carbon::parse($image->date_start)->format('Y-m-d') }}"
|
||||
required
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<label class="leading-tight text-gray-800 dark:text-gray-200 w-full" for="date_end">End Date:</label>
|
||||
<input
|
||||
class="block text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
||||
type="date"
|
||||
name="date_end"
|
||||
id="date_end"
|
||||
value="{{ \Carbon\Carbon::parse($image->date_end)->format('Y-m-d') }}"
|
||||
required
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="p-4 pt-11">
|
||||
<label class="leading-tight text-gray-800 dark:text-gray-200 w-full" for="default">Default:</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="default"
|
||||
id="default"
|
||||
value="1"
|
||||
@if ($image->default) checked @endif
|
||||
class="w-5 h-5 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="h-5 pt-10">
|
||||
<button type="submit" class="ml-1 inline-block rounded bg-sky-800 px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-sky-700 focus:bg-sky-600">
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
<td class="px-6 py-4 pt-[69px] flex">
|
||||
<form method="POST" action="{{ route('admin.background.delete') }}">
|
||||
@csrf
|
||||
@method('delete')
|
||||
<input type="hidden" value="{{ $image->id }}" name="id">
|
||||
<button type="submit" class="ml-1 inline-block rounded bg-rose-600 px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600">
|
||||
Delete
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{ $images->links('pagination::tailwind') }}
|
||||
</div>
|
||||
</div>
|
20
resources/views/livewire/download-button.blade.php
Normal file
20
resources/views/livewire/download-button.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<div>
|
||||
<a href="{{ $downloadUrl }}" wire:click="clicked({{ $downloadId }})" download>
|
||||
<button id="dl-{{ $downloadId }}" class="group rounded-md shadow {{ $background }} text-white cursor-pointer flex justify-between items-center overflow-hidden transition-all hover:glow m-1 w-[190px] h-[65px]">
|
||||
<div class="relative w-12 h-[65px] bg-white bg-opacity-20 text-white flex justify-center items-center transition-all">
|
||||
<svg class="w-4 h-4 transition-all group-hover:-translate-y-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex flex-col text-center w-full">
|
||||
@if($fillNumbers)
|
||||
<p class="text-lg">Episode {{ str_pad($episodeNumber, 2, '0', STR_PAD_LEFT) }}</p>
|
||||
@else
|
||||
<p class="text-lg">Episode {{ $episodeNumber }}</p>
|
||||
@endif
|
||||
<p class="text-xs">HEVC MKV {{ $fileSize ?? '' }}</p>
|
||||
<p class="text-xs" id="count-{{ $downloadId }}">Downloaded {{ $downloadCount }} times</p>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
54
resources/views/livewire/downloads-free.blade.php
Normal file
54
resources/views/livewire/downloads-free.blade.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<div>
|
||||
<p class="text-gray-800 dark:text-gray-200 text-center">
|
||||
You have <code>{{ $downloadsLeft }}/{{ config('hstream.free_downloads_count') }}</code> free daily 4k downloads left.
|
||||
<br>
|
||||
Free 4k downloads will only be available, if enough people are subscribed to patreon!
|
||||
<br>
|
||||
Patreon subscribers don't have any limits!
|
||||
</p>
|
||||
<div class="flex flex-wrap justify-around">
|
||||
@if ($granted === 0 && !$override)
|
||||
<a href="#" wire:click.prevent="generate">
|
||||
<button class="group rounded-md shadow bg-yellow-600 text-white cursor-pointer flex justify-between items-center overflow-hidden transition-all hover:glow m-1 w-[190px] h-[65px]">
|
||||
<div class="relative w-12 h-[65px] bg-white bg-opacity-20 text-white flex justify-center items-center transition-all">
|
||||
<svg class="w-4 h-4 transition-all group-hover:-translate-y-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex flex-col text-center w-full">
|
||||
<p class="text-lg">Generate download</p>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
@elseif ($granted === 1 || $override)
|
||||
@php
|
||||
$episode = \App\Models\Episode::where('id', $episodeId)->firstOrFail();
|
||||
$download = $interpolated == true ? $episode->getDownloadByType('UHDi') : $episode->getDownloadByType('UHD');
|
||||
|
||||
$now = \Illuminate\Support\Carbon::now();
|
||||
$expire = \Illuminate\Support\Facades\Crypt::encryptString($now->addHours(6));
|
||||
$file = \Illuminate\Support\Facades\Crypt::encryptString('hentai/'.$download->url);
|
||||
|
||||
$dlpdomains = config('hstream.download_domain_4k');
|
||||
$downloadURL = $dlpdomains[array_rand($dlpdomains)].'/download/'.$file.'/'.$expire;
|
||||
$fillNumbers = false;
|
||||
@endphp
|
||||
|
||||
<livewire:download-button
|
||||
:download-url="$downloadURL"
|
||||
:download-id="$download->id"
|
||||
:download-count="$download->count"
|
||||
:episode-number="$episode->episode"
|
||||
:fill-numbers="$fillNumbers"
|
||||
:file-size="$download->getFileSize()">
|
||||
@elseif ($granted === 3)
|
||||
<p class="text-red-600">
|
||||
Daily download limit reached!
|
||||
</p>
|
||||
@elseif ($granted === 4)
|
||||
<p class="text-red-600">
|
||||
Download will be available 7 days after release!
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
146
resources/views/livewire/downloads.blade.php
Normal file
146
resources/views/livewire/downloads.blade.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<div class="py-3">
|
||||
<div class="mx-auto sm:px-6 lg:px-8 space-y-6 max-w-[100%] xl:max-w-[80%] 2xl:max-w-[50%]">
|
||||
<!-- Search Filter -->
|
||||
<div class="p-4 sm:p-8 bg-white dark:bg-neutral-800 shadow sm:rounded-lg">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
|
||||
<!-- Title -->
|
||||
<div>
|
||||
<label for="live-search"
|
||||
class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" 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.600ms="search" type="search" id="live-search"
|
||||
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
||||
placeholder="{{ __('search.search-hentai') }}" required>
|
||||
|
||||
<div class="absolute right-0 top-[11px]" wire:loading>
|
||||
<svg aria-hidden="true"
|
||||
class="inline w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600"
|
||||
viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||
fill="currentFill" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Ordering -->
|
||||
<div>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<i class="fa-solid fa-sort text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<select wire:model.live="order"
|
||||
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
<option value="az">A-Z</option>
|
||||
<option value="za">Z-A</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="float-right text-gray-900 dark:text-white">
|
||||
<input type="checkbox" wire:model.live="withTorrents">
|
||||
Show only with Torrent
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@php $dldomains = config('hstream.download_domain'); @endphp
|
||||
|
||||
<div class="relative pt-5 mx-auto sm:px-6 lg:px-8 space-y-6 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[60%]" wire:keydown.right.window="nextPage" wire:keydown.left.window="previousPage">
|
||||
<div class="flex flex-col">
|
||||
<div class="overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div class="inline-block min-w-full py-2 sm:px-6 lg:px-8">
|
||||
<div class="overflow-hidden">
|
||||
|
||||
<!-- Desktop -->
|
||||
<table class="min-w-full text-left text-sm font-light collapse md:visible">
|
||||
<thead class="border-b font-medium dark:border-neutral-500 bg-white dark:bg-neutral-800 shadow sm:rounded-lg">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-4">Title</th>
|
||||
<th scope="col" class="px-6 py-4">Download</th>
|
||||
<th scope="col" class="px-6 py-4">Torrent</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($hentai as $h)
|
||||
@php $episode = $h->episodes->first(); @endphp
|
||||
<tr class="border-b dark:border-neutral-500">
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
{{ $episode->title }}
|
||||
@if ($episode->title != $episode->title_jpn)
|
||||
<br>
|
||||
{{ $episode->title_jpn }}
|
||||
@endif
|
||||
@auth
|
||||
@if(Auth::user()->is_admin)
|
||||
<br>
|
||||
<a href="{{ route('admin.add.torrentpage', ['hentai_id' => $h->id]) }}" target="_blank">Add Torrent</a>
|
||||
@endif
|
||||
@endauth
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
@foreach($h->episodes as $episode)
|
||||
@include('livewire.partials.download-button', ['hdl' => $episode])
|
||||
@endforeach
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
@include('livewire.partials.torrent-button', ['hentai' => $h])
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Mobile -->
|
||||
<table class="min-w-full text-left text-sm font-light visible md:collapse">
|
||||
<thead class="font-medium">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-4"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($hentai as $h)
|
||||
@php $episode = $h->episodes->first(); @endphp
|
||||
<tr class="border-b dark:border-neutral-500">
|
||||
<td class="px-2 py-4 grid grid-flow-row">
|
||||
{{ $episode->title }}
|
||||
@if ($episode->title != $episode->title_jpn)
|
||||
<br>
|
||||
{{ $episode->title_jpn }}
|
||||
@endif
|
||||
<br>
|
||||
<div class="flex flex-row flex-wrap">
|
||||
@foreach($h->episodes as $episode)
|
||||
@include('livewire.partials.download-button', ['hdl' => $episode])
|
||||
@endforeach
|
||||
@include('livewire.partials.torrent-button', ['hentai' => $h])
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ $hentai->links('pagination::tailwind') }}
|
||||
|
||||
</div>
|
||||
</div>
|
13
resources/views/livewire/like-button.blade.php
Normal file
13
resources/views/livewire/like-button.blade.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<div>
|
||||
@if (Auth::check())
|
||||
<div class="text-xl text-gray-800 dark:text-gray-200 leading-tight cursor-pointer whitespace-nowrap" wire:click="like" wire:poll.90000ms="update">
|
||||
@else
|
||||
<div data-te-toggle="tooltip" title="Please login to like the episode" class="text-xl text-gray-800 dark:text-gray-200 leading-tight cursor-pointer whitespace-nowrap" wire:poll.60000ms="update">
|
||||
@endif
|
||||
@if ($liked)
|
||||
<i class="fa-solid fa-heart pr-[4px] text-rose-600"></i> {{ $likeCount }}
|
||||
@else
|
||||
<i class="fa-regular fa-heart pr-[4px]"></i> {{ $likeCount }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
28
resources/views/livewire/live-search.blade.php
Normal file
28
resources/views/livewire/live-search.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<div class="py-24">
|
||||
<div class="mx-auto sm:px-6 lg:px-8 space-y-6 max-w-[100%] xl:max-w-[95%] 2xl:max-w-[90%]">
|
||||
@include('livewire.partials.search-filter')
|
||||
</div>
|
||||
<input type="hidden" id="ts_reference" value="{{ Carbon\Carbon::now()->timestamp }}" />
|
||||
<div class="relative pt-5 mx-auto sm:px-6 lg:px-8 space-y-6 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[90%]" 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">
|
||||
@if ($view == 'thumbnail')
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-2">
|
||||
@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">
|
||||
@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>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ $episodes->appends(['tags' => $selectedtags])->links('pagination::tailwind') }}
|
||||
</div>
|
||||
@vite(['resources/js/preview.js'])
|
||||
</div>
|
63
resources/views/livewire/nav-live-search.blade.php
Normal file
63
resources/views/livewire/nav-live-search.blade.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<div class="flex items-center">
|
||||
<form method="POST" action="{{ route('hentai.searchredirect') }}">
|
||||
@csrf
|
||||
<label for="live-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
|
||||
<div class="absolute right-2 left-2 sm:relative sm:min-w-[200px] md:min-w-[300px] lg:min-w-[400px] xl:min-w-[500px] transition-all">
|
||||
<div class="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" 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.600ms="navSearch" type="search" id="live-search" name="live-search" class="block p-4 pl-10 w-full text-sm text-gray-900 rounded-lg border border-gray-300/50 bg-gray-50/20 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900/40 dark:border-neutral-600/50 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900" placeholder="@if(request()->path() !== 'search'){{ __('search.search-hentai') }}@endif" required @if(request()->path() == 'search') disabled @endif>
|
||||
<button type="submit" class="absolute right-2.5 bottom-2.5 px-4 py-2 text-sm font-medium text-white bg-rose-700 rounded-lg hover:bg-rose-800 disabled:bg-gray-300 disabled:hover:bg-gray-300 disabled:dark:bg-gray-500 disabled:dark:hover:bg-gray-500 focus:ring-4 focus:outline-none focus:ring-rose-300 dark:bg-rose-600 dark:hover:bg-rose-700 dark:focus:ring-rose-800" @if(request()->path() == 'search') disabled @endif>{{ __('search.search') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if((! $hide) && request()->path() != 'search' && request()->path() != 'download-search')
|
||||
<!-- BG Blur and BG Size -->
|
||||
<div class="absolute left-0 sm:top-[65px] w-[100%] h-[calc(100vh-60px)] z-40 text-gray-900 dark:text-white bg-neutral-100/80 dark:bg-neutral-900/80">
|
||||
<div class="flex justify-center items-center">
|
||||
<!-- Padding for Grid -->
|
||||
<div class="flex justify-center w-5/6">
|
||||
<div class="grid grid-cols-1 gap-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
|
||||
@foreach($episodes as $episode)
|
||||
<div class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110">
|
||||
<a class="hover:text-blue-600" href="{{ route('hentai.index', ['title' => $episode->slug ]) }}">
|
||||
<div class="absolute w-[95%] top-[38%] text-center z-10">
|
||||
<svg aria-hidden="true" class="inline mr-2 w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
|
||||
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
|
||||
</svg>
|
||||
</div>
|
||||
<img
|
||||
alt="{{ $episode->title }} - {{ $episode->episode }}"
|
||||
loading="lazy"
|
||||
width="500"
|
||||
class="block object-cover object-center relative z-20 rounded-lg aspect-video"
|
||||
src="{{ $episode->gallery->first()->thumbnail_url }}">
|
||||
</img>
|
||||
<p class="absolute right-4 top-4 bg-white/80 dark:bg-neutral-700/80 !text-gray-900 dark:!text-white rounded-bl-lg rounded-lg p-1 pr-2 pl-2 font-semibold text-sm">{{ $episode->getResolution() }}</p>
|
||||
<p class="absolute left-4 bottom-4 bg-white/80 dark:bg-neutral-700/80 !text-gray-900 dark:!text-white rounded-bl-lg rounded-lg p-1 pr-2 pl-2 font-semibold text-sm"><i class="fa-regular fa-eye"></i> {{ $episode->view_count }} <i class="fa-regular fa-heart"></i> {{ count($episode->likes) }}</p>
|
||||
<p class="absolute w-[95%] text-center text-sm">{{ $episode->title }} - {{ $episode->episode }}</p>
|
||||
</a>
|
||||
</div>
|
||||
@endforeach
|
||||
<div class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110">
|
||||
<a class="hover:text-blue-600" href="{{ route('hentai.search', ['s' => $query]) }}">
|
||||
<img
|
||||
alt="gallery"
|
||||
loading="lazy"
|
||||
width="500"
|
||||
class="block object-cover object-center rounded-lg aspect-video"
|
||||
src="{{ $randomimage->thumbnail_url }}">
|
||||
</img>
|
||||
<p class="absolute left-2 top-2 w-[95%] h-[91.5%] bg-white/10 dark:bg-neutral-700/10 !text-gray-900 dark:!text-white rounded-bl-lg rounded-lg font-semibold p-4 pr-8 pl-8 text-center"></p>
|
||||
<p class="absolute left-[20%] top-[35%] bg-white/80 dark:bg-neutral-700/80 !text-gray-900 dark:!text-white rounded-bl-lg rounded-lg font-semibold p-4 pr-8 pl-8 text-center">Advanced Search...</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
13
resources/views/livewire/partials/download-button.blade.php
Normal file
13
resources/views/livewire/partials/download-button.blade.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<a href="{{ $dldomains[array_rand($dldomains)] }}/{{ $hdl->getDownloadByType('FHD')->url }}">
|
||||
<button class="group rounded-md shadow bg-rose-600 text-white cursor-pointer flex justify-between items-center overflow-hidden transition-all hover:glow m-1 w-[150px]">
|
||||
<div class="relative w-12 h-12 bg-white bg-opacity-20 text-white flex justify-center items-center transition-all"><svg id="arrow" class="w-4 h-4 transition-all group-hover:-translate-y-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
|
||||
</svg>
|
||||
<div id="progress" class="absolute w-full h-0 bg-white bg-opacity-20 top-0 duration-200"></div>
|
||||
</div>
|
||||
<div class="w-32 text-center">
|
||||
<p class="px-5 text-sm row-span-2">Episode {{ $hdl->episode }}</p>
|
||||
<p class="px-5 text-xs">HEVC MKV</p>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
123
resources/views/livewire/partials/search-filter.blade.php
Normal file
123
resources/views/livewire/partials/search-filter.blade.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<!-- Search Filter -->
|
||||
<div>
|
||||
<div class="p-4 sm:p-8 bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow sm:rounded-lg">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4">
|
||||
|
||||
<!-- Title -->
|
||||
<div>
|
||||
<label for="live-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" 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.600ms="search" type="search" id="live-search" class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900" placeholder="{{ __('search.search-hentai') }}" required>
|
||||
|
||||
<div class="absolute right-0 top-[11px]" wire:loading>
|
||||
<svg aria-hidden="true" class="inline w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor" />
|
||||
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Genres -->
|
||||
<div>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<i class="fa-solid fa-sliders text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<p data-te-toggle="modal" data-te-target="#modalGenres" data-te-ripple-init data-te-ripple-color="light" id="genres-filter" class="block cursor-pointer w-full p-4 pl-10 text-sm text-gray-500 dark:text-gray-400 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
@if($tagcount === 0)
|
||||
Select Genres
|
||||
@elseif($tagcount === 1)
|
||||
Selected {{$tagcount }} Genre
|
||||
@elseif($tagcount > 1)
|
||||
Selected {{$tagcount }} Genres
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Genres Blacklist -->
|
||||
<div>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<i class="fa-solid fa-shield text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<p data-te-toggle="modal" data-te-target="#modalBlacklist" data-te-ripple-init data-te-ripple-color="light" id="blacklist-filter" class="block cursor-pointer w-full p-4 pl-10 text-sm text-gray-500 dark:text-gray-400 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
@if($blacklistcount === 0)
|
||||
Select Blacklist
|
||||
@elseif($blacklistcount === 1)
|
||||
Selected {{ $blacklistcount }} Blacklist Item
|
||||
@elseif($blacklistcount > 1)
|
||||
Selected {{ $blacklistcount }} Blacklist Items
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Studios -->
|
||||
<div>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<i class="fa-solid fa-microphone-lines text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<p data-te-toggle="modal" data-te-target="#modalStudios" data-te-ripple-init data-te-ripple-color="light" id="studios-filter" class="block cursor-pointer w-full p-4 pl-10 text-sm text-gray-500 dark:text-gray-400 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
@if($studiocount === 0)
|
||||
Select Studios
|
||||
@elseif($studiocount === 1)
|
||||
Selected {{ $studiocount }} Studio
|
||||
@elseif($studiocount > 1)
|
||||
Selected {{ $studiocount }} Studios
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ordering -->
|
||||
<div class="grid grid-cols-2">
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<i class="fa-solid fa-sort text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<select wire:model.live="order" class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
<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>
|
||||
|
||||
<div class="relative right-2 left-0 ml-2 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<i class="fa-solid fa-list text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<select wire:model.live="view" class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
<option value="thumbnail">Thumbnail</option>
|
||||
<option value="poster">Poster</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@auth
|
||||
<div class="float-right pt-1">
|
||||
<input class="w-4 h-4 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
type="checkbox" wire:model.live="hideWatched" value="true" id="checkBoxHideWatched" />
|
||||
<label class="inline-block hover:cursor-pointer dark:text-white" for="checkBoxHideWatched">
|
||||
Hide watched
|
||||
</label>
|
||||
</div>
|
||||
@endauth
|
||||
</div>
|
||||
@include('modals.filter-genres')
|
||||
@include('modals.filter-studios')
|
||||
@include('modals.filter-blacklist')
|
||||
</div>
|
86
resources/views/livewire/partials/search-result.blade.php
Normal file
86
resources/views/livewire/partials/search-result.blade.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<div wire:key="episode-{{ $episode->id }}">
|
||||
@if ($searchIsJpn)
|
||||
<div class="relative p-1 mb-14 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110"
|
||||
data-thumbs="{{ optional($episode->gallery)->pluck('thumbnail_url') }}">
|
||||
@else
|
||||
<div class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110"
|
||||
data-thumbs="{{ optional($episode->gallery)->pluck('thumbnail_url') }}">
|
||||
@endif
|
||||
<a class="hover:text-blue-600" href="{{ route('hentai.index', ['title' => $episode->slug]) }}">
|
||||
<div class="absolute w-[95%] top-[38%] text-center z-10">
|
||||
<svg aria-hidden="true"
|
||||
class="inline mr-2 w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600"
|
||||
viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||
fill="currentFill" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@switch(true)
|
||||
@case($view === 'thumbnail')
|
||||
<img alt="{{ $episode->title }} - {{ $episode->episode }}" loading="lazy" width="500"
|
||||
class="block object-cover object-center relative z-20 rounded-lg aspect-video"
|
||||
src="{{ optional($episode->gallery->first())->thumbnail_url }}">
|
||||
@if ($episode->hasAutoTrans())
|
||||
<p
|
||||
class="absolute right-2 bottom-2 bg-blue-600/80 !text-white rounded-tl-lg rounded-br-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-regular fa-closed-captioning"></i> Multi-Subs
|
||||
</p>
|
||||
@endif
|
||||
@break
|
||||
|
||||
@case($view === 'poster')
|
||||
<img alt="{{ $episode->title }} - {{ $episode->episode }}" loading="lazy" width="400"
|
||||
class="block relative rounded-lg object-cover object-center aspect-[11/16] z-20"
|
||||
src="{{ $episode->cover_url }}">
|
||||
@break
|
||||
|
||||
@endswitch
|
||||
|
||||
@php $problematic = cache()->rememberForever('episodeProblematic'.$episode->id, fn () => $episode->getProblematicTags()); @endphp
|
||||
@if (!empty($problematic))
|
||||
<p
|
||||
class="absolute left-2 top-2 bg-red-700/70 !text-white rounded-br-lg rounded-tl-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-solid fa-triangle-exclamation"></i> {{ $problematic }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if (auth()->check() && $episode->userWatched(auth()->user()->id))
|
||||
<p
|
||||
class="absolute right-2 top-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-regular fa-eye"></i> {{ $episode->viewCountFormatted() }} <i
|
||||
class="fa-regular fa-heart"></i>
|
||||
{{ $episode->likeCount() }} <i class="fa-regular fa-comment"></i> {{ $episode->commentCount() }}
|
||||
</p>
|
||||
@else
|
||||
<p
|
||||
class="absolute right-2 top-2 bg-rose-700/70 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-rose-700/70 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-regular fa-eye"></i>
|
||||
{{ $episode->viewCountFormatted() }}
|
||||
<i class="fa-regular fa-heart"></i> {{ $episode->likeCount() }} <i class="fa-regular fa-comment"></i>
|
||||
{{ $episode->commentCount() }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
<div class="absolute w-[95%] grid grid-cols-1 text-center">
|
||||
@if ($searchIsJpn)
|
||||
<p class="text-sm text-center text-black dark:text-white">{{ $episode->title }}
|
||||
({{ $episode->title_jpn }}) - {{ $episode->episode }}</p>
|
||||
@else
|
||||
<p class="text-sm text-center text-black dark:text-white">{{ $episode->title }} -
|
||||
{{ $episode->episode }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
25
resources/views/livewire/partials/torrent-button.blade.php
Normal file
25
resources/views/livewire/partials/torrent-button.blade.php
Normal file
@@ -0,0 +1,25 @@
|
||||
@forelse ($hentai->torrents as $torrent)
|
||||
<a href="{{ $torrent->torrent_url }}" target="_blank">
|
||||
<button class="group rounded-md shadow bg-primary-600 text-white cursor-pointer flex justify-between items-center overflow-hidden transition-all hover:glow m-1 w-[150px]">
|
||||
<div class="relative w-12 h-12 bg-white bg-opacity-20 text-white flex justify-center items-center transition-all">
|
||||
<i id="arrow" class="fa-solid fa-magnet transition-all group-hover:-translate-y-1"></i>
|
||||
<div id="progress" class="absolute w-full h-0 bg-white bg-opacity-20 top-0 duration-200"></div>
|
||||
</div>
|
||||
<div class="w-32 text-center">
|
||||
<p class="text-sm">Episode {{ $torrent->episodes }}</p>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
@empty
|
||||
<a>
|
||||
<button class="group rounded-md shadow bg-gray-600 text-white cursor-pointer flex justify-between items-center overflow-hidden transition-all hover:glow m-1 w-[150px]">
|
||||
<div class="relative w-12 h-12 bg-white bg-opacity-20 text-white flex justify-center items-center transition-all">
|
||||
<i id="arrow" class="fa-solid fa-magnet transition-all group-hover:-translate-y-1"></i>
|
||||
<div id="progress" class="absolute w-full h-0 bg-white bg-opacity-20 top-0 duration-200"></div>
|
||||
</div>
|
||||
<div class="w-32 text-center">
|
||||
<p class="text-sm">Torrent not available</p>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
@endforelse
|
101
resources/views/livewire/playlist-overview.blade.php
Normal file
101
resources/views/livewire/playlist-overview.blade.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<div>
|
||||
<div
|
||||
class="relative pt-5 mx-auto sm:px-6 lg:px-8 space-y-6 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[90%]">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="flex text-sm font-light bg-neutral-950/50 backdrop-blur-lg rounded-lg p-10 gap-2">
|
||||
<a href="{{ route('user.index', ['username' => $playlist->user->username]) }}">
|
||||
@if ($playlist->user->avatar)
|
||||
<img class="relative w-24 h-24 flex-none rounded-full shadow-lg"
|
||||
src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ $playlist->user->id }}/{{ $playlist->user->avatar }}.webp">
|
||||
@else
|
||||
<img class="relative w-24 h-24 flex-none rounded-full shadow-lg" src="/images/default-avatar.webp">
|
||||
@endif
|
||||
</a>
|
||||
<div class="flex flex-col justify-center flex-1 pl-4">
|
||||
<h1 class="font-bold text-3xl">{{ $playlist->name }}</h1>
|
||||
<p class="font-light text-lg text-neutral-200">Episodes: {{ count($playlistEpisodes) }}</p>
|
||||
<p class="font-light text-lg text-neutral-200">Creator: <a
|
||||
href="{{ route('user.index', ['username' => $playlist->user->username]) }}">{{ $playlist->user->username }}</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center pl-4">
|
||||
<div class="flex justify-end">
|
||||
<a href="{{ route('hentai.index', ['title' => $playlistEpisodes->first()->episode->slug, 'playlist' => $playlist->id]) }}"
|
||||
class="cursor-pointer float-right text-white bg-rose-700 hover:bg-rose-800 focus:ring-4 focus:outline-none focus:ring-rose-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-rose-600 dark:hover:bg-rose-700 dark:focus:ring-rose-800">{{ __('playlist.play') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@forelse($playlistEpisodes as $playlistEpisode)
|
||||
@php $episode = $playlistEpisode->episode; @endphp
|
||||
<div wire:key="playlist-episode-{{ $playlistEpisode->id }}"
|
||||
class="flex justify-between items-center rounded-lg hover:bg-black border border-neutral-950 bg-neutral-950/50 backdrop-blur-lg transition !mt-1 gap-2">
|
||||
<div class="flex pl-5 pr-5 w-10">
|
||||
{{ $playlistEpisode->position }}
|
||||
</div>
|
||||
<div class="flex-[2] hidden md:block">
|
||||
<div class="relative p-1 w-full md:p-2">
|
||||
<a href="{{ route('hentai.index', ['title' => $episode->slug]) }}">
|
||||
<img alt="{{ $episode->title }} - {{ $episode->episode }}" loading="lazy" width="1000"
|
||||
class="block object-cover object-center relative z-20 rounded-lg aspect-video"
|
||||
src="{{ $episode->gallery->first()->thumbnail_url }}">
|
||||
|
||||
@guest
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-rose-700/70 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30 collapse md:visible">
|
||||
<i class="fa-regular fa-eye"></i> {{ $episode->viewCountFormatted() }} <i
|
||||
class="fa-regular fa-heart"></i>
|
||||
{{ $episode->likeCount() }} <i class="fa-regular fa-comment"></i>
|
||||
{{ $episode->commentCount() }}
|
||||
</p>
|
||||
@endguest
|
||||
|
||||
@auth
|
||||
@if ($episode->userWatched(auth()->user()->id))
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-regular fa-eye"></i> {{ $episode->viewCountFormatted() }} <i
|
||||
class="fa-regular fa-heart"></i> {{ $episode->likeCount() }} <i
|
||||
class="fa-regular fa-comment"></i>
|
||||
{{ $episode->commentCount() }}
|
||||
</p>
|
||||
@else
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-rose-700/70 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-regular fa-eye"></i> {{ $episode->viewCountFormatted() }} <i
|
||||
class="fa-regular fa-heart"></i> {{ $episode->likeCount() }} <i
|
||||
class="fa-regular fa-comment"></i>
|
||||
{{ $episode->commentCount() }}
|
||||
</p>
|
||||
@endif
|
||||
@endauth
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-[5]">
|
||||
<a href="{{ route('hentai.index', ['title' => $episode->slug]) }}"
|
||||
class="font-bold">{{ $episode->title }} - {{ $episode->episode }}</a>
|
||||
<br>
|
||||
<a href="{{ route('hentai.index', ['title' => $episode->slug]) }}">{{ $episode->title_jpn }}</a>
|
||||
</div>
|
||||
<div class="pr-5">
|
||||
@auth
|
||||
@if (Auth::user()->id === $playlist->user->id)
|
||||
<button class="pr-2" wire:click="moveUp({{ $playlistEpisode->id }})"><i
|
||||
class="fa-solid fa-arrow-up"></i></button>
|
||||
<button class="pr-2" wire:click="moveDown({{ $playlistEpisode->id }})"><i
|
||||
class="fa-solid fa-arrow-down"></i></button>
|
||||
<button wire:click="remove({{ $playlistEpisode->id }})" class="text-red-500"><i
|
||||
class="fa-solid fa-trash"></i></button>
|
||||
@endif
|
||||
@endauth
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="pt-6 text-2xl text-center">
|
||||
No results (╥﹏╥)
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
83
resources/views/livewire/playlists.blade.php
Normal file
83
resources/views/livewire/playlists.blade.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<div>
|
||||
<!-- Search -->
|
||||
<div class="p-4 mx-3 sm:p-8 bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow sm:rounded-lg">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="live-search"
|
||||
class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" 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.600ms="search" type="search" id="playlist-search"
|
||||
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
||||
placeholder="Search Playlist...">
|
||||
|
||||
<div class="absolute right-0 top-[11px]" wire:loading>
|
||||
<svg aria-hidden="true"
|
||||
class="inline w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600"
|
||||
viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||
fill="currentFill" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Ordering -->
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<i class="fa-solid fa-sort text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<select wire:model.live="order"
|
||||
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
||||
<option value="az">A-Z</option>
|
||||
<option value="za">Z-A</option>
|
||||
<option value="episode-count">Episode count</option>
|
||||
<option value="newest">Newest</option>
|
||||
<option value="oldest">Oldest</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-cols-1 sm:grid md:grid-cols-3" wire:keydown.right.window="nextPage"
|
||||
wire:keydown.left.window="previousPage">
|
||||
|
||||
@foreach ($playlists as $playlist)
|
||||
<div wire:key="playlist-{{ $playlist->id }}"
|
||||
class="mx-3 mt-6 flex flex-col rounded-lg bg-white shadow-[0_2px_15px_-3px_rgba(0,0,0,0.07),0_10px_20px_-2px_rgba(0,0,0,0.04)] dark:bg-neutral-950/50 backdrop-blur-lg sm:shrink-0 sm:grow sm:basis-0 z-10">
|
||||
<a href="{{ route('playlist.show', $playlist->id) }}">
|
||||
@php
|
||||
$pe = \App\Models\PlaylistEpisode::where('playlist_id', $playlist->id)
|
||||
->orderBy('position', 'desc')
|
||||
->first();
|
||||
@endphp
|
||||
<img class="rounded-t-lg aspect-video" src="{{ $pe->episode->gallery->first()->thumbnail_url }}"
|
||||
alt="Hollywood Sign on The Hill" />
|
||||
</a>
|
||||
<div class="p-6">
|
||||
<h5 class="mb-2 text-xl font-medium leading-tight text-neutral-800 dark:text-neutral-50">
|
||||
{{ $playlist->name }}
|
||||
</h5>
|
||||
<p class="mb-2 text-sm leading-tight text-neutral-800 dark:text-neutral-50">
|
||||
{{ $playlist->episodes_count }} {{ __('home.episodes') }}
|
||||
<a href="{{ route('hentai.index', ['title' => $playlist->episodes->first()->episode->slug, 'playlist' => $playlist->id]) }}"
|
||||
class="cursor-pointer float-right text-white bg-rose-700 hover:bg-rose-800 focus:ring-4 focus:outline-none focus:ring-rose-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-rose-600 dark:hover:bg-rose-700 dark:focus:ring-rose-800">{{ __('playlist.play') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="mt-10 mb-10">
|
||||
{{ $playlists->links('pagination::tailwind') }}
|
||||
</div>
|
||||
</div>
|
28
resources/views/livewire/user-likes.blade.php
Normal file
28
resources/views/livewire/user-likes.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<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">
|
||||
@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">
|
||||
@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">
|
||||
@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>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ $episodes->appends(['tags' => $selectedtags])->links('pagination::tailwind') }}
|
||||
</div>
|
||||
@vite(['resources/js/preview.js'])
|
||||
</div
|
5
resources/views/livewire/view-count.blade.php
Normal file
5
resources/views/livewire/view-count.blade.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<div>
|
||||
<a class="text-xl text-gray-800 dark:text-gray-200 leading-tight whitespace-nowrap" wire:poll.90000ms="update">
|
||||
<i class="fa-regular fa-eye pr-0.5"></i> {{ $viewCount }}
|
||||
</a>
|
||||
</div>
|
28
resources/views/livewire/watched.blade.php
Normal file
28
resources/views/livewire/watched.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<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">
|
||||
@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">
|
||||
{{ $episodes->first()->created_at->diffForHumans(['parts' => 1]) }}
|
||||
</p>
|
||||
</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-5">
|
||||
@foreach ($episodes as $episode)
|
||||
<div class="mt-2 mb-6 ml-4">
|
||||
<x-episode-thumbnail :episode="$episode->episode" />
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
{{ $watched->links('pagination::tailwind') }}
|
||||
</div>
|
||||
</div
|
Reference in New Issue
Block a user