A lot of things
- Added Database page. - Added Xenforo API compatibility - Added Hovercard - Added Notifications
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<div class="filter-group" x-data="{open:false,search:''}">
|
||||
<div class="filter-title-row" @click="open = !open">
|
||||
<div class="filter-title-left">
|
||||
<h4 class="filter-title">{{ $title }}</h4>
|
||||
<span class="internal-filter-count" x-show="$wire.{{ $model }}.length > 0" x-text="$wire.{{ $model }}.length"></span>
|
||||
</div>
|
||||
<div class="filter-title-right" @click.stop>
|
||||
<div class="filter-mode">
|
||||
<button type="button" wire:click="$set('{{ $modeModel }}', 'or')" class="filter-btn-mode {{ $selectedMode === 'or' ? 'active' : '' }}">OR</button>
|
||||
<button type="button" wire:click="$set('{{ $modeModel }}', 'and')" class="filter-btn-mode {{ $selectedMode === 'and' ? 'active' : '' }}">AND</button>
|
||||
</div>
|
||||
<button type="button" class="internal-filter-clear" x-show="$wire.{{ $model }}.length > 0" @click="$wire.set('{{ $model }}',[])" title="Clear">
|
||||
<i data-lucide="x" size="11"></i>
|
||||
</button>
|
||||
<i data-lucide="chevron-down" size="14" class="filter-chevron" :class="{ 'rotated': !open }"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div x-show="open" x-transition>
|
||||
<div class="internal-filter-search">
|
||||
<i data-lucide="search" size="13"></i>
|
||||
<input type="text" x-model="search" placeholder="Search...">
|
||||
</div>
|
||||
<div class="filter-options">
|
||||
@foreach($items as $item)
|
||||
<label class="filter-option" x-show="search.length >= 3 && '{{strtolower($item->{$nameProperty}) }}'.includes(search.toLowerCase())">
|
||||
<input type="checkbox" wire:model.live="{{ $model }}" value="{{ $item->{$idProperty} }}">
|
||||
{{ $item->{$nameProperty} }}
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
<div class="filter-group" x-data="{open:false}">
|
||||
<div class="filter-title-row" @click="open = !open">
|
||||
<div class="filter-title-left">
|
||||
<h4 class="filter-title">{{ $title }}</h4>
|
||||
<span class="internal-filter-count" x-show="$wire.{{ $model }}.length > 0" x-text="$wire.{{ $model }}.length"></span>
|
||||
</div>
|
||||
<div class="filter-title-right" @click.stop>
|
||||
<div class="filter-mode">
|
||||
<button type="button" wire:click="$set('{{ $modeModel }}', 'or')" class="filter-btn-mode {{ $selectedMode === 'or' ? 'active' : '' }}">OR</button>
|
||||
<button type="button" wire:click="$set('{{ $modeModel }}', 'and')" class="filter-btn-mode {{ $selectedMode === 'and' ? 'active' : '' }}">AND</button>
|
||||
</div>
|
||||
<button type="button" class="internal-filter-clear" x-show="$wire.{{ $model }}.length > 0" @click="$wire.set('{{ $model }}',[])" title="Clear">
|
||||
<i data-lucide="x" size="11"></i>
|
||||
</button>
|
||||
<i data-lucide="chevron-down" size="14" class="filter-chevron" :class="{ 'rotated': !open }"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-options" x-show="open" x-transition>
|
||||
@foreach($items as $item)
|
||||
<label class="filter-option">
|
||||
<input type="checkbox" wire:model.live="{{ $model }}" value="{{ $item->{$idProperty} }}">
|
||||
{{ $item->{$nameProperty} }}
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="filter-group" x-data="{open: false,search:''}">
|
||||
<div class="filter-title-row" @click="open = !open">
|
||||
<div class="filter-title-left">
|
||||
<h4 class="filter-title">{{ $title }}</h4>
|
||||
<span class="internal-filter-count" x-show="$wire.{{ $model }}.length > 0" x-text="$wire.{{ $model }}.length"></span>
|
||||
</div>
|
||||
<div class="filter-title-right" @click.stop>
|
||||
<button type="button" class="internal-filter-clear" x-show="$wire.{{ $model }}.length > 0" @click="$wire.set('{{ $model }}',[])" title="Clear">
|
||||
<i data-lucide="x" size="11"></i>
|
||||
</button>
|
||||
<i data-lucide="chevron-down" size="14" class="filter-chevron" :class="{ 'rotated': !open }"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div x-show="open" x-transition>
|
||||
<div class="internal-filter-search">
|
||||
<i data-lucide="search" size="13"></i>
|
||||
<input type="text" x-model="search" placeholder="Search...">
|
||||
</div>
|
||||
<div class="filter-options">
|
||||
@foreach($items as $item)
|
||||
<label class="filter-option" x-show="search.length >= 3 && '{{strtolower($item->{$nameProperty}) }}'.includes(search.toLowerCase())">
|
||||
<input type="checkbox" wire:model.live="{{ $model }}" value="{{ $item->{$idProperty} }}">
|
||||
{{ $item->{$nameProperty} }}
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
<div class="filter-group" x-data="{open: false}">
|
||||
<div class="filter-title-row" @click="open = !open">
|
||||
<div class="filter-title-left">
|
||||
<h4 class="filter-title">{{ $title }}</h4>
|
||||
<span class="internal-filter-count" x-show="$wire.{{ $model }}.length > 0" x-text="$wire.{{ $model }}.length"></span>
|
||||
</div>
|
||||
<div class="filter-title-right" @click.stop>
|
||||
<button type="button" class="internal-filter-clear" x-show="$wire.{{ $model }}.length > 0" @click="$wire.set('{{ $model }}',[])" title="Clear">
|
||||
<i data-lucide="x" size="11"></i>
|
||||
</button>
|
||||
<i data-lucide="chevron-down" size="14" class="filter-chevron" :class="{ 'rotated': !open }"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-options" x-show="open" x-transition>
|
||||
@foreach($items as $item)
|
||||
<label class="filter-option">
|
||||
<input type="checkbox" wire:model.live="{{ $model }}" value="{{ $item->{$idProperty} }}">
|
||||
{{ $item->{$nameProperty} }}
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
40
resources/views/components/entry-card.blade.php
Normal file
40
resources/views/components/entry-card.blade.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="entry-card">
|
||||
<div class="entry-cover-wrapper">
|
||||
<span class="entry-badge">{{ $entry->getRealPlatform()?->name ?? 'Unknown' }}</span>
|
||||
@if( $entry->main_image )
|
||||
<img src="{{ Storage::url($entry->main_image) }}">
|
||||
@else
|
||||
<i data-lucide="image" size="40" color="var(--border)"></i>
|
||||
@endif
|
||||
</div>
|
||||
<div class="entry-card-info">
|
||||
<div class="entry-card-title">{{ $entry->title }}</div>
|
||||
<div class="entry-card-author">
|
||||
@forelse( $entry->authors as $author)
|
||||
@if($loop->first)By @endif
|
||||
{{ $author-> name }}
|
||||
@if( !$loop->last ), @endif
|
||||
@empty
|
||||
No authors
|
||||
@endforelse
|
||||
</div>
|
||||
<div style="margin-bottom:10px">
|
||||
<span class="badge {{ $entry->type }}">{{ \App\View\Components\EntryCard::ENTRY_TYPES_BADGE[$entry->type] ?? $entry->type }}</span>
|
||||
@if( section_must_be('romhacks', $entry->type ) )
|
||||
@foreach( $entry->modifications as $modif )
|
||||
<span class="badge orange">{{ $modif->name }}</span>
|
||||
@endforeach
|
||||
@if( $entry->status_id )
|
||||
<span class="badge">{{ $entry->status->name }}</span>
|
||||
@endif
|
||||
@foreach( $entry->languages as $lang )
|
||||
<span class="badge">{{ $lang->name }}</span>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
<div class="entry-card-meta">
|
||||
<span><i data-lucide="download" size="12"></i> x</span>
|
||||
<span>Added: {{ $entry->created_at->format('y-m-d') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
76
resources/views/components/hovercard.blade.php
Normal file
76
resources/views/components/hovercard.blade.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<div
|
||||
x-data
|
||||
x-show="$store.hovercard.start"
|
||||
x-cloak
|
||||
class="hovercard-overlay hovercard"
|
||||
:style="{ left: $store.hovercard.x + 'px', top: $store.hovercard.y + 'px' }"
|
||||
@mouseleave="$store.hovercard.close()"
|
||||
@keydown.escape.window="$store.hovercard.close()"
|
||||
>
|
||||
|
||||
<template x-if="$store.hovercard.loading">
|
||||
<div class="hovercard-overlay-loading">
|
||||
<i data-lucide="loader-2" class="spin"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template x-if="$store.hovercard.error">
|
||||
<div class="hovercard-overlay-error">
|
||||
<i data-lucide="alert-circle"></i>
|
||||
<p>Failed to load profile.</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template x-if="$store.hovercard.data && !$store.hovercard.loading && !$store.hovercard.error">
|
||||
<div>
|
||||
<div class="hovercard-header">
|
||||
<div
|
||||
class="hovercard-avatar"
|
||||
:style="$store.hovercard.data.avatar_url === null
|
||||
? { background: $store.hovercard.data.avatar_color }
|
||||
: {}"
|
||||
>
|
||||
<template x-if="$store.hovercard.data.avatar_url !== null">
|
||||
<img :src="$store.hovercard.data.avatar_url" alt="avatar">
|
||||
</template>
|
||||
<template x-if="$store.hovercard.data.avatar_url === null">
|
||||
<span x-text="$store.hovercard.data.avatar_letter"></span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hovercard-body">
|
||||
<div class="hovercard-username" x-text="$store.hovercard.data.username"></div>
|
||||
<div class="hovercard-title" x-text="$store.hovercard.data.group_name"></div>
|
||||
|
||||
<div class="hovercard-stats">
|
||||
<div class="hovercard-stat">
|
||||
<span class="stat-value" x-text="$store.hovercard.data.message_count"></span>
|
||||
<span class="stat-label">Messages</span>
|
||||
</div>
|
||||
<div class="hovercard-stat">
|
||||
<span class="stat-value" x-text="$store.hovercard.data.reaction_score"></span>
|
||||
<span class="stat-label">Reactions</span>
|
||||
</div>
|
||||
<div class="hovercard-stat">
|
||||
<span class="stat-value" x-text="$store.hovercard.data.trophy_points"></span>
|
||||
<span class="stat-label">Points</span>
|
||||
</div>
|
||||
<div class="hovercard-stat">
|
||||
<span class="stat-value" x-text="$store.hovercard.data.entries_count"></span>
|
||||
<span class="stat-label">Entries</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hovercard-actions">
|
||||
<a href="#" class="btn" title="View profile">
|
||||
<i data-lucide="user" size="14"></i>
|
||||
</a>
|
||||
<a href="#" class="btn" title="Send message">
|
||||
<i data-lucide="mail" size="14"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -34,7 +34,9 @@
|
||||
{{ \Auth::user()?->username ?? "Guest" }}
|
||||
</span>
|
||||
<span class="user_role">
|
||||
Lorem
|
||||
<a href="{{ \Auth::guest() ? xfRoute('login') : xfRoute('logout') }}">
|
||||
{{ \Auth::guest() ? 'Login' : 'Logout' }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
68
resources/views/components/notifications.blade.php
Normal file
68
resources/views/components/notifications.blade.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<div
|
||||
x-data
|
||||
x-cloak
|
||||
x-show="$store.notifications.start"
|
||||
x-translation:enter="dropdown-enter"
|
||||
x-transition:leave="dropdown-leave"
|
||||
class="notifications"
|
||||
@click.outside="$store.notifications.close()"
|
||||
@keydown.escape.window="$store.notifications.close()"
|
||||
>
|
||||
<div class="notifications-header">
|
||||
<span class="notifications-header-title">Notifications</span>
|
||||
<div class="notifications-header-actions">
|
||||
<button type="button" class="btn" x-show="$store.notifications.unread > 0" @click="$store.notifications.markAllRead()" title="Mark all as read">
|
||||
<i data-lucide="check-circle" size="14"></i>
|
||||
</button>
|
||||
<a href="{{ xfRoute('account.alerts') }}" class="btn">
|
||||
<i data-lucide="external-link" size="14"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template x-if="$store.notifications.loading">
|
||||
<div class="notifications-loading">
|
||||
<i data-lucide="loader-2" class="spin"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template x-if="$store.notifications.error">
|
||||
<div class="notifications-empty">
|
||||
<i data-lucide="alert-circle" size="24"></i>
|
||||
<span>Failed to load notifications.</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template x-if="$store.notifications.data && !$store.notifications.loading">
|
||||
<div>
|
||||
|
||||
<template x-if="$store.notifications.data.length === 0">
|
||||
<div class="notifications-empty">
|
||||
<i data-lucide="bell-off" size="24"></i>
|
||||
<span>No new notifications.</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template x-for="notif in $store.notifications.data" :key="notif.alert_id">
|
||||
<a :href="notif.alert_url" class="notifications-item" :class="{ 'unread': notif.view_date === 0 }">
|
||||
<div class="notifications-avatar">
|
||||
<template x-if="notif.User?.avatar_urls?.s">
|
||||
<img :src="notif.User.avatar_urls.s" :alt="notif.username">
|
||||
</template>
|
||||
<template x-if="!notif.User?.avatar_urls?.s">
|
||||
<span x-text="notif.username?.charAt(0).toUpperCase()"></span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="notifications-content">
|
||||
<span class="notifications-text" x-text="notif.alert_text"></span>
|
||||
<span class="notifications-date" x-text="new Date(notif.event_date * 1000).toLocaleDateString()"></span>
|
||||
</div>
|
||||
|
||||
<div class="notifications-unread-dot" x-show="notif.view_date === 0"></div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -1,3 +1,4 @@
|
||||
@php $topbarModSeparator = false; $topBarAdminSeparator = false; @endphp
|
||||
<header id="topbar">
|
||||
<button class="mobile-toggle">
|
||||
<i data-lucide="menu"></i>
|
||||
@@ -9,8 +10,65 @@
|
||||
</div>
|
||||
|
||||
<div class="topbar-actions">
|
||||
|
||||
@if( !\Auth::guest() && \Auth::user()->is_admin === 1 )
|
||||
@php $topbarAdminSeparator = true; @endphp
|
||||
<a href="{{ config('app.forum_url') . '/admin.php' }}" class="btn">
|
||||
<i data-lucide="landmark" size="18"></i>
|
||||
</a>
|
||||
<a href="{{ config('app.url') . '/manage' }}" class="btn">
|
||||
<i data-lucide="shield-cog" size="18"></i>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if( $topbarAdminSeparator )
|
||||
<div class="vertical-separator"></div>
|
||||
@endif
|
||||
|
||||
@if( !\Auth::guest() && \Auth::user()->is_moderator === 1 )
|
||||
@php $topbarModSeparator = true; @endphp
|
||||
<a href="#" class="btn">
|
||||
<i data-lucide="siren" size="18"></i>
|
||||
</a>
|
||||
<a href="{{ xfRoute('approval-queue') }}" class="btn">
|
||||
<i data-lucide="message-circle-check" size="18"></i>
|
||||
</a>
|
||||
<a href="{{ xfRoute('reports') }}" class="btn">
|
||||
<i data-lucide="triangle-alert" size="18"></i>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if( $topbarModSeparator )
|
||||
<div class="vertical-separator"></div>
|
||||
@endif
|
||||
|
||||
{{-- Users --}}
|
||||
@if( !\Auth::guest() && \Auth::user()->can('romhackplaza', 'canSubmitEntry') )
|
||||
<a href="#" class="btn">
|
||||
<i data-lucide="hard-drive-upload" size="18"></i>
|
||||
</a>
|
||||
@endif
|
||||
@if( !\Auth::guest() )
|
||||
<div x-data x-init="$store.notifications.unviewed = {{ \Auth::user()->alerts_unviewed }}" style="position:relative">
|
||||
<button type="button" class="btn" :class="{ 'active': $store.notifications.start }" @click="$store.notifications.open($el)" @click.outside="$store.notifications.close()">
|
||||
<i data-lucide="bell" size="18"></i>
|
||||
<span
|
||||
class="topbar-badge"
|
||||
:class="$store.notifications.unread > 9 ? 'topbar-badge--overflow' : ''"
|
||||
x-show="$store.notifications.unread > 0"
|
||||
x-text="$store.notifications.unread > 99 ? '99+' : $store.notifications.unread"
|
||||
></span>
|
||||
</button>
|
||||
|
||||
@include('components.notifications')
|
||||
</div>
|
||||
<button class="btn">
|
||||
<i data-lucide="mail" size="18"></i>
|
||||
</button>
|
||||
@endif
|
||||
<button class="btn">
|
||||
<i data-lucide="bell" size="18"></i>
|
||||
<i data-lucide="settings" size="18"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
6
resources/views/components/xf-username-link.blade.php
Normal file
6
resources/views/components/xf-username-link.blade.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<span x-data class="userlink"
|
||||
@mouseenter.debounce.300ms="$store.hovercard.open($el,'{{ route('dynamic.hovercard', ['user_id' => $user?->user_id ?? 0 ]) }}')"
|
||||
@mouseleave="setTimeout(() => { const C = document.querySelector('.hovercard'); if(!C?.matches(':hover')) $store.hovercard.close(); }, 200)"
|
||||
>
|
||||
{{ $user->username }}
|
||||
</span>
|
||||
@@ -1,11 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>RomHack Plaza</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Bienvenue sur RomHack Plaza</h1>
|
||||
<p>Le catalogue est en construction.</p>
|
||||
</body>
|
||||
</html>
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('page-title', "Database - " . config('app.name') )
|
||||
|
||||
@section('content')
|
||||
@livewire('database')
|
||||
@endsection
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
</div>
|
||||
<x-error-block error-type="page-not-allowed" />
|
||||
|
||||
{{ xfRoute( 'profile-posts.comments', ['profile_post_comment_id' => 1] ) }}
|
||||
<x-xf-username-link user-id="2" />
|
||||
@endsection
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
</main>
|
||||
|
||||
</div>
|
||||
@include('components.hovercard')
|
||||
@livewireScripts
|
||||
@stack('scripts')
|
||||
</body>
|
||||
|
||||
79
resources/views/livewire/database.blade.php
Normal file
79
resources/views/livewire/database.blade.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<div @filters-updated.window="refreshIcons($el)">
|
||||
<div class="database-search filter-bar">
|
||||
<input
|
||||
type="text"
|
||||
wire:model.live.debounce="search"
|
||||
placeholder="Search..."
|
||||
class="form-input filter-bar-search"
|
||||
>
|
||||
@if( $search || $types || $platforms || $games || $statuses || $authors || $languages || $modifications )
|
||||
<button type="button" wire:click="clearFilters" class="btn">
|
||||
<i data-lucide="x"></i> Clear filters
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="database-wrapper">
|
||||
<aside class="database-filters">
|
||||
|
||||
{{-- Types --}}
|
||||
<div class="filter-group" x-data="{open: true}">
|
||||
<div class="filter-title-row" @click="open = !open">
|
||||
<h4 class="filter-title">Type</h4>
|
||||
<i data-lucide="chevron-down" size="14" class="filter-chevron" :class="{ 'rotated': !open }"></i>
|
||||
</div>
|
||||
<div class="filter-options" x-show="open" x-transition>
|
||||
@foreach( \App\Livewire\Database::ENTRY_TYPES as $k => $v )
|
||||
<label class="filter-option">
|
||||
<input type="checkbox" wire:model.live="types" value="{{ $k }}">
|
||||
{{ $v }}
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Games --}}
|
||||
<x-database-filter-without-mode-search title="Game" :items="$allGames" model="games" />
|
||||
|
||||
{{-- Platforms --}}
|
||||
<x-database-filter-without-mode title="Platform" :items="$allPlatforms" model="platforms"/>
|
||||
|
||||
{{-- Statuses --}}
|
||||
<x-database-filter-without-mode title="Status" :items="$allStatuses" model="statuses"/>
|
||||
|
||||
{{-- Authors --}}
|
||||
<x-database-filter-with-mode-search title="Authors" :items="$allAuthors" model="authors" mode-model="authorsMode" :selected-mode="$authorsMode" />
|
||||
|
||||
{{-- Languages --}}
|
||||
<x-database-filter-with-mode title="Languages" :items="$allLanguages" model="languages" mode-model="languagesMode" :selected-mode="$languagesMode" />
|
||||
|
||||
{{-- Modifications --}}
|
||||
<x-database-filter-with-mode title="Modifications" :items="$allModifications" model="modifications" mode-model="modificationsMode" :selected-mode="$modificationsMode" />
|
||||
|
||||
</aside>
|
||||
|
||||
<div class="database-results">
|
||||
<div class="database-sort">
|
||||
@foreach( \App\Livewire\Database::SORT_OPTIONS as $k => $v )
|
||||
<button type="button" wire:click="setSort('{{ $k }}')" class="btn {{ $sortBy === $k ? 'active' : '' }}">
|
||||
{{ $v }}
|
||||
</button>
|
||||
@if( $sortBy === $k )
|
||||
<i data-lucide="{{ $sortDir === 'asc' ? 'arrow-up' : 'arrow-down' }}"></i>
|
||||
@endif
|
||||
@endforeach
|
||||
<span class="database-results-count">{{ $entries->total() }} results</span>
|
||||
</div>
|
||||
|
||||
<div class="grid-entries">
|
||||
@forelse($entries as $entry)
|
||||
<x-entry-card :entry="$entry" />
|
||||
@empty
|
||||
<p>No entries found.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
{{ $entries->links() }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
102
resources/views/vendor/livewire/bootstrap.blade.php
vendored
Normal file
102
resources/views/vendor/livewire/bootstrap.blade.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
@php
|
||||
if (! isset($scrollTo)) {
|
||||
$scrollTo = 'body';
|
||||
}
|
||||
|
||||
$scrollIntoViewJsSnippet = ($scrollTo !== false)
|
||||
? <<<JS
|
||||
(\$el.closest('{$scrollTo}') || document.querySelector('{$scrollTo}')).scrollIntoView()
|
||||
JS
|
||||
: '';
|
||||
@endphp
|
||||
|
||||
<div>
|
||||
@if ($paginator->hasPages())
|
||||
<nav class="d-flex justify-items-center justify-content-between">
|
||||
<div class="d-flex justify-content-between flex-fill d-sm-none">
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.previous')</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<button type="button" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled">@lang('pagination.previous')</button>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<button type="button" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled">@lang('pagination.next')</button>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link" aria-hidden="true">@lang('pagination.next')</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="d-none flex-sm-fill d-sm-flex align-items-sm-center justify-content-sm-between">
|
||||
<div>
|
||||
<p class="small text-muted">
|
||||
{!! __('Showing') !!}
|
||||
<span class="fw-semibold">{{ $paginator->firstItem() }}</span>
|
||||
{!! __('to') !!}
|
||||
<span class="fw-semibold">{{ $paginator->lastItem() }}</span>
|
||||
{!! __('of') !!}
|
||||
<span class="fw-semibold">{{ $paginator->total() }}</span>
|
||||
{!! __('results') !!}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<button type="button" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" aria-label="@lang('pagination.previous')">‹</button>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="page-item active" wire:key="paginator-{{ $paginator->getPageName() }}-page-{{ $page }}" aria-current="page"><span class="page-link">{{ $page }}</span></li>
|
||||
@else
|
||||
<li class="page-item" wire:key="paginator-{{ $paginator->getPageName() }}-page-{{ $page }}"><button type="button" class="page-link" wire:click="gotoPage({{ $page }}, '{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}">{{ $page }}</button></li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<button type="button" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" aria-label="@lang('pagination.next')">›</button>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@endif
|
||||
</div>
|
||||
53
resources/views/vendor/livewire/simple-bootstrap.blade.php
vendored
Normal file
53
resources/views/vendor/livewire/simple-bootstrap.blade.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
@php
|
||||
if (! isset($scrollTo)) {
|
||||
$scrollTo = 'body';
|
||||
}
|
||||
|
||||
$scrollIntoViewJsSnippet = ($scrollTo !== false)
|
||||
? <<<JS
|
||||
(\$el.closest('{$scrollTo}') || document.querySelector('{$scrollTo}')).scrollIntoView()
|
||||
JS
|
||||
: '';
|
||||
@endphp
|
||||
|
||||
<div>
|
||||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.previous')</span>
|
||||
</li>
|
||||
@else
|
||||
@if(method_exists($paginator,'getCursorName'))
|
||||
<li class="page-item">
|
||||
<button dusk="previousPage" type="button" class="page-link" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $paginator->previousCursor()->encode() }}" wire:click="setPage('{{$paginator->previousCursor()->encode()}}','{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled">@lang('pagination.previous')</button>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<button type="button" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled">@lang('pagination.previous')</button>
|
||||
</li>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
@if(method_exists($paginator,'getCursorName'))
|
||||
<li class="page-item">
|
||||
<button dusk="nextPage" type="button" class="page-link" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $paginator->nextCursor()->encode() }}" wire:click="setPage('{{$paginator->nextCursor()->encode()}}','{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled">@lang('pagination.next')</button>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<button type="button" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled">@lang('pagination.next')</button>
|
||||
</li>
|
||||
@endif
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.next')</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
</div>
|
||||
56
resources/views/vendor/livewire/simple-tailwind.blade.php
vendored
Normal file
56
resources/views/vendor/livewire/simple-tailwind.blade.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
@php
|
||||
if (! isset($scrollTo)) {
|
||||
$scrollTo = 'body';
|
||||
}
|
||||
|
||||
$scrollIntoViewJsSnippet = ($scrollTo !== false)
|
||||
? <<<JS
|
||||
(\$el.closest('{$scrollTo}') || document.querySelector('{$scrollTo}')).scrollIntoView()
|
||||
JS
|
||||
: '';
|
||||
@endphp
|
||||
|
||||
<div>
|
||||
@if ($paginator->hasPages())
|
||||
<nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
|
||||
<span>
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md dark:text-gray-600 dark:bg-gray-800 dark:border-gray-600">
|
||||
{!! __('pagination.previous') !!}
|
||||
</span>
|
||||
@else
|
||||
@if(method_exists($paginator,'getCursorName'))
|
||||
<button type="button" dusk="previousPage" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $paginator->previousCursor()->encode() }}" wire:click="setPage('{{$paginator->previousCursor()->encode()}}','{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-blue-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.previous') !!}
|
||||
</button>
|
||||
@else
|
||||
<button
|
||||
type="button" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-blue-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.previous') !!}
|
||||
</button>
|
||||
@endif
|
||||
@endif
|
||||
</span>
|
||||
|
||||
<span>
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
@if(method_exists($paginator,'getCursorName'))
|
||||
<button type="button" dusk="nextPage" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $paginator->nextCursor()->encode() }}" wire:click="setPage('{{$paginator->nextCursor()->encode()}}','{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-blue-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.next') !!}
|
||||
</button>
|
||||
@else
|
||||
<button type="button" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-blue-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.next') !!}
|
||||
</button>
|
||||
@endif
|
||||
@else
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md dark:text-gray-600 dark:bg-gray-800 dark:border-gray-600">
|
||||
{!! __('pagination.next') !!}
|
||||
</span>
|
||||
@endif
|
||||
</span>
|
||||
</nav>
|
||||
@endif
|
||||
</div>
|
||||
35
resources/views/vendor/livewire/tailwind.blade.php
vendored
Normal file
35
resources/views/vendor/livewire/tailwind.blade.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
@if ($paginator->hasPages())
|
||||
<div class="database-pagination">
|
||||
|
||||
{{-- Précédent --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<button class="btn" disabled>«</button>
|
||||
@else
|
||||
<button class="btn" wire:click="previousPage">«</button>
|
||||
@endif
|
||||
|
||||
{{-- Pages --}}
|
||||
@foreach ($elements as $element)
|
||||
@if (is_string($element))
|
||||
<button class="btn" disabled>{{ $element }}</button>
|
||||
@endif
|
||||
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
<button
|
||||
class="btn {{ $page == $paginator->currentPage() ? 'active' : '' }}"
|
||||
wire:click="gotoPage({{ $page }})"
|
||||
>{{ $page }}</button>
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Suivant --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<button class="btn" wire:click="nextPage">»</button>
|
||||
@else
|
||||
<button class="btn" disabled>»</button>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
@endif
|
||||
Reference in New Issue
Block a user