dark/light mode
This commit is contained in:
+149
-46
@@ -3,16 +3,52 @@
|
|||||||
:root {
|
:root {
|
||||||
--primary: #7F00FF;
|
--primary: #7F00FF;
|
||||||
--accent: #00C9FF;
|
--accent: #00C9FF;
|
||||||
--background: #121212;
|
|
||||||
--text: #EAEAEA;
|
|
||||||
--gradient-start: #4f46e5;
|
--gradient-start: #4f46e5;
|
||||||
--gradient-end: #7c3aed;
|
--gradient-end: #7c3aed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dark Theme (Default) */
|
||||||
|
[data-theme="dark"] {
|
||||||
|
--background: #0f172a;
|
||||||
|
--background-alt: #1e293b;
|
||||||
|
--background-elevated: rgba(30, 30, 30, 0.8);
|
||||||
|
--text: #e2e8f0;
|
||||||
|
--text-muted: #94a3b8;
|
||||||
|
--border-color: rgba(255, 255, 255, 0.1);
|
||||||
|
--card-bg: rgba(30, 30, 30, 0.6);
|
||||||
|
--card-hover: rgba(127, 0, 255, 0.05);
|
||||||
|
--input-bg: #1a1a1a;
|
||||||
|
--dropdown-bg: #1e293b;
|
||||||
|
--shadow: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light Theme */
|
||||||
|
[data-theme="light"] {
|
||||||
|
--background: #f8fafc;
|
||||||
|
--background-alt: #ffffff;
|
||||||
|
--background-elevated: rgba(255, 255, 255, 0.95);
|
||||||
|
--text: #1e293b;
|
||||||
|
--text-muted: #64748b;
|
||||||
|
--border-color: rgba(0, 0, 0, 0.1);
|
||||||
|
--card-bg: rgba(255, 255, 255, 0.8);
|
||||||
|
--card-hover: rgba(127, 0, 255, 0.08);
|
||||||
|
--input-bg: #ffffff;
|
||||||
|
--dropdown-bg: #ffffff;
|
||||||
|
--shadow: rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #0f172a!important;
|
background-color: var(--background) !important;
|
||||||
color: #e2e8f0;
|
color: var(--text);
|
||||||
background: url('../../img/top_bg_transparency_4.png') repeat-x #0f172a;
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] body {
|
||||||
|
background: url('../../img/top_bg_transparency_4.png') repeat-x var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] body {
|
||||||
|
background: linear-gradient(180deg, #e0e7ff 0%, var(--background) 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gradient-text {
|
.gradient-text {
|
||||||
@@ -52,21 +88,22 @@ body {
|
|||||||
|
|
||||||
/* Form Styles */
|
/* Form Styles */
|
||||||
.form-control {
|
.form-control {
|
||||||
background-color: var(--background) !important;
|
background-color: var(--input-bg) !important;
|
||||||
border-color: rgba(255, 255, 255, 0.1) !important;
|
border-color: var(--border-color) !important;
|
||||||
color: var(--text) !important;
|
color: var(--text) !important;
|
||||||
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control:focus {
|
.form-control:focus {
|
||||||
background-color: var(--background) !important;
|
background-color: var(--input-bg) !important;
|
||||||
border-color: var(--primary) !important;
|
border-color: var(--primary) !important;
|
||||||
box-shadow: 0 0 0 0.25rem rgba(127, 0, 255, 0.25) !important;
|
box-shadow: 0 0 0 0.25rem rgba(127, 0, 255, 0.25) !important;
|
||||||
color: var(--text) !important;
|
color: var(--text) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-check-input {
|
.form-check-input {
|
||||||
background-color: var(--background) !important;
|
background-color: var(--input-bg) !important;
|
||||||
border-color: rgba(255, 255, 255, 0.1) !important;
|
border-color: var(--border-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-check-input:checked {
|
.form-check-input:checked {
|
||||||
@@ -81,8 +118,8 @@ body {
|
|||||||
|
|
||||||
/* Alert Styles */
|
/* Alert Styles */
|
||||||
.alert {
|
.alert {
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
background-color: var(--card-bg);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid var(--border-color);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,29 +129,37 @@ body {
|
|||||||
color: #28a745;
|
color: #28a745;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .alert-success {
|
||||||
|
background-color: rgba(40, 167, 69, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
.alert-danger {
|
.alert-danger {
|
||||||
background-color: rgba(220, 53, 69, 0.1);
|
background-color: rgba(220, 53, 69, 0.1);
|
||||||
border-color: rgba(220, 53, 69, 0.2);
|
border-color: rgba(220, 53, 69, 0.2);
|
||||||
color: #dc3545;
|
color: #dc3545;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .alert-danger {
|
||||||
|
background-color: rgba(220, 53, 69, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
/* Custom Pagination Styles */
|
/* Custom Pagination Styles */
|
||||||
.pagination {
|
.pagination {
|
||||||
--bs-pagination-color: var(--text);
|
--bs-pagination-color: var(--text);
|
||||||
--bs-pagination-bg: var(--background);
|
--bs-pagination-bg: var(--card-bg);
|
||||||
--bs-pagination-border-color: transparent;
|
--bs-pagination-border-color: var(--border-color);
|
||||||
--bs-pagination-hover-color: var(--text);
|
--bs-pagination-hover-color: var(--text);
|
||||||
--bs-pagination-hover-bg: rgba(255, 255, 255, 0.1);
|
--bs-pagination-hover-bg: var(--card-hover);
|
||||||
--bs-pagination-hover-border-color: transparent;
|
--bs-pagination-hover-border-color: var(--border-color);
|
||||||
--bs-pagination-focus-color: var(--text);
|
--bs-pagination-focus-color: var(--text);
|
||||||
--bs-pagination-focus-bg: rgba(255, 255, 255, 0.1);
|
--bs-pagination-focus-bg: var(--card-hover);
|
||||||
--bs-pagination-focus-box-shadow: none;
|
--bs-pagination-focus-box-shadow: none;
|
||||||
--bs-pagination-active-color: white;
|
--bs-pagination-active-color: white;
|
||||||
--bs-pagination-active-bg: linear-gradient(90deg, var(--primary), var(--accent));
|
--bs-pagination-active-bg: linear-gradient(90deg, var(--primary), var(--accent));
|
||||||
--bs-pagination-active-border-color: transparent;
|
--bs-pagination-active-border-color: transparent;
|
||||||
--bs-pagination-disabled-color: #6c757d;
|
--bs-pagination-disabled-color: var(--text-muted);
|
||||||
--bs-pagination-disabled-bg: var(--background);
|
--bs-pagination-disabled-bg: var(--card-bg);
|
||||||
--bs-pagination-disabled-border-color: transparent;
|
--bs-pagination-disabled-border-color: var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-link {
|
.page-link {
|
||||||
@@ -140,8 +185,9 @@ body {
|
|||||||
|
|
||||||
/* Custom dropdown styles */
|
/* Custom dropdown styles */
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
background-color: var(--background);
|
background-color: var(--dropdown-bg);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid var(--border-color);
|
||||||
|
box-shadow: 0 4px 15px var(--shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
@@ -149,7 +195,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item:hover {
|
.dropdown-item:hover {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: var(--card-hover);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,30 +249,18 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
background-color: rgba(15, 23, 42, 0.8);
|
background-color: var(--background-elevated);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar a {
|
.navbar a {
|
||||||
color: white!important;
|
color: var(--text) !important;
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu {
|
|
||||||
background-color: #1e293b;
|
|
||||||
border: 1px solid #334155;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item {
|
|
||||||
color: #e2e8f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item:hover {
|
|
||||||
background-color: #334155;
|
|
||||||
color: #e2e8f0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-divider {
|
.dropdown-divider {
|
||||||
border-top: 1px solid #334155;
|
border-top: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover-container{
|
.cover-container{
|
||||||
@@ -312,9 +346,10 @@ body {
|
|||||||
|
|
||||||
/* Card View Styles */
|
/* Card View Styles */
|
||||||
.game-card-enhanced {
|
.game-card-enhanced {
|
||||||
background-color: rgba(30, 30, 30, 0.8);
|
background-color: var(--card-bg);
|
||||||
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-card-enhanced:hover {
|
.game-card-enhanced:hover {
|
||||||
@@ -323,13 +358,14 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.game-card-enhanced .card-body {
|
.game-card-enhanced .card-body {
|
||||||
background-color: rgba(18, 18, 18, 0.9);
|
background-color: var(--card-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List View Styles */
|
/* List View Styles */
|
||||||
.game-card-list {
|
.game-card-list {
|
||||||
background-color: rgba(30, 30, 30, 0.8);
|
background-color: var(--card-bg);
|
||||||
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-card-list:hover {
|
.game-card-list:hover {
|
||||||
@@ -338,7 +374,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.game-card-list .card-body {
|
.game-card-list .card-body {
|
||||||
background-color: rgba(18, 18, 18, 0.9);
|
background-color: var(--card-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* View Mode Button Styles */
|
/* View Mode Button Styles */
|
||||||
@@ -350,11 +386,78 @@ body {
|
|||||||
.view-mode-btn.active {
|
.view-mode-btn.active {
|
||||||
background: linear-gradient(90deg, var(--primary), var(--accent));
|
background: linear-gradient(90deg, var(--primary), var(--accent));
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
color: white;
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-mode-btn:not(.active):hover {
|
.view-mode-btn:not(.active):hover {
|
||||||
background-color: rgba(127, 0, 255, 0.1);
|
background-color: var(--card-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Theme Toggle Button */
|
||||||
|
.theme-toggle-btn {
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: var(--card-bg);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle-btn:hover {
|
||||||
|
background: var(--card-hover);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle-btn i {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text color overrides for light theme */
|
||||||
|
[data-theme="light"] .text-white {
|
||||||
|
color: var(--text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .text-muted {
|
||||||
|
color: var(--text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .text-gray-400 {
|
||||||
|
color: var(--text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .bg-dark {
|
||||||
|
background-color: var(--card-bg) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .border-secondary {
|
||||||
|
border-color: var(--border-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .border-dark {
|
||||||
|
border-color: var(--border-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button styles for light theme */
|
||||||
|
[data-theme="light"] .btn-outline-light {
|
||||||
|
border-color: var(--border-color);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .btn-outline-light:hover {
|
||||||
|
background-color: var(--card-hover);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
footer {
|
||||||
|
background-color: var(--background-alt);
|
||||||
|
border-top-color: var(--border-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Responsive adjustments */
|
/* Responsive adjustments */
|
||||||
|
|||||||
@@ -3,53 +3,256 @@
|
|||||||
@section('title', $game->name)
|
@section('title', $game->name)
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container mt-4">
|
<!-- Hero Section with Background -->
|
||||||
<!-- Main Game Info Section -->
|
<div class="game-hero-section" style="background: linear-gradient(to bottom, rgba(15, 23, 42, 0.3) 0%, rgba(15, 23, 42, 0.9) 70%, #0f172a 100%), url('{{ $game->cover_url }}') center/cover;">
|
||||||
<div class="row mb-4">
|
<div class="container">
|
||||||
<!-- Left Column: Cover, Rating, Add to List -->
|
<div class="row align-items-end" style="min-height: 400px;">
|
||||||
<div class="col-md-3">
|
<div class="col-12">
|
||||||
<!-- Cover Image -->
|
<div class="game-hero-content pb-4">
|
||||||
<div class="game-cover position-relative mb-3">
|
<h1 class="display-4 fw-bold text-white mb-3">{{ $game->name }}</h1>
|
||||||
<img src="{{ $game->cover_url }}" class="img-fluid rounded shadow-lg w-100" alt="{{ $game->name }}">
|
<div class="d-flex flex-wrap align-items-center gap-3 mb-3">
|
||||||
@if($game->rating)
|
@if($game->rating)
|
||||||
<div class="position-absolute top-0 end-0 bg-dark bg-opacity-75 p-2 rounded-circle m-2 shadow">
|
<div class="hero-rating">
|
||||||
<div class="d-flex align-items-center justify-content-center">
|
<div class="d-flex align-items-center">
|
||||||
<span class="fw-bold text-warning">{{ number_format($game->rating, 1) }}</span>
|
<div class="rating-circle me-2">
|
||||||
|
<span class="rating-number">{{ number_format($game->rating, 0) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
@endif
|
<div class="rating-stars mb-1">
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Rating Section -->
|
|
||||||
<div class="card bg-dark text-white mb-3">
|
|
||||||
<div class="card-body text-center">
|
|
||||||
<h5 class="card-title">Rating</h5>
|
|
||||||
@if($game->rating)
|
|
||||||
<div class="d-flex justify-content-center">
|
|
||||||
<div class="rating-stars d-flex gap-1">
|
|
||||||
@for($i = 1; $i <= 5; $i++)
|
@for($i = 1; $i <= 5; $i++)
|
||||||
<i class="fas fa-star {{ $i <= ($game->rating/20) ? 'text-warning' : 'text-secondary' }}"></i>
|
<i class="fas fa-star {{ $i <= ($game->rating/20) ? 'text-warning' : 'text-secondary' }}"></i>
|
||||||
@endfor
|
@endfor
|
||||||
</div>
|
</div>
|
||||||
<span class="ms-2">({{ number_format($game->rating_count) }} ratings)</span>
|
<small class="text-muted">{{ number_format($game->rating_count) }} ratings</small>
|
||||||
</div>
|
</div>
|
||||||
@else
|
</div>
|
||||||
<p class="text-muted">No ratings yet</p>
|
</div>
|
||||||
|
@endif
|
||||||
|
@if($game->first_release_date)
|
||||||
|
<div class="hero-meta-item">
|
||||||
|
<i class="far fa-calendar-alt me-2"></i>
|
||||||
|
<span>{{ $game->first_release_date->format('Y') }}</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
<div class="hero-genres">
|
||||||
|
@foreach($game->genres()->limit(3)->get() as $genre)
|
||||||
|
<span class="badge bg-dark bg-opacity-75 border border-secondary">{{ $genre->name }}</span>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Main Content Area -->
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="row">
|
||||||
|
<!-- Left Column: Media & Description -->
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<!-- Media Gallery -->
|
||||||
|
@if($game->screenshots->count() > 0 || $game->videos->count() > 0)
|
||||||
|
<div class="media-gallery-section mb-4">
|
||||||
|
<div class="card gradient-border">
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<!-- Main Display -->
|
||||||
|
<div class="media-main-display">
|
||||||
|
@if($game->screenshots->count() > 0)
|
||||||
|
<img id="mainMediaDisplay" src="{{ $game->screenshots->first()->url }}" class="img-fluid w-100" alt="Screenshot" style="max-height: 500px; object-fit: cover;">
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Thumbnails -->
|
||||||
|
<div class="media-thumbnails p-3">
|
||||||
|
<div class="row g-2">
|
||||||
|
@foreach($game->screenshots->take(6) as $index => $screenshot)
|
||||||
|
<div class="col-2">
|
||||||
|
<div class="media-thumbnail {{ $index === 0 ? 'active' : '' }}" data-type="image" data-url="{{ $screenshot->url }}">
|
||||||
|
<img src="{{ $screenshot->url }}" class="img-fluid" alt="Screenshot {{ $index + 1 }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
@foreach($game->videos->take(2) as $video)
|
||||||
|
<div class="col-2">
|
||||||
|
<div class="media-thumbnail" data-type="video" data-video-id="{{ $video->video_id }}">
|
||||||
|
<img src="https://img.youtube.com/vi/{{ $video->video_id }}/mqdefault.jpg" class="img-fluid" alt="Video">
|
||||||
|
<div class="play-overlay">
|
||||||
|
<i class="fas fa-play-circle fa-2x"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- About This Game -->
|
||||||
|
<div class="card gradient-border mb-4">
|
||||||
|
<div class="card-header bg-dark bg-opacity-50">
|
||||||
|
<h3 class="h5 mb-0 text-white">About This Game</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@if($game->summary)
|
||||||
|
<p class="text-white mb-4">{{ $game->summary }}</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if($game->storyline)
|
||||||
|
<h6 class="text-white fw-bold mb-3">Storyline</h6>
|
||||||
|
<p class="text-muted">{{ $game->storyline }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Add to List Button -->
|
<!-- Reviews Section -->
|
||||||
|
<div class="card gradient-border mb-4">
|
||||||
|
<div class="card-header bg-dark bg-opacity-50 d-flex justify-content-between align-items-center">
|
||||||
|
<h3 class="h5 mb-0 text-white">Reviews</h3>
|
||||||
|
@auth
|
||||||
|
<a href="{{ route('games.reviews.create', $game) }}" class="btn btn-gradient btn-sm">
|
||||||
|
<i class="fas fa-plus me-1"></i>Write Review
|
||||||
|
</a>
|
||||||
|
@endauth
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@if($reviews->isEmpty())
|
||||||
|
<div class="text-center py-5">
|
||||||
|
<i class="fas fa-comments fa-3x text-muted mb-3"></i>
|
||||||
|
<p class="text-muted mb-3">No reviews yet. Be the first to review this game!</p>
|
||||||
|
@auth
|
||||||
|
<a href="{{ route('games.reviews.create', $game) }}" class="btn btn-gradient">
|
||||||
|
<i class="fas fa-plus me-1"></i>Write a Review
|
||||||
|
</a>
|
||||||
|
@else
|
||||||
|
<a href="{{ route('login') }}" class="btn btn-gradient">
|
||||||
|
<i class="fas fa-sign-in-alt me-1"></i>Login to Write a Review
|
||||||
|
</a>
|
||||||
|
@endauth
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<!-- Overall Rating Summary -->
|
||||||
|
@if($game->rating)
|
||||||
|
<div class="review-summary mb-4 p-4 bg-dark bg-opacity-25 rounded">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-4 text-center border-end border-secondary">
|
||||||
|
<div class="overall-score mb-2">
|
||||||
|
<span class="display-3 fw-bold gradient-text">{{ number_format($game->rating, 1) }}</span>
|
||||||
|
<span class="text-muted">/100</span>
|
||||||
|
</div>
|
||||||
|
<div class="rating-stars mb-2">
|
||||||
|
@for($i = 1; $i <= 5; $i++)
|
||||||
|
<i class="fas fa-star {{ $i <= ($game->rating/20) ? 'text-warning' : 'text-secondary' }}"></i>
|
||||||
|
@endfor
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">{{ number_format($game->rating_count) }} reviews</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h6 class="text-white mb-3">Rating Distribution</h6>
|
||||||
|
@foreach(array_slice($ratingDistribution, 0, 5) as $rating)
|
||||||
|
<div class="d-flex align-items-center mb-2">
|
||||||
|
<span class="rating-label text-muted me-2" style="width: 60px;">{{ $rating['range'] }} stars</span>
|
||||||
|
<div class="progress flex-grow-1" style="height: 8px;">
|
||||||
|
<div class="progress-bar bg-gradient" style="width: {{ $rating['percentage'] }}%; background: linear-gradient(90deg, var(--primary), var(--accent));"></div>
|
||||||
|
</div>
|
||||||
|
<span class="ms-2 text-muted" style="width: 50px;">{{ number_format($rating['percentage'], 0) }}%</span>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<!-- Individual Reviews -->
|
||||||
|
<div class="reviews-list">
|
||||||
|
@foreach($reviews->take(5) as $review)
|
||||||
|
<div class="review-item mb-3 p-3 bg-dark bg-opacity-25 rounded">
|
||||||
|
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="user-avatar me-3">
|
||||||
|
<i class="fas fa-user-circle fa-2x text-muted"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="{{ route('profile.show', $review->user) }}" class="text-white text-decoration-none fw-bold">
|
||||||
|
{{ $review->user->name }}
|
||||||
|
</a>
|
||||||
|
<div class="small text-muted">
|
||||||
|
<i class="far fa-clock me-1"></i>{{ $review->created_at->diffForHumans() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-end">
|
||||||
|
<div class="review-score mb-1" style="background: {{ $review->rating >= 7 ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : ($review->rating >= 5 ? 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' : 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)') }}; padding: 0.5rem 1rem; border-radius: 8px; display: inline-block;">
|
||||||
|
<span class="fw-bold text-white">{{ $review->rating }}/10</span>
|
||||||
|
</div>
|
||||||
|
@if($review->recommended)
|
||||||
|
<div class="small">
|
||||||
|
<i class="fas fa-thumbs-up text-success me-1"></i>
|
||||||
|
<span class="text-success">Recommended</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="review-content text-white">
|
||||||
|
{!! nl2br(e(Str::limit($review->content, 300))) !!}
|
||||||
|
@if(strlen($review->content) > 300)
|
||||||
|
<a href="{{ route('reviews.show', $review) }}" class="text-primary">Read more</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div class="review-footer mt-3 pt-3 border-top border-secondary d-flex justify-content-between">
|
||||||
|
<a href="{{ route('reviews.show', $review) }}" class="btn btn-sm btn-outline-gradient">
|
||||||
|
Read full review
|
||||||
|
</a>
|
||||||
|
@if(auth()->id() === $review->user_id)
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<a href="{{ route('reviews.edit', $review) }}" class="btn btn-sm btn-outline-gradient">
|
||||||
|
<i class="fas fa-edit"></i> Edit
|
||||||
|
</a>
|
||||||
|
<form action="{{ route('reviews.destroy', $review) }}" method="POST" class="d-inline">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit" class="btn btn-sm btn-outline-danger" onclick="return confirm('Are you sure?')">
|
||||||
|
<i class="fas fa-trash"></i> Delete
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if($reviews->count() > 5)
|
||||||
|
<div class="text-center mt-4">
|
||||||
|
<a href="{{ route('games.reviews.index', $game) }}" class="btn btn-outline-gradient">
|
||||||
|
View All {{ $reviews->count() }} Reviews
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right Column: Game Details Sidebar -->
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<!-- Cover & Action Buttons -->
|
||||||
|
<div class="card gradient-border mb-4 sticky-top" style="top: 100px;">
|
||||||
|
<div class="card-body">
|
||||||
|
<img src="{{ $game->cover_url }}" class="img-fluid rounded mb-3 w-100" alt="{{ $game->name }}" style="box-shadow: 0 4px 20px rgba(0,0,0,0.5);">
|
||||||
|
|
||||||
|
<!-- Add to List -->
|
||||||
@auth
|
@auth
|
||||||
<div class="dropdown mb-3 w-100">
|
<div class="dropdown mb-3 w-100">
|
||||||
<button class="btn btn-outline-primary dropdown-toggle w-100" type="button" id="addToListDropdown"
|
<button class="btn btn-gradient w-100 py-2" type="button" data-bs-toggle="dropdown">
|
||||||
data-bs-toggle="dropdown" aria-expanded="false">
|
<i class="fas fa-plus me-2"></i>Add to My Lists
|
||||||
<i class="fas fa-plus me-2"></i>Add to List
|
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-dark w-100" aria-labelledby="addToListDropdown">
|
<ul class="dropdown-menu dropdown-menu-dark w-100">
|
||||||
@foreach(Auth::user()->lists as $list)
|
@foreach(Auth::user()->lists as $list)
|
||||||
<li>
|
<li>
|
||||||
<form action="{{ route('lists.addGame', $list) }}" method="POST" class="d-inline">
|
<form action="{{ route('lists.addGame', $list) }}" method="POST">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" name="game_id" value="{{ $game->id }}">
|
<input type="hidden" name="game_id" value="{{ $game->id }}">
|
||||||
<button type="submit" class="dropdown-item">
|
<button type="submit" class="dropdown-item">
|
||||||
@@ -66,308 +269,299 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@else
|
||||||
|
<a href="{{ route('login') }}" class="btn btn-gradient w-100 mb-3 py-2">
|
||||||
|
<i class="fas fa-sign-in-alt me-2"></i>Login to Add to List
|
||||||
|
</a>
|
||||||
@endauth
|
@endauth
|
||||||
|
|
||||||
|
<!-- Game Info -->
|
||||||
|
<div class="game-info-sidebar">
|
||||||
|
<div class="info-item mb-3 pb-3 border-bottom border-secondary">
|
||||||
|
<small class="text-muted d-block mb-1">Release Date</small>
|
||||||
|
<span class="text-white">{{ $game->first_release_date ? $game->first_release_date->format('F j, Y') : 'TBA' }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Middle Column: Title, Release Date, Description -->
|
@if($game->platforms()->count() > 0)
|
||||||
<div class="col-md-6">
|
<div class="info-item mb-3 pb-3 border-bottom border-secondary">
|
||||||
<!-- Title and Release Date -->
|
<small class="text-muted d-block mb-2">Platforms</small>
|
||||||
<h1 class="fw-bold mb-2">{{ $game->name }}</h1>
|
|
||||||
<p class="text-muted mb-3">
|
|
||||||
<i class="far fa-calendar-alt me-2"></i> Released on {{ $game->first_release_date->format('F j, Y') }}
|
|
||||||
@if(isset($game->company))
|
|
||||||
by {{ $game->company }}
|
|
||||||
@endif
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<!-- Description -->
|
|
||||||
<div class="card bg-dark text-white mb-3">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title mb-3">Description</h5>
|
|
||||||
<p class="card-text">{{ $game->summary }}</p>
|
|
||||||
@if($game->storyline)
|
|
||||||
<h6 class="mt-4 mb-2">Storyline</h6>
|
|
||||||
<p class="card-text">{{ $game->storyline }}</p>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Right Column: Platforms, Genres -->
|
|
||||||
<div class="col-md-3">
|
|
||||||
<!-- Platforms -->
|
|
||||||
<div class="card bg-dark text-white mb-3">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title mb-3">Platforms</h5>
|
|
||||||
<div class="d-flex flex-wrap gap-2">
|
<div class="d-flex flex-wrap gap-2">
|
||||||
@foreach($game->platforms()->get() as $platform)
|
@foreach($game->platforms()->get() as $platform)
|
||||||
<span class="badge bg-secondary">{{ $platform->name }}</span>
|
<span class="badge bg-secondary">
|
||||||
|
<i class="fas fa-desktop me-1"></i>{{ $platform->name }}
|
||||||
|
</span>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endif
|
||||||
|
|
||||||
<!-- Genres -->
|
@if($game->genres()->count() > 0)
|
||||||
<div class="card bg-dark text-white mb-3">
|
<div class="info-item mb-3 pb-3 border-bottom border-secondary">
|
||||||
<div class="card-body">
|
<small class="text-muted d-block mb-2">Genres</small>
|
||||||
<h5 class="card-title mb-3">Genres</h5>
|
|
||||||
<div class="d-flex flex-wrap gap-2">
|
<div class="d-flex flex-wrap gap-2">
|
||||||
@foreach($game->genres()->get() as $genre)
|
@foreach($game->genres()->get() as $genre)
|
||||||
<span class="badge bg-primary">{{ $genre->name }}</span>
|
<span class="badge bg-primary">{{ $genre->name }}</span>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Bottom Section -->
|
|
||||||
<div class="row mb-4">
|
|
||||||
<!-- Left Column: Stats -->
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card bg-dark text-white mb-4">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="mb-0">Stats</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<ul class="list-group list-group-flush bg-transparent">
|
|
||||||
<li class="list-group-item bg-dark text-white border-secondary">
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<span><i class="far fa-calendar-alt me-2"></i>Release Date</span>
|
|
||||||
<span class="text-end">{{ $game->first_release_date->format('F j, Y') }}</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
@if($game->rating)
|
|
||||||
<li class="list-group-item bg-dark text-white border-secondary">
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<span><i class="fas fa-star me-2"></i>Rating</span>
|
|
||||||
<span class="text-end">{{ number_format($game->rating, 1) }}/100 ({{ number_format($game->rating_count) }} ratings)</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if($game->url)
|
@if($game->url)
|
||||||
<li class="list-group-item bg-dark text-white border-secondary">
|
<div class="info-item mb-3 pb-3 border-bottom border-secondary">
|
||||||
<div class="d-flex justify-content-between">
|
<small class="text-muted d-block mb-1">Official Website</small>
|
||||||
<span><i class="fas fa-external-link-alt me-2"></i>Website</span>
|
<a href="{{ $game->url }}" target="_blank" class="text-white text-decoration-none">
|
||||||
<a href="{{ $game->url }}" target="_blank" class="text-primary">Visit</a>
|
Visit Website <i class="fas fa-external-link-alt ms-1"></i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
@endif
|
@endif
|
||||||
</ul>
|
|
||||||
|
|
||||||
@if($reviews->isNotEmpty())
|
@if($game->rating)
|
||||||
<div class="mt-4">
|
<div class="info-item">
|
||||||
<h6 class="mb-3">Rating Distribution</h6>
|
<small class="text-muted d-block mb-1">Community Rating</small>
|
||||||
@foreach($ratingDistribution as $rating)
|
<div class="d-flex align-items-center">
|
||||||
<div class="d-flex align-items-center mb-2">
|
<span class="text-white fw-bold me-2">{{ number_format($game->rating, 1) }}/100</span>
|
||||||
<div class="rating-label me-2" style="width: 30px;">{{ $rating['range'] }}</div>
|
<span class="text-muted small">({{ number_format($game->rating_count) }} votes)</span>
|
||||||
<div class="progress flex-grow-1" style="height: 10px;">
|
|
||||||
<div class="progress-bar bg-warning" role="progressbar" style="width: {{ $rating['percentage'] }}%"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ms-2" style="width: 40px;">{{ $rating['count'] }}</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right Column: Games on Series (Similar Games) -->
|
<!-- Similar Games -->
|
||||||
<div class="col-md-8">
|
|
||||||
@if($game->similar_games->count() > 0)
|
@if($game->similar_games->count() > 0)
|
||||||
<div class="card bg-dark text-white mb-4">
|
<div class="card gradient-border mb-4">
|
||||||
<div class="card-header">
|
<div class="card-header bg-dark bg-opacity-50">
|
||||||
<h5 class="mb-0">Games on Series</h5>
|
<h5 class="mb-0 text-white">You May Also Like</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body p-2">
|
||||||
<div class="row g-3">
|
@foreach($game->similar_games->take(4) as $similar)
|
||||||
@foreach($game->similar_games as $similar)
|
<a href="{{ route('games.show', $similar) }}" class="similar-game-item d-flex p-2 mb-2 rounded text-decoration-none">
|
||||||
<div class="col-md-6 col-lg-4">
|
<img src="{{ $similar->cover_url }}" alt="{{ $similar->name }}" class="similar-game-cover me-3 rounded">
|
||||||
<div class="card bg-dark h-100 hover-scale">
|
<div class="flex-grow-1">
|
||||||
<a href="{{ route('games.show', $similar) }}" class="text-decoration-none">
|
<h6 class="text-white mb-1 small">{{ Str::limit($similar->name, 40) }}</h6>
|
||||||
<img src="{{ $similar->cover_url }}" class="card-img-top" alt="{{ $similar->name }}">
|
<div class="d-flex align-items-center">
|
||||||
<div class="card-body">
|
|
||||||
<h6 class="card-title text-white">{{ $similar->name }}</h6>
|
|
||||||
<p class="card-text text-muted small">{{ $similar->first_release_date->format('Y') }}</p>
|
|
||||||
@if($similar->rating)
|
@if($similar->rating)
|
||||||
<div class="d-flex align-items-center mt-2">
|
<span class="badge bg-primary me-2">{{ number_format($similar->rating, 0) }}</span>
|
||||||
<div class="rating-stars d-flex gap-1">
|
@endif
|
||||||
@for($i = 1; $i <= 5; $i++)
|
@if($similar->first_release_date)
|
||||||
<i class="fas fa-star {{ $i <= ($similar->rating/20) ? 'text-warning' : 'text-secondary' }}"></i>
|
<small class="text-muted">{{ $similar->first_release_date->format('Y') }}</small>
|
||||||
@endfor
|
|
||||||
</div>
|
|
||||||
<span class="ms-2 small">{{ number_format($similar->rating, 1) }}</span>
|
|
||||||
</div>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
<!-- DLCs -->
|
||||||
@if($game->dlcs->count() > 0)
|
@if($game->dlcs->count() > 0)
|
||||||
<div class="card bg-dark text-white mb-4">
|
<div class="card gradient-border mb-4">
|
||||||
<div class="card-header">
|
<div class="card-header bg-dark bg-opacity-50">
|
||||||
<h5 class="mb-0">DLCs & Expansions</h5>
|
<h5 class="mb-0 text-white">DLC & Expansions</h5>
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row g-3">
|
|
||||||
@foreach($game->dlcs as $dlc)
|
|
||||||
<div class="col-md-6 col-lg-4">
|
|
||||||
<div class="card bg-dark h-100">
|
|
||||||
<img src="{{ $dlc->cover_url }}" class="card-img-top" alt="{{ $dlc->name }}">
|
|
||||||
<div class="card-body">
|
|
||||||
<h6 class="card-title">{{ $dlc->name }}</h6>
|
|
||||||
<a href="{{ route('games.show', $dlc) }}" class="btn btn-sm btn-outline-primary mt-2">View Details</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-body p-2">
|
||||||
|
@foreach($game->dlcs->take(4) as $dlc)
|
||||||
|
<a href="{{ route('games.show', $dlc) }}" class="similar-game-item d-flex p-2 mb-2 rounded text-decoration-none">
|
||||||
|
<img src="{{ $dlc->cover_url }}" alt="{{ $dlc->name }}" class="similar-game-cover me-3 rounded">
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<h6 class="text-white mb-1 small">{{ Str::limit($dlc->name, 40) }}</h6>
|
||||||
|
<small class="text-muted">Additional Content</small>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
<!-- Latest Reviews Section -->
|
@push('styles')
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="card bg-dark text-white mb-4">
|
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
|
||||||
<h5 class="mb-0">Latest Reviews</h5>
|
|
||||||
@auth
|
|
||||||
<a href="{{ route('games.reviews.create', $game) }}" class="btn btn-gradient btn-sm">
|
|
||||||
<i class="fas fa-plus me-2"></i>Write a Review
|
|
||||||
</a>
|
|
||||||
@endauth
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
@if($reviews->isEmpty())
|
|
||||||
<div class="text-center py-5">
|
|
||||||
<i class="fas fa-comments fa-3x text-muted mb-3"></i>
|
|
||||||
<p class="text-muted mb-3">No reviews yet. Be the first to review this game!</p>
|
|
||||||
@auth
|
|
||||||
<a href="{{ route('games.reviews.create', $game) }}" class="btn btn-gradient">
|
|
||||||
<i class="fas fa-plus me-2"></i>Write a Review
|
|
||||||
</a>
|
|
||||||
@else
|
|
||||||
<a href="{{ route('login') }}" class="btn btn-gradient">
|
|
||||||
<i class="fas fa-sign-in-alt me-2"></i>Login to Write a Review
|
|
||||||
</a>
|
|
||||||
@endauth
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<div class="reviews-list">
|
|
||||||
@foreach($reviews->take(3) as $review)
|
|
||||||
<div class="card bg-dark border-secondary mb-4">
|
|
||||||
<div class="card-header">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="me-3">
|
|
||||||
<i class="fas fa-user-circle fa-2x"></i>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h6 class="mb-0">
|
|
||||||
<a href="{{ route('profile.show', $review->user) }}" class="text-white text-decoration-none">
|
|
||||||
{{ $review->user->name }}
|
|
||||||
</a>
|
|
||||||
</h6>
|
|
||||||
<small class="text-muted">
|
|
||||||
<i class="far fa-clock"></i> {{ $review->created_at->diffForHumans() }}
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="rating-badge me-2 px-2 py-1 rounded" style="background-color: {{ $review->rating >= 7 ? '#28a745' : ($review->rating >= 5 ? '#ffc107' : '#dc3545') }};">
|
|
||||||
<span class="fw-bold">{{ $review->rating }}/10</span>
|
|
||||||
</div>
|
|
||||||
@if($review->recommended)
|
|
||||||
<span class="badge bg-success">Recommended</span>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="review-content">
|
|
||||||
{!! nl2br(e(Str::limit($review->content, 300))) !!}
|
|
||||||
@if(strlen($review->content) > 300)
|
|
||||||
<a href="{{ route('reviews.show', $review) }}" class="text-primary">Read more</a>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer bg-dark border-top border-secondary">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<a href="{{ route('reviews.show', $review) }}" class="btn btn-link text-white p-0">
|
|
||||||
Read full review
|
|
||||||
</a>
|
|
||||||
@if(auth()->id() === $review->user_id)
|
|
||||||
<div class="d-flex gap-2">
|
|
||||||
<a href="{{ route('reviews.edit', $review) }}" class="btn btn-outline-primary btn-sm">
|
|
||||||
<i class="fas fa-edit"></i> Edit
|
|
||||||
</a>
|
|
||||||
<form action="{{ route('reviews.destroy', $review) }}" method="POST" class="d-inline">
|
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="btn btn-outline-danger btn-sm" onclick="return confirm('Are you sure you want to delete this review?')">
|
|
||||||
<i class="fas fa-trash"></i> Delete
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
@if($reviews->count() > 3)
|
|
||||||
<div class="text-center mt-3">
|
|
||||||
<a href="{{ route('games.reviews.index', $game) }}" class="btn btn-outline-primary">
|
|
||||||
View All {{ $reviews->count() }} Reviews
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.hover-scale {
|
/* Hero Section */
|
||||||
transition: transform 0.3s ease;
|
.game-hero-section {
|
||||||
|
margin: -2rem -15px 0;
|
||||||
|
padding: 2rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover-scale:hover {
|
[data-theme="light"] .game-hero-section {
|
||||||
transform: scale(1.03);
|
background-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-gradient {
|
.rating-circle {
|
||||||
background: linear-gradient(90deg, var(--primary), var(--accent));
|
width: 60px;
|
||||||
border: none;
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 4px 15px rgba(79, 70, 229, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating-number {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-gradient:hover {
|
.hero-meta-item {
|
||||||
opacity: 0.9;
|
padding: 0.5rem 1rem;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border-radius: 8px;
|
||||||
color: white;
|
color: white;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-outline-primary {
|
[data-theme="light"] .hero-meta-item {
|
||||||
border-color: var(--primary);
|
background: rgba(255, 255, 255, 0.9);
|
||||||
color: var(--primary);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-outline-primary:hover {
|
/* Media Gallery */
|
||||||
background-color: var(--primary);
|
.media-main-display {
|
||||||
|
background: #000;
|
||||||
|
min-height: 400px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-thumbnail {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-thumbnail:hover,
|
||||||
|
.media-thumbnail.active {
|
||||||
|
border-color: var(--gradient-start);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-thumbnail img {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
color: white;
|
color: white;
|
||||||
|
text-shadow: 0 2px 4px rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar Games */
|
||||||
|
.similar-game-item {
|
||||||
|
transition: all 0.2s;
|
||||||
|
background: var(--card-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.similar-game-item:hover {
|
||||||
|
background: var(--card-hover);
|
||||||
|
transform: translateX(5px);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.similar-game-cover {
|
||||||
|
width: 60px;
|
||||||
|
height: 80px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reviews */
|
||||||
|
.review-item {
|
||||||
|
transition: all 0.2s;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-item:hover {
|
||||||
|
border-color: rgba(127, 0, 255, 0.3);
|
||||||
|
background: var(--card-hover) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card Styles */
|
||||||
|
.card {
|
||||||
|
background: var(--card-bg);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light theme specific styles */
|
||||||
|
[data-theme="light"] .card {
|
||||||
|
box-shadow: 0 2px 8px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .text-white {
|
||||||
|
color: var(--text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .text-muted {
|
||||||
|
color: var(--text-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="light"] .bg-dark {
|
||||||
|
background-color: var(--card-bg) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.game-hero-section {
|
||||||
|
min-height: 300px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-top {
|
||||||
|
position: relative !important;
|
||||||
|
top: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@endsection
|
@endpush
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Media Gallery Handler
|
||||||
|
const thumbnails = document.querySelectorAll('.media-thumbnail');
|
||||||
|
const mainDisplay = document.getElementById('mainMediaDisplay');
|
||||||
|
|
||||||
|
if (mainDisplay && thumbnails.length > 0) {
|
||||||
|
thumbnails.forEach(thumbnail => {
|
||||||
|
thumbnail.addEventListener('click', function() {
|
||||||
|
// Remove active class from all
|
||||||
|
thumbnails.forEach(t => t.classList.remove('active'));
|
||||||
|
// Add active class to clicked
|
||||||
|
this.classList.add('active');
|
||||||
|
|
||||||
|
const type = this.getAttribute('data-type');
|
||||||
|
|
||||||
|
if (type === 'image') {
|
||||||
|
const imageUrl = this.getAttribute('data-url');
|
||||||
|
mainDisplay.outerHTML = `<img id="mainMediaDisplay" src="${imageUrl}" class="img-fluid w-100" alt="Screenshot" style="max-height: 500px; object-fit: cover;">`;
|
||||||
|
} else if (type === 'video') {
|
||||||
|
const videoId = this.getAttribute('data-video-id');
|
||||||
|
mainDisplay.outerHTML = `<div id="mainMediaDisplay" class="ratio ratio-16x9"><iframe src="https://www.youtube.com/embed/${videoId}" allowfullscreen></iframe></div>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|||||||
@@ -189,7 +189,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center gap-3">
|
||||||
|
<!-- Theme Toggle Button -->
|
||||||
|
<button type="button" class="theme-toggle-btn" id="themeToggle" aria-label="Toggle theme">
|
||||||
|
<i class="fas fa-moon" id="themeIcon"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
@auth
|
@auth
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-outline-light dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
<button class="btn btn-outline-light dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
||||||
@@ -249,6 +254,48 @@
|
|||||||
|
|
||||||
<!-- Bootstrap Bundle with Popper -->
|
<!-- Bootstrap Bundle with Popper -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Theme Toggle Script -->
|
||||||
|
<script>
|
||||||
|
// Theme management
|
||||||
|
(function() {
|
||||||
|
const themeToggle = document.getElementById('themeToggle');
|
||||||
|
const themeIcon = document.getElementById('themeIcon');
|
||||||
|
const htmlElement = document.documentElement;
|
||||||
|
|
||||||
|
// Get saved theme or default to dark
|
||||||
|
const savedTheme = localStorage.getItem('theme') || 'dark';
|
||||||
|
|
||||||
|
// Apply theme on load
|
||||||
|
function applyTheme(theme) {
|
||||||
|
htmlElement.setAttribute('data-theme', theme);
|
||||||
|
|
||||||
|
// Update icon
|
||||||
|
if (theme === 'dark') {
|
||||||
|
themeIcon.classList.remove('fa-sun');
|
||||||
|
themeIcon.classList.add('fa-moon');
|
||||||
|
} else {
|
||||||
|
themeIcon.classList.remove('fa-moon');
|
||||||
|
themeIcon.classList.add('fa-sun');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply saved theme immediately
|
||||||
|
applyTheme(savedTheme);
|
||||||
|
|
||||||
|
// Toggle theme on button click
|
||||||
|
if (themeToggle) {
|
||||||
|
themeToggle.addEventListener('click', function() {
|
||||||
|
const currentTheme = htmlElement.getAttribute('data-theme');
|
||||||
|
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||||
|
|
||||||
|
applyTheme(newTheme);
|
||||||
|
localStorage.setItem('theme', newTheme);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
@stack('scripts')
|
@stack('scripts')
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user