forge/resources/views/mod/show.blade.php
Refringe 593b44150c
Resolves Mod Detail Page Version Issue
The latest version on the mod detail page was being selected by created date instead of highest version number. This has been resolved. Also adds a test for this issue.
2024-08-09 12:35:46 -04:00

220 lines
15 KiB
PHP

<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
{{ __('Mod Details') }}
</h2>
</x-slot>
<div class="grid grid-cols-1 lg:grid-cols-3 max-w-7xl mx-auto py-6 px-4 gap-6 sm:px-6 lg:px-8">
<div class="lg:col-span-2 flex flex-col gap-6">
{{-- Main Mod Details Card --}}
<div class="p-4 sm:p-6 text-center sm:text-left bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 drop-shadow-2xl">
<div class="flex flex-col sm:flex-row gap-4 sm:gap-6">
<div class="grow-0 shrink-0 flex justify-center items-center">
@if (empty($mod->thumbnail))
<img src="https://placehold.co/144x144/EEE/31343C?font=source-sans-pro&text={{ $mod->name }}" alt="{{ $mod->name }}" class="block dark:hidden w-36 rounded-lg">
<img src="https://placehold.co/144x144/31343C/EEE?font=source-sans-pro&text={{ $mod->name }}" alt="{{ $mod->name }}" class="hidden dark:block w-36 rounded-lg">
@else
<img src="{{ $mod->thumbnailUrl }}" alt="{{ $mod->name }}" class="w-36 rounded-lg">
@endif
</div>
<div class="grow flex flex-col justify-center items-center sm:items-start text-gray-800 dark:text-gray-200">
<div class="flex justify-between items-center space-x-3">
<h2 class="pb-1 sm:pb-2 text-3xl font-bold text-gray-900 dark:text-white">
{{ $mod->name }}
<span class="font-light text-nowrap text-gray-700 dark:text-gray-400">
{{ $latestVersion->version }}
</span>
</h2>
</div>
<p>
{{ __('Created by') }}
@foreach ($mod->users as $user)
<a href="{{ $user->profileUrl() }}" class="text-slate-600 dark:text-gray-200 hover:underline">{{ $user->name }}</a>{{ $loop->last ? '' : ',' }}
@endforeach
</p>
<p title="{{ __('Exactly') }} {{ $mod->total_downloads }}">{{ Number::downloads($mod->total_downloads) }} {{ __('Downloads') }}</p>
<p class="mt-2">
<span class="badge-version {{ $latestVersion->sptVersion->color_class }} inline-flex items-center rounded-md px-2 py-1 text-xs font-medium text-nowrap">
{{ $latestVersion->sptVersion->version }} {{ __('Compatible') }}
</span>
</p>
</div>
</div>
</div>
{{-- Tabs --}}
<div x-data="{ selectedTab: window.location.hash ? window.location.hash.substring(1) : 'description' }" x-init="$watch('selectedTab', (tab) => {window.location.hash = tab})" class="lg:col-span-2 flex flex-col gap-6">
<div>
{{-- Mobile Download Button --}}
<a href="{{ $latestVersion->link }}" class="block lg:hidden mb-6">
<button class="text-lg font-extrabold hover:bg-cyan-400 dark:hover:bg-cyan-600 shadow-md dark:shadow-gray-950 drop-shadow-2xl bg-cyan-500 dark:bg-cyan-700 rounded-xl w-full h-20">{{ __('Download Latest Version') }} ({{ $latestVersion->version }})</button>
</a>
{{-- Mobile Dropdown --}}
<div class="sm:hidden">
<label for="tabs" class="sr-only">{{ __('Select a tab') }}</label>
<select id="tabs" name="tabs" x-model="selectedTab" class="block w-full rounded-md dark:text-white bg-gray-100 dark:bg-gray-950 border-gray-300 dark:border-gray-700 focus:border-grey-500 dark:focus:border-grey-600 focus:ring-grey-500 dark:focus:ring-grey-600">
<option value="description">{{ __('Description') }}</option>
<option value="versions">{{ __('Versions') }}</option>
<option value="comments">{{ __('Comments') }}</option>
</select>
</div>
{{-- Desktop Tabs --}}
<div class="hidden sm:block">
<nav class="isolate flex divide-x divide-gray-200 dark:divide-gray-800 rounded-xl shadow-md dark:shadow-gray-950 drop-shadow-2xl" aria-label="Tabs">
<button @click="selectedTab = 'description'" class="tab rounded-l-xl group relative min-w-0 flex-1 overflow-hidden py-4 px-4 text-center text-sm font-medium text-gray-900 dark:text-white bg-white dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-black dark:hover:text-white focus:z-10" aria-current="page">
<span>{{ __('Description') }}</span>
<span aria-hidden="true" :class="selectedTab === 'description' ? 'bg-gray-500 absolute inset-x-0 bottom-0 h-0.5' : 'bottom-0 h-0.5'"></span>
</button>
<button @click="selectedTab = 'versions'" class="tab group relative min-w-0 flex-1 overflow-hidden py-4 px-4 text-center text-sm font-medium text-gray-900 dark:text-white bg-white dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-black dark:hover:text-white focus:z-10">
<span>{{ __('Versions') }}</span>
<span aria-hidden="true" :class="selectedTab === 'versions' ? 'bg-gray-500 absolute inset-x-0 bottom-0 h-0.5' : 'bottom-0 h-0.5'"></span>
</button>
<button @click="selectedTab = 'comments'" class="tab rounded-r-xl group relative min-w-0 flex-1 overflow-hidden py-4 px-4 text-center text-sm font-medium text-gray-900 dark:text-white bg-white dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-black dark:hover:text-white focus:z-10">
<span>{{ __('Comments') }}</span>
<span aria-hidden="true" :class="selectedTab === 'comments' ? 'bg-gray-500 absolute inset-x-0 bottom-0 h-0.5' : 'bottom-0 h-0.5'"></span>
</button>
</nav>
</div>
</div>
{{-- Mod Description --}}
<div x-show="selectedTab === 'description'" class="user-markdown p-4 sm:p-6 bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 drop-shadow-2xl">
{{-- The description below is safe to write directly because it has been run though HTMLPurifier during the import process. --}}
{!! Str::markdown($mod->description) !!}
</div>
{{-- Mod Versions --}}
<div x-show="selectedTab === 'versions'">
@foreach ($mod->versions as $version)
<div class="p-4 mb-4 sm:p-6 bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 drop-shadow-2xl">
<div class="pb-6 border-b-2 border-gray-200 dark:border-gray-800">
<div class="flex items-center justify-between">
<a class="text-2xl font-extrabold" href="{{ $version->link }}">
{{ __('Version') }} {{ $version->version }}
</a>
<p class="text-gray-700 dark:text-gray-300" title="{{ __('Exactly') }} {{ $version->downloads }}">{{ Number::downloads($version->downloads) }} {{ __('Downloads') }}</p>
</div>
<div class="flex items-center justify-between">
<span class="badge-version {{ $version->sptVersion->color_class }} inline-flex items-center rounded-md px-2 py-1 text-xs font-medium text-nowrap">
{{ $version->sptVersion->version }}
</span>
<a href="{{ $version->virus_total_link }}">{{__('Virus Total Results')}}</a>
</div>
<div class="flex items-center justify-between text-gray-600 dark:text-gray-400">
<span>{{ __('Created') }} {{ $version->created_at->format("M d, h:m a") }}</span>
<span>{{ __('Updated') }} {{ $version->updated_at->format("M d, h:m a") }}</span>
</div>
@if ($version->dependencies->isNotEmpty() && $version->dependencies->contains(fn($dependency) => $dependency->resolvedVersion?->mod))
<div class="text-gray-600 dark:text-gray-400">
{{ __('Dependencies:') }}
@foreach ($version->dependencies as $dependency)
@if ($dependency->resolvedVersion?->mod)
<a href="{{ $dependency->resolvedVersion->mod->detailUrl() }}">
{{ $dependency->resolvedVersion->mod->name }}&nbsp;({{ $dependency->resolvedVersion->version }})
</a>@if (!$loop->last), @endif
@endif
@endforeach
</div>
@endif
</div>
<div class="p-3 user-markdown">
{{-- The description below is safe to write directly because it has been run though HTMLPurifier during the import process. --}}
{!! Str::markdown($version->description) !!}
</div>
</div>
@endforeach
</div>
{{-- Comments --}}
<div x-show="selectedTab === 'comments'" class="user-markdown p-4 sm:p-6 bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 drop-shadow-2xl">
<p>{{ __('The comments go here.') }}</p>
</div>
</div>
</div>
{{-- Right Column --}}
<div class="col-span-1 flex flex-col gap-6">
{{-- Desktop Download Button --}}
<a href="{{ $latestVersion->link }}" class="hidden lg:block">
<button class="text-lg font-extrabold hover:bg-cyan-400 dark:hover:bg-cyan-600 shadow-md dark:shadow-gray-950 drop-shadow-2xl bg-cyan-500 dark:bg-cyan-700 rounded-xl w-full h-20">{{ __('Download Latest Version') }} ({{ $latestVersion->version }})</button>
</a>
{{-- Additional Mod Details --}}
<div class="p-4 sm:p-6 bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 drop-shadow-2xl">
<h2 class="text-2xl font-bold text-gray-900 dark:text-gray-100">{{ __('Details') }}</h2>
<ul role="list" class="divide-y divide-gray-200 dark:divide-gray-800 text-gray-900 dark:text-gray-100">
@if ($mod->license)
<li class="px-4 py-4 sm:px-0">
<h3>{{ __('License') }}</h3>
<p class="truncate">
<a href="{{ $mod->license->link }}" title="{{ $mod->license->name }}" target="_blank">
{{ $mod->license->name }}
</a>
</p>
</li>
@endif
@if ($mod->source_code_link)
<li class="px-4 py-4 sm:px-0">
<h3>{{ __('Source Code') }}</h3>
<p class="truncate">
<a href="{{ $mod->source_code_link }}" title="{{ $mod->source_code_link }}" target="_blank">
{{ $mod->source_code_link }}
</a>
</p>
</li>
@endif
@if ($latestVersion->virus_total_link)
<li class="px-4 py-4 sm:px-0">
<h3>{{ __('Latest Version VirusTotal Result') }}</h3>
<p class="truncate">
<a href="{{ $latestVersion->virus_total_link }}" title="{{ $latestVersion->virus_total_link }}" target="_blank">
{{ $latestVersion->virus_total_link }}
</a>
</p>
</li>
@endif
@if ($latestVersion->dependencies->isNotEmpty() && $latestVersion->dependencies->contains(fn($dependency) => $dependency->resolvedVersion?->mod))
<li class="px-4 py-4 sm:px-0">
<h3>{{ __('Latest Version Dependencies') }}</h3>
<p class="truncate">
@foreach ($latestVersion->dependencies as $dependency)
<a href="{{ $dependency->resolvedVersion->mod->detailUrl() }}">
{{ $dependency->resolvedVersion->mod->name }}&nbsp;({{ $dependency->resolvedVersion->version }})
</a><br />
@endforeach
</p>
</li>
@endif
@if ($mod->contains_ads)
<li class="px-4 py-4 sm:px-0 flex flex-row gap-2 items-center">
<svg class="grow-0 w-[16px] h-[16px]" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor">
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.15-.043l4.25-5.5Z" clip-rule="evenodd"/>
</svg>
<h3 class="grow">
{{ __('Includes Advertising') }}
</h3>
</li>
@endif
@if ($mod->contains_ai_content)
<li class="px-4 py-4 sm:px-0 flex flex-row gap-2 items-center">
<svg class="grow-0 w-[16px] h-[16px]" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor">
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.15-.043l4.25-5.5Z" clip-rule="evenodd"/>
</svg>
<h3 class="grow">
{{ __('Includes AI Generated Content') }}
</h3>
</li>
@endif
</ul>
</div>
</div>
</div>
</x-app-layout>