2026-06-02 20:54:10 +02:00
|
|
|
<?php /** @var \App\Models\EntryGallery $galleryItem */ ?>
|
2026-05-20 18:25:15 +02:00
|
|
|
@extends('layouts.app')
|
|
|
|
|
|
|
|
|
|
@section('page-title', $entry->title . " - " . config('app.name') )
|
|
|
|
|
|
|
|
|
|
@section('content')
|
|
|
|
|
{{ \Diglactic\Breadcrumbs\Breadcrumbs::render() }}
|
|
|
|
|
<article id="entry-container">
|
|
|
|
|
<div class="entry-header">
|
|
|
|
|
<div class="entry-cover">
|
|
|
|
|
@if( $entry->main_image )
|
|
|
|
|
<img src="{{ Storage::url($entry->main_image) }}">
|
|
|
|
|
@else
|
|
|
|
|
<div class="entry-cover-placeholder">
|
|
|
|
|
<i data-lucide="image" size="48"></i>
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="entry-info">
|
|
|
|
|
<h1 class="entry-title">
|
|
|
|
|
{{ $entry->title }}
|
2026-06-02 20:54:10 +02:00
|
|
|
@if( $entry->state === 'pending' )
|
|
|
|
|
<div style="display:inline;color:var(--rhpz-orange);">
|
|
|
|
|
-
|
|
|
|
|
<i data-lucide="clock" size="24"></i>
|
|
|
|
|
Pending approval
|
|
|
|
|
</div>
|
|
|
|
|
@elseif( $entry->state === 'rejected' )
|
|
|
|
|
<div style="display:inline;color:var(--error);">
|
|
|
|
|
-
|
|
|
|
|
<i data-lucide="x-circle" size="24"></i>
|
|
|
|
|
Rejected
|
|
|
|
|
</div>
|
|
|
|
|
@elseif( $entry->state === 'locked' )
|
|
|
|
|
<div style="display:inline;color:var(--error);">
|
|
|
|
|
-
|
|
|
|
|
<i data-lucide="lock" size="24"></i>
|
|
|
|
|
Locked
|
|
|
|
|
</div>
|
|
|
|
|
@elseif( $entry->state === 'draft' )
|
|
|
|
|
<div style="display:inline;color:var(--rhpz-orange);">
|
|
|
|
|
-
|
|
|
|
|
<i data-lucide="scissors" size="24"></i>
|
|
|
|
|
Draft
|
|
|
|
|
</div>
|
|
|
|
|
@elseif( $entry->state === 'hidden' )
|
|
|
|
|
<div style="display:inline;color:var(--rhpz-orange);">
|
|
|
|
|
-
|
|
|
|
|
<i data-lucide="hide" size="24"></i>
|
|
|
|
|
Hidden
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
2026-05-20 18:25:15 +02:00
|
|
|
</h1>
|
|
|
|
|
<div class="entry-authors">
|
|
|
|
|
@forelse( $entry->authors as $author)
|
|
|
|
|
@if($loop->first)By @endif
|
|
|
|
|
{{ $author->name }}
|
|
|
|
|
@if( !$loop->last ), @endif
|
|
|
|
|
@empty
|
|
|
|
|
No authors
|
|
|
|
|
@endforelse
|
|
|
|
|
</div>
|
2026-06-02 20:54:10 +02:00
|
|
|
<div class="entry-submission-byline">
|
|
|
|
|
@if($entry->user_id)
|
|
|
|
|
<span>
|
|
|
|
|
<i data-lucide="user" size="14"></i>
|
|
|
|
|
Posted by <x-xf-username-link :user-id="$entry->user_id" />
|
|
|
|
|
</span>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
<span>
|
|
|
|
|
<i data-lucide="calendar" size="14"></i>
|
|
|
|
|
{{ $entry->created_at->format('M d, Y') }}
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
|
|
@if($entry->updated_at && $entry->updated_at->gt($entry->created_at))
|
|
|
|
|
<span>
|
|
|
|
|
<i data-lucide="file-edit" size="14"></i>
|
|
|
|
|
Updated {{ $entry->updated_at->diffForHumans() }}
|
|
|
|
|
</span>
|
|
|
|
|
@endif
|
|
|
|
|
</div>
|
2026-05-20 18:25:15 +02:00
|
|
|
<div class="entry-meta-grid">
|
|
|
|
|
@if( $entry->game )
|
|
|
|
|
<x-entry-meta-item label="Game Name" value="{{ $entry->game->name }}" />
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->getRealPlatform() )
|
|
|
|
|
<x-entry-meta-item label="Platform" value="{{ ($entry->getRealPlatform())->name }}" />
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->game && $entry->game->genre )
|
|
|
|
|
<x-entry-meta-item label="Genre" value="{{ $entry->game->genre->name }}" />
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->languages->isNotEmpty() )
|
|
|
|
|
<x-entry-meta-item label="Language" value="{{ $entry->languages->pluck('name')->implode(', ') }}" route="none" />
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->status_id )
|
|
|
|
|
<x-entry-meta-item label="Status" value="{{ $entry->status->name }}" />
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->version )
|
|
|
|
|
<x-entry-meta-item label="Version" value="{{ $entry->version }}" route="none" />
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->release_date )
|
|
|
|
|
<x-entry-meta-item label="Release Date" value="{{ $entry->release_date }}" />
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->modifications->isNotEmpty() )
|
|
|
|
|
<x-entry-meta-item label="Type of hack" value="{{ $entry->modifications->pluck('name')->implode(', ') }}" route="none" />
|
|
|
|
|
@endif
|
|
|
|
|
</div>
|
2026-06-02 20:54:10 +02:00
|
|
|
<div class="hack-actions" style="display:flex;gap:10px;">
|
|
|
|
|
@if($entry->state === 'pending')
|
|
|
|
|
@can('approve', $entry)
|
|
|
|
|
<div x-data="{ rejectOpen: false }">
|
|
|
|
|
<form action="{{ route('queue.approve', $entry) }}" method="POST" style="display:inline">
|
|
|
|
|
@csrf
|
|
|
|
|
@method('PATCH')
|
|
|
|
|
<button type="submit" class="btn success" onclick="return confirm('Approve this entry?')">
|
|
|
|
|
<i data-lucide="check-circle" size="14"></i>
|
|
|
|
|
Approve
|
|
|
|
|
</button>
|
|
|
|
|
</form>
|
|
|
|
|
<button type="button" class="btn danger" style="margin-right:15px;" @click="rejectOpen = !rejectOpen">
|
|
|
|
|
<i data-lucide="x-circle" size="14"></i>
|
|
|
|
|
Reject
|
|
|
|
|
</button>
|
|
|
|
|
<div
|
|
|
|
|
class="modal-overlay"
|
|
|
|
|
x-cloak
|
|
|
|
|
x-show="rejectOpen"
|
|
|
|
|
x-transition.opacity
|
|
|
|
|
@click.self="rejectOpen = false"
|
|
|
|
|
@keydown.escape.window="rejectOpen = false"
|
|
|
|
|
@modal:opened.window="refreshIcons($el)"
|
|
|
|
|
>
|
|
|
|
|
<div class="modal-window" x-show="rejectOpen" x-transition>
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<span class="modal-title">Reject entry</span>
|
|
|
|
|
<button type="button" class="modal-close" @click="rejectOpen = false">
|
|
|
|
|
<i data-lucide="x" size="20"></i>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<form action="{{ route('queue.reject', $entry) }}" method="POST">
|
|
|
|
|
@csrf
|
|
|
|
|
@method('PATCH')
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<x-form-field-title name="Rejection reason" required="true" />
|
|
|
|
|
<textarea
|
|
|
|
|
class="form-input"
|
|
|
|
|
name="reason"
|
|
|
|
|
rows="4"
|
|
|
|
|
placeholder="Explain why this entry is being rejected..."
|
|
|
|
|
required
|
|
|
|
|
></textarea>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="queue-mod-actions">
|
|
|
|
|
<button type="button" class="btn" @click="rejectOpen = false">
|
|
|
|
|
Cancel
|
|
|
|
|
</button>
|
|
|
|
|
<button type="submit" class="btn danger">
|
|
|
|
|
<i data-lucide="x-circle" size="14"></i>
|
|
|
|
|
Confirm rejection
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@endcan
|
|
|
|
|
@endif
|
2026-05-21 13:20:16 +02:00
|
|
|
<button class="btn primary" onclick="Livewire.dispatch('entryOpenFilesModal', { entryId: {{ $entry->id }} })">
|
2026-05-20 18:25:15 +02:00
|
|
|
<i data-lucide="download"></i> Download
|
|
|
|
|
</button>
|
2026-05-27 21:24:38 +02:00
|
|
|
@can('update',$entry)
|
2026-06-02 20:54:10 +02:00
|
|
|
<a href="{{ route('submit.edit', ['section' => $entry->type, 'entry' => $entry ] ) }}" class="btn">
|
2026-05-27 21:24:38 +02:00
|
|
|
<i data-lucide="edit"></i> Edit
|
|
|
|
|
</a>
|
|
|
|
|
@endcan
|
|
|
|
|
@auth
|
|
|
|
|
<a href="{{ xfRoute("romhackplaza_entry/{$entry->id}/report") }}" class="btn">
|
|
|
|
|
<i data-lucide="flag"></i> Report / Claim Ownership
|
|
|
|
|
</a>
|
|
|
|
|
@endauth
|
2026-05-20 18:25:15 +02:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="entry-content">
|
|
|
|
|
@if( $entry->description )
|
|
|
|
|
<x-entry-section-title label="Description" icon="file-text" />
|
|
|
|
|
<div class="entry-description">
|
|
|
|
|
{{ $entry->description }}
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->hashes->isNotEmpty() )
|
|
|
|
|
<x-entry-section-title label="Hashes" icon="table-properties" />
|
|
|
|
|
<div class="entry-description">
|
|
|
|
|
@foreach( $entry->hashes->all() as $hash )
|
|
|
|
|
Filename: {{ $hash->filename }}<br>
|
|
|
|
|
CRC32: {{ $hash->hash_crc32 }}<br>
|
|
|
|
|
SHA-1: {{ $hash->hash_sha1 }}<br>
|
|
|
|
|
Verified: {{ $hash->verified }}<br>
|
|
|
|
|
@endforeach
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->staff_credits )
|
2026-06-02 20:54:10 +02:00
|
|
|
<x-entry-section-title label="Staff Credits" icon="users-round" />
|
|
|
|
|
<div class="entry-description">
|
|
|
|
|
<ul>
|
|
|
|
|
@foreach( $entry->parseStaffCredits() as $item )
|
|
|
|
|
<li>{{ $item['name'] }}: {{ $item['description'] }}</li>
|
|
|
|
|
@endforeach
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->gallery->isNotEmpty() )
|
|
|
|
|
<div x-data="{ open: false, currentImage: ''}" x-cloak>
|
|
|
|
|
<x-entry-section-title label="Gallery" icon="images" />
|
|
|
|
|
<div class="entry-gallery">
|
|
|
|
|
@foreach( $entry->gallery as $galleryItem )
|
|
|
|
|
<div class="entry-gallery-item" @click="currentImage = '{{ Storage::url($galleryItem->image) }}'; open = true; "><img src="{{ Storage::url($galleryItem->image) }}"></div>
|
|
|
|
|
@endforeach
|
|
|
|
|
</div>
|
|
|
|
|
<div class="gallery-modal" x-show="open" x-transition.opacity.duration.300ms @click="open = false" @keydown.escape.window="open = false">
|
|
|
|
|
<span class="gallery-modal-close" @click="open = false;"><i data-lucide="x"></i></span>
|
|
|
|
|
<div class="gallery-modal-content" @click.stop>
|
|
|
|
|
<img :src="currentImage">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->relevant_link )
|
|
|
|
|
<x-entry-section-title label="Relevant Link" icon="link" />
|
2026-05-20 18:25:15 +02:00
|
|
|
<div class="entry-description">
|
2026-06-02 20:54:10 +02:00
|
|
|
<a href="{{ $entry->relevant_link }}" target="_blank">{{ $entry->relevant_link }}</a>
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
@if( $entry->getYoutubeVideoId() )
|
|
|
|
|
<div x-data="{open: false, src: ''}" x-cloak class="youtube-section">
|
|
|
|
|
|
|
|
|
|
<x-entry-section-title label="Youtube Video" icon="play" />
|
|
|
|
|
|
|
|
|
|
<div class="video-thumbnail-wrapper" @click="src = 'https://www.youtube.com/embed/{{ $entry->getYoutubeVideoId() }}?autoplay=1'; open = true">
|
|
|
|
|
<img src="https://img.youtube.com/vi/{{ $entry->youtube_id }}/maxresdefault.jpg">
|
|
|
|
|
<div class="play-trigger">
|
|
|
|
|
<i data-lucide="play"></i>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="gallery-modal" x-show="open" x-transition.opacity.duration.300ms @click="open = false; src = ''" @keydown.escape.window="open = false; src = ''">
|
|
|
|
|
<span class="gallery-modal-close" @click="open = false; src = '';"><i data-lucide="x"></i></span>
|
|
|
|
|
<div class="gallery-modal-video" @click.stop>
|
|
|
|
|
<iframe :src="src" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-20 18:25:15 +02:00
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
</div>
|
|
|
|
|
</article>
|
2026-05-27 21:24:38 +02:00
|
|
|
@include('entries.comments')
|
2026-05-21 13:20:16 +02:00
|
|
|
@livewire('entry-files-modal')
|
2026-05-20 18:25:15 +02:00
|
|
|
@endsection
|