Files
animexe/resources/views/frontend/tribunal/index.blade.php
T
2026-07-14 00:01:48 +03:00

223 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('frontend.layouts.app')
@section('title', 'Anime Mahkemesi | Animexe')
@push('styles')
<style>
.trib-hero{padding-top:calc(var(--nav-h) + 40px);padding-bottom:32px;text-align:center;background:radial-gradient(ellipse at 50% 0%,rgba(255,45,125,.12) 0%,transparent 70%)}
.trib-hero h1{font-size:2rem;font-weight:900;letter-spacing:-.02em;margin-bottom:8px}
.trib-hero h1 span{color:#ff2d7d}
.trib-hero p{color:rgba(255,255,255,.45);font-size:.95rem}
.trib-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px;padding:0 0 40px}
.trib-card{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.07);border-radius:14px;padding:20px;transition:border-color .2s,transform .2s;cursor:pointer;text-decoration:none;display:block;color:#fff}
.trib-card:hover{border-color:rgba(255,45,125,.3);transform:translateY(-2px)}
.trib-card-anime{font-size:.72rem;color:rgba(255,45,125,.8);font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:8px}
.trib-card-q{font-size:.98rem;font-weight:700;line-height:1.4;margin-bottom:14px}
.trib-sides{display:flex;gap:8px;margin-bottom:14px}
.trib-side{flex:1;padding:6px 10px;border-radius:8px;font-size:.75rem;font-weight:700;text-align:center}
.trib-side.a{background:rgba(0,200,100,.1);color:#00c864;border:1px solid rgba(0,200,100,.2)}
.trib-side.b{background:rgba(255,60,60,.1);color:#ff3c3c;border:1px solid rgba(255,60,60,.2)}
.trib-side.c{background:rgba(59,130,246,.1);color:#3b82f6;border:1px solid rgba(59,130,246,.2)}
.trib-side.d{background:rgba(245,158,11,.1);color:#f59e0b;border:1px solid rgba(245,158,11,.2)}
.trib-side.e{background:rgba(167,139,250,.1);color:#a78bfa;border:1px solid rgba(167,139,250,.2)}
.trib-side.f{background:rgba(236,72,153,.1);color:#ec4899;border:1px solid rgba(236,72,153,.2)}
.trib-meta{display:flex;gap:12px;font-size:.72rem;color:rgba(255,255,255,.3)}
.trib-status-open{color:#00c864;font-weight:700}
.trib-status-closed{color:rgba(255,255,255,.3)}
.trib-create-btn{display:inline-flex;align-items:center;gap:8px;padding:10px 24px;border-radius:20px;background:rgba(255,45,125,.15);border:1px solid rgba(255,45,125,.3);color:#ff2d7d;font-weight:700;font-size:.88rem;cursor:pointer;text-decoration:none;transition:all .15s;font-family:inherit}
.trib-create-btn:hover{background:rgba(255,45,125,.28)}
/* Modal */
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.7);z-index:1000;display:none;align-items:center;justify-content:center;padding:16px}
.modal-overlay.on{display:flex}
.modal-box{background:#0e0e1a;border:1px solid rgba(255,255,255,.1);border-radius:18px;padding:28px;width:100%;max-width:520px;max-height:90vh;overflow-y:auto}
.modal-title{font-size:1.15rem;font-weight:900;margin-bottom:20px}
.mf-label{font-size:.75rem;font-weight:700;color:rgba(255,255,255,.45);text-transform:uppercase;letter-spacing:.07em;margin-bottom:6px}
.mf-input{width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:10px 14px;color:#fff;font-size:.9rem;font-family:inherit;outline:none;margin-bottom:14px;resize:none}
.mf-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.mf-btn{width:100%;padding:12px;border-radius:12px;border:none;background:rgba(255,45,125,.2);color:#ff2d7d;font-weight:700;font-size:.9rem;cursor:pointer;font-family:inherit;transition:background .15s}
.mf-btn:hover{background:rgba(255,45,125,.35)}
</style>
@endpush
@section('content')
<div style="max-width:1200px;margin:0 auto;padding:0 20px">
<div class="trib-hero">
<h1>⚖️ Anime <span>Mahkemesi</span></h1>
<p>Tartışmalı kararlar, karakterler, sahneler topluluk yargılıyor.</p>
@auth
<br>
<button class="trib-create-btn" onclick="document.getElementById('create-modal').classList.add('on')">
<i class="bi bi-plus-lg"></i> Dava
</button>
@endauth
</div>
<div class="trib-grid">
@forelse($tribunals as $t)
<a class="trib-card" href="{{ route('tribunal.show', $t) }}">
<div class="trib-card-anime">{{ $t->anime->title }}</div>
<div class="trib-card-q">{{ $t->question }}</div>
<div class="trib-sides" style="grid-template-columns:repeat({{ min(count($t->allSides()), 4) }},1fr)">
@foreach($t->allSides() as $key => $label)
<div class="trib-side {{ $key }}">{{ Str::limit($label, 20) }}</div>
@endforeach
</div>
<div class="trib-meta">
<span class="trib-status-{{ $t->status }}">{{ $t->status === 'open' ? '🟢 Açık' : '🔴 Kapalı' }}</span>
<span><i class="bi bi-people"></i> {{ $t->votes_count }} oy</span>
<span>{{ $t->created_at->diffForHumans() }}</span>
</div>
</a>
@empty
<div style="grid-column:1/-1;text-align:center;padding:60px;color:rgba(255,255,255,.3)">
<i class="bi bi-balance" style="font-size:3rem;display:block;margin-bottom:12px"></i>
Henüz dava açılmamış.
</div>
@endforelse
</div>
{{ $tribunals->links('frontend.pagination') }}
</div>
{{-- Dava Açma Modalı --}}
@auth
<div class="modal-overlay" id="create-modal" onclick="if(event.target===this)this.classList.remove('on')">
<div class="modal-box">
<div class="modal-title">⚖️ Yeni Dava </div>
<div class="mf-label">Anime</div>
<input class="mf-input" type="text" id="cm-anime-search" placeholder="Anime adı ara..." autocomplete="off" oninput="searchAnime(this.value)">
<div id="cm-anime-results" style="margin-bottom:14px;display:none;background:rgba(0,0,0,.4);border:1px solid rgba(255,255,255,.1);border-radius:10px;overflow:hidden;max-height:160px;overflow-y:auto"></div>
<input type="hidden" id="cm-anime-id">
<div class="mf-label">Soru / Karar</div>
<textarea class="mf-input" id="cm-question" rows="2" maxlength="280" placeholder="Örn: Sasuke'nin Konoha'yı terk etmesi doğru muydu?"></textarea>
<div id="cm-sides-wrap">
<div class="mf-row" style="margin-bottom:0">
<div>
<div class="mf-label" style="color:#00c864">Taraf A (Yeşil)</div>
<input class="mf-input" id="cm-side-a" maxlength="100" placeholder="Örn: Haklıydı">
</div>
<div>
<div class="mf-label" style="color:#ff3c3c">Taraf B (Kırmızı)</div>
<input class="mf-input" id="cm-side-b" maxlength="100" placeholder="Örn: Haksızdı">
</div>
</div>
<div id="cm-extra-sides"></div>
</div>
<div style="margin-bottom:14px">
<button type="button" id="cm-add-side-btn" onclick="addExtraSide()"
style="background:none;border:1px dashed rgba(255,255,255,.2);border-radius:8px;color:rgba(255,255,255,.4);font-size:.78rem;padding:6px 14px;cursor:pointer;font-family:inherit;transition:all .15s;width:100%"
onmouseover="this.style.borderColor='rgba(255,255,255,.4)';this.style.color='#fff'"
onmouseout="this.style.borderColor='rgba(255,255,255,.2)';this.style.color='rgba(255,255,255,.4)'">
<i class="bi bi-plus-lg"></i> Seçenek Ekle (max 4 ekstra)
</button>
</div>
<div class="mf-label">Kapanış Tarihi (isteğe bağlı)</div>
<input class="mf-input" type="date" id="cm-closes-at" min="{{ now()->addDay()->format('Y-m-d') }}">
<div id="cm-error" style="color:#ff4444;font-size:.8rem;margin-bottom:10px;display:none"></div>
<button class="mf-btn" onclick="submitTribunal()">Davayı </button>
</div>
</div>
@endauth
@endsection
@push('scripts')
<script>
const CSRF = document.querySelector('meta[name="csrf-token"]')?.content ?? '';
let animeSearchTimer = null;
function searchAnime(q) {
clearTimeout(animeSearchTimer);
if (q.length < 2) { document.getElementById('cm-anime-results').style.display = 'none'; return; }
animeSearchTimer = setTimeout(async () => {
const r = await fetch(`/search?q=${encodeURIComponent(q)}&json=1`);
if (!r.ok) return;
const d = await r.json();
const res = document.getElementById('cm-anime-results');
const items = (d.animes || d.results || []).slice(0, 6);
if (!items.length) { res.style.display = 'none'; return; }
res.style.display = 'block';
res.innerHTML = items.map(a => `<div onclick="selectAnime(${a.id},'${a.title.replace(/'/g,"\\'")}')"
style="padding:8px 12px;cursor:pointer;font-size:.85rem;border-bottom:1px solid rgba(255,255,255,.05);display:flex;align-items:center;gap:10px"
onmouseover="this.style.background='rgba(255,255,255,.07)'" onmouseout="this.style.background=''">
${a.cover ? `<img src="${a.cover}" style="width:28px;height:40px;object-fit:cover;border-radius:3px;flex-shrink:0">` : '<div style="width:28px;height:40px;background:#222;border-radius:3px;flex-shrink:0"></div>'}
<span>${a.title}</span>
</div>`).join('');
}, 300);
}
function selectAnime(id, title) {
document.getElementById('cm-anime-id').value = id;
document.getElementById('cm-anime-search').value = title;
document.getElementById('cm-anime-results').style.display = 'none';
}
const SIDE_COLORS = ['#00c864','#ff3c3c','#3b82f6','#f59e0b','#a78bfa','#ec4899'];
const SIDE_NAMES = ['A (Yeşil)','B (Kırmızı)','C (Mavi)','D (Turuncu)','E (Mor)','F (Pembe)'];
let extraSideCount = 0;
function addExtraSide() {
if (extraSideCount >= 4) return;
extraSideCount++;
const idx = extraSideCount + 1; // 0=a,1=b, so extra starts at 2 (c)
const color = SIDE_COLORS[idx] || '#ffffff';
const name = SIDE_NAMES[idx] || ('Seçenek ' + (idx+1));
const wrap = document.getElementById('cm-extra-sides');
const div = document.createElement('div');
div.id = 'cm-extra-' + extraSideCount;
div.style.marginTop = '10px';
div.innerHTML = `
<div style="display:flex;align-items:center;gap:6px">
<div style="font-size:.72rem;font-weight:700;color:${color};text-transform:uppercase;letter-spacing:.07em;white-space:nowrap">Taraf ${name}</div>
<button type="button" onclick="removeExtraSide(${extraSideCount})"
style="margin-left:auto;background:none;border:none;color:rgba(255,80,80,.5);cursor:pointer;font-size:.8rem;padding:0 4px">✕</button>
</div>
<input class="mf-input" id="cm-extra-val-${extraSideCount}" maxlength="100" placeholder="Seçenek metni..." style="margin-top:4px">`;
wrap.appendChild(div);
if (extraSideCount >= 4) document.getElementById('cm-add-side-btn').style.display = 'none';
}
function removeExtraSide(n) {
document.getElementById('cm-extra-' + n)?.remove();
extraSideCount = Math.max(0, extraSideCount - 1);
document.getElementById('cm-add-side-btn').style.display = '';
// Renumber visible extras
const extras = document.getElementById('cm-extra-sides').children;
extraSideCount = extras.length;
}
async function submitTribunal() {
const err = document.getElementById('cm-error');
err.style.display = 'none';
const animeId = document.getElementById('cm-anime-id').value;
const question = document.getElementById('cm-question').value.trim();
const sideA = document.getElementById('cm-side-a').value.trim();
const sideB = document.getElementById('cm-side-b').value.trim();
const closesAt = document.getElementById('cm-closes-at').value;
// Extra sides
const extraSides = [];
for (let i = 1; i <= 4; i++) {
const v = document.getElementById('cm-extra-val-' + i)?.value.trim();
if (v) extraSides.push(v);
}
if (!animeId) { err.textContent = 'Anime seçin.'; err.style.display = 'block'; return; }
if (question.length < 10) { err.textContent = 'Soru en az 10 karakter olmalı.'; err.style.display = 'block'; return; }
if (!sideA || !sideB) { err.textContent = 'A ve B taraflarını doldurun.'; err.style.display = 'block'; return; }
const r = await fetch('/mahkeme', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF, 'Accept': 'application/json' },
body: JSON.stringify({ anime_id: animeId, question, side_a: sideA, side_b: sideB, extra_sides: extraSides, closes_at: closesAt || null }),
});
const d = await r.json();
if (d.url) window.location.href = d.url;
else { err.textContent = d.error || 'Hata oluştu.'; err.style.display = 'block'; }
}
</script>
@endpush