Initial commit: Animexe Laravel platform

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 00:01:48 +03:00
co-authored by Claude Opus 4.8
commit a63515cfc6
366 changed files with 74773 additions and 0 deletions
@@ -0,0 +1,417 @@
@extends('admin.layouts.app')
@section('title', 'Ayarlar')
@section('page-title', 'Site Ayarları')
@section('content')
<div class="row justify-content-center">
<div class="col-xl-6 col-lg-7">
<form method="POST" action="{{ route('admin.settings.update') }}">
@csrf
{{-- Genel --}}
<div class="card mb-3">
<div class="card-header">
<i class="bi bi-globe" style="color:var(--accent-lt)"></i>
<h6>Genel Ayarlar</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">Site Adı</label>
<input type="text" name="site_name" class="form-control" value="{{ $settings['site_name']->value ?? 'Animexe' }}">
</div>
<div class="mb-3">
<label class="form-label">Site Açıklaması</label>
<textarea name="site_description" class="form-control" rows="2">{{ $settings['site_description']->value ?? '' }}</textarea>
</div>
<div>
<label class="form-label">İletişim E-postası</label>
<input type="email" name="contact_email" class="form-control" value="{{ $settings['contact_email']->value ?? '' }}">
</div>
</div>
</div>
{{-- BunnyCDN --}}
<div class="card mb-3">
<div class="card-header">
<i class="bi bi-cloud" style="color:var(--info)"></i>
<h6>BunnyCDN</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">Storage Zone Adı</label>
<input type="text" name="bunnycdn_zone" class="form-control" value="{{ $settings['bunnycdn_zone']->value ?? '' }}">
</div>
<div class="mb-3">
<label class="form-label">API Key</label>
<input type="password" name="bunnycdn_api_key" class="form-control" value="{{ $settings['bunnycdn_api_key']->value ?? '' }}">
</div>
<div class="mb-3">
<label class="form-label">Pull Zone URL</label>
<input type="text" name="bunnycdn_pull_url" class="form-control" value="{{ $settings['bunnycdn_pull_url']->value ?? '' }}" placeholder="https://animexe.b-cdn.net">
</div>
<div class="mb-3">
<label class="form-label">
Token Auth Security Key
<span style="color:var(--text2);font-size:11px"> BunnyCDN Pull Zone Security</span>
</label>
<input type="password" name="bunnycdn_token_key" class="form-control" value="{{ $settings['bunnycdn_token_key']->value ?? '' }}" placeholder="Boş = token imzalama kapalı">
</div>
<div>
<label class="form-label">Token Geçerlilik Süresi (dakika)</label>
<input type="number" name="bunnycdn_token_ttl" class="form-control" min="10" max="1440"
value="{{ $settings['bunnycdn_token_ttl']->value ?? 120 }}" style="max-width:140px">
<div class="form-text">URL bu kadar dakika sonra geçersiz olur. IDM / direkt link çalışmaz.</div>
</div>
</div>
</div>
{{-- Intro Video --}}
<div class="card mb-3">
<div class="card-header">
<i class="bi bi-play-circle" style="color:var(--warning)"></i>
<h6>Intro Video</h6>
</div>
<div class="card-body">
<div style="font-size:13px;color:var(--text2);margin-bottom:16px">
Her bölüm başında oynatılacak tanıtım videosu. Intro bittikten sonra asıl video
<strong style="color:var(--text)">belirtilen saniyeden</strong> başlar.
</div>
@if($settings['intro_video_url']->value ?? null)
<div class="mb-3 p-3 rounded" style="background:var(--info-dim);border:1px solid rgba(6,182,212,.2)">
<div style="font-size:12px;color:var(--text2);margin-bottom:6px">Mevcut intro:</div>
<code style="font-size:11.5px;color:var(--info);word-break:break-all;display:block;margin-bottom:8px">{{ $settings['intro_video_url']->value }}</code>
<video src="{{ $settings['intro_video_url']->value }}" controls style="max-width:100%;max-height:110px;border-radius:6px"></video>
</div>
@endif
<div class="mb-3">
<label class="form-label">Intro Video URL</label>
<input type="url" name="intro_video_url" class="form-control"
value="{{ $settings['intro_video_url']->value ?? '' }}"
placeholder="https://cdn.animexe.com/intro/site-intro.mp4">
<div class="form-text">Aşağıdan BunnyCDN'e yükledikten sonra burası otomatik dolar.</div>
</div>
<div class="d-flex align-items-center justify-content-between p-3 rounded mb-3" style="background:var(--surface2);border:1px solid var(--border)">
<div>
<div style="font-size:13.5px;font-weight:600;color:var(--text)">Intro Aktif</div>
<div style="font-size:12px;color:var(--text2)">Her bölüm öncesi intro oynat</div>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" name="intro_enabled" value="1" id="intro_enabled" role="switch"
{{ ($settings['intro_enabled']->value ?? '0') == '1' ? 'checked' : '' }}>
</div>
</div>
<div class="row g-3">
<div class="col-6">
<label class="form-label">Skip butonu (saniye sonra)</label>
<input type="number" name="intro_skip_after" class="form-control" min="0" max="30"
value="{{ $settings['intro_skip_after']->value ?? 5 }}">
</div>
<div class="col-6">
<label class="form-label">Ana videodan atla (saniye)</label>
<input type="number" name="main_video_skip_seconds" class="form-control" min="0" max="120"
value="{{ $settings['main_video_skip_seconds']->value ?? 10 }}">
</div>
<div class="col-6">
<label class="form-label">Rakip watermark kapat (saniye)</label>
<input type="number" name="watermark_cover_seconds" class="form-control" min="0" max="60"
value="{{ $settings['watermark_cover_seconds']->value ?? 11 }}">
<div class="form-text">0 = kapalı</div>
</div>
</div>
</div>
</div>
{{-- DeepSeek AI --}}
<div class="card mb-3">
<div class="card-header">
<i class="bi bi-stars" style="color:var(--accent-lt)"></i>
<h6>DeepSeek AI</h6>
</div>
<div class="card-body">
<div class="mb-4">
<label class="form-label">API Key</label>
<input type="password" name="deepseek_api_key" class="form-control" value="{{ $settings['deepseek_api_key']->value ?? '' }}">
</div>
<div class="d-flex flex-column gap-3">
<div class="d-flex align-items-center justify-content-between p-3 rounded" style="background:var(--surface2);border:1px solid var(--border)">
<div>
<div style="font-size:13.5px;font-weight:600;color:var(--text)">Otomatik Açıklama</div>
<div style="font-size:12px;color:var(--text2)">Bot bölüm eklerken boş açıklamayı AI ile doldurur</div>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" name="ai_auto_description" value="1" id="ai_auto_desc" role="switch"
{{ ($settings['ai_auto_description']->value ?? '0') == '1' ? 'checked' : '' }}>
</div>
</div>
<div class="d-flex align-items-center justify-content-between p-3 rounded" style="background:var(--surface2);border:1px solid var(--border)">
<div>
<div style="font-size:13.5px;font-weight:600;color:var(--text)">Otomatik SEO</div>
<div style="font-size:12px;color:var(--text2)">Bot yeni anime eklerken SEO alanlarını AI ile doldurur</div>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" name="ai_auto_seo" value="1" id="ai_auto_seo" role="switch"
{{ ($settings['ai_auto_seo']->value ?? '0') == '1' ? 'checked' : '' }}>
</div>
</div>
</div>
</div>
</div>
{{-- Premium Ücretsiz Mod --}}
<div class="card mb-3" style="border-color:rgba(255,215,0,.3)">
<div class="card-header" style="background:rgba(255,215,0,.05);border-color:rgba(255,215,0,.2)">
<i class="bi bi-stars" style="color:#ffd700"></i>
<h6 style="color:#ffd700">Premium Ücretsiz Mod</h6>
</div>
<div class="card-body">
<div style="font-size:13px;color:var(--text2);margin-bottom:16px">
Açıkken <strong style="color:var(--text)">tüm kullanıcılar</strong> premium özelliklere ücretsiz erişir.
</div>
<div class="d-flex align-items-center justify-content-between p-3 rounded" style="background:rgba(255,215,0,.06);border:1px solid rgba(255,215,0,.2)">
<div>
<div style="font-size:13.5px;font-weight:700;color:#ffd700">Herkes Premium Kullansın</div>
<div style="font-size:12px;color:var(--text2)">Kapatınca sadece aboneler erişebilir</div>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" name="premium_free_mode" value="1" id="pfm" role="switch"
{{ ($settings['premium_free_mode']->value ?? '0') == '1' ? 'checked' : '' }}>
</div>
</div>
</div>
</div>
{{-- GIF --}}
<div class="card mb-3">
<div class="card-header">
<i class="bi bi-image-alt" style="color:var(--info)"></i>
<h6>GIF Arama</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">
Giphy API Key
<span class="badge bg-success ms-1" style="font-size:10px">Önerilen</span>
</label>
<input type="text" name="giphy_api_key" class="form-control" value="{{ $settings['giphy_api_key']->value ?? '' }}" placeholder="Giphy API key...">
<div class="form-text">
Ücretsiz: <a href="https://developers.giphy.com/" target="_blank" style="color:var(--info)">developers.giphy.com</a> Create App API
</div>
</div>
<div>
<label class="form-label" style="color:var(--text2)">Tenor API Key <span style="font-size:11px">(Giphy yoksa kullanılır)</span></label>
<input type="text" name="tenor_api_key" class="form-control" value="{{ $settings['tenor_api_key']->value ?? '' }}" placeholder="Google Cloud Tenor API key...">
</div>
</div>
</div>
{{-- Yorumlar --}}
<div class="card mb-3">
<div class="card-header">
<i class="bi bi-chat-dots" style="color:var(--warning)"></i>
<h6>Yorum Ayarları</h6>
</div>
<div class="card-body d-flex flex-column gap-3">
@foreach([
['comments_enabled','Yorumlar Açık','Kullanıcılar yorum yapabilir','ce'],
['comments_require_approval','Onay Beklesin','Yorumlar yayınlanmadan önce onaylanır','cra'],
['nav_show_messages','Navbarda Mesajlar Linki','Kapatınca AI linki gösterilir','nsm'],
] as [$key,$label,$desc,$id])
<div class="d-flex align-items-center justify-content-between p-3 rounded" style="background:var(--surface2);border:1px solid var(--border)">
<div>
<div style="font-size:13.5px;font-weight:600;color:var(--text)">{{ $label }}</div>
<div style="font-size:12px;color:var(--text2)">{{ $desc }}</div>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" name="{{ $key }}" value="1" id="{{ $id }}" role="switch"
{{ ($settings[$key]->value ?? '1') == '1' ? 'checked' : '' }}>
</div>
</div>
@endforeach
</div>
</div>
{{-- Reklam (VAST) --}}
<div class="card mb-3">
<div class="card-header d-flex align-items-center gap-2">
<i class="bi bi-badge-ad-fill" style="color:#ffd60a"></i>
<h6 class="mb-0">Reklam (VAST)</h6>
</div>
<div class="card-body">
<div class="mb-3 d-flex align-items-center gap-3">
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" name="ads_enabled" value="1" id="ads_enabled" role="switch"
{{ ($settings['ads_enabled']->value ?? '0') == '1' ? 'checked' : '' }}>
<label class="form-check-label" for="ads_enabled">Reklamları Etkinleştir</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">VAST Tag URL</label>
<input type="url" name="ads_vast_url" class="form-control font-monospace"
value="{{ $settings['ads_vast_url']->value ?? '' }}"
placeholder="https://...">
<div class="form-text">Reklam ağından aldığın VAST URL'si buraya yapıştır.</div>
</div>
<div class="row g-3">
<div class="col-sm-6">
<label class="form-label">Kaç bölümde bir göster?</label>
<div class="input-group">
<input type="number" name="ads_freq_episodes" class="form-control" min="1" max="50"
value="{{ $settings['ads_freq_episodes']->value ?? 4 }}">
<span class="input-group-text">bölüm</span>
</div>
<div class="form-text">Her kullanıcı en fazla bu kadar bölümde bir reklam görür.</div>
</div>
<div class="col-sm-6">
<label class="form-label">Minimum süre (dakika)</label>
<div class="input-group">
<input type="number" name="ads_freq_minutes" class="form-control" min="1" max="1440"
value="{{ $settings['ads_freq_minutes']->value ?? 10 }}">
<span class="input-group-text">dakika</span>
</div>
<div class="form-text">Son reklamdan bu kadar dakika geçmeden tekrar göstermez.</div>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-lg w-100 mb-4">
<i class="bi bi-floppy"></i> Ayarları Kaydet
</button>
</form>
{{-- Favicon --}}
<div class="card mb-3">
<div class="card-header">
<i class="bi bi-image" style="color:var(--info)"></i>
<h6>Site Favicon</h6>
</div>
<div class="card-body">
<div style="font-size:13px;color:var(--text2);margin-bottom:14px">PNG, ICO veya SVG. Tarayıcı sekmesinde gösterilir. Maksimum 2 MB.</div>
@php $curFav = $settings['site_favicon']->value ?? '' @endphp
@if($curFav)
<div class="d-flex align-items-center gap-3 mb-3 p-3 rounded" style="background:var(--surface2);border:1px solid var(--border)">
<img src="{{ $curFav }}?v={{ time() }}" alt="favicon" style="width:32px;height:32px;object-fit:contain;border-radius:6px;background:var(--surface);padding:2px">
<code style="font-size:11.5px;color:var(--info);word-break:break-all">{{ $curFav }}</code>
</div>
@endif
<form method="POST" action="{{ route('admin.settings.favicon.upload') }}" enctype="multipart/form-data">
@csrf
<div class="d-flex gap-2 align-items-center">
<input type="file" name="favicon_file" class="form-control" accept=".png,.ico,.svg,.jpg,.jpeg" required>
<button type="submit" class="btn btn-info flex-shrink-0"><i class="bi bi-upload"></i> Yükle</button>
</div>
@error('favicon_file')<div style="font-size:12px;color:var(--danger);margin-top:6px">{{ $message }}</div>@enderror
</form>
</div>
</div>
{{-- Intro Upload --}}
<div class="card mb-5">
<div class="card-header">
<i class="bi bi-cloud-upload" style="color:var(--warning)"></i>
<h6>Intro Video Yükle (BunnyCDN)</h6>
</div>
<div class="card-body">
<div style="font-size:13px;color:var(--text2);margin-bottom:14px">
MP4 veya WebM, maksimum 200 MB. Yükleme tamamlanınca URL yukarıdaki alana otomatik kaydedilir.
</div>
<form method="POST" action="{{ route('admin.settings.intro.upload') }}" enctype="multipart/form-data" id="intro-upload-form">
@csrf
<div class="mb-3">
<label class="form-label">Video Dosyası</label>
<input type="file" name="intro_video_file" class="form-control" accept="video/mp4,video/webm" required
onchange="document.getElementById('intro-upload-btn').textContent = 'Yükle: ' + this.files[0]?.name">
</div>
<button type="submit" id="intro-upload-btn" class="btn btn-warning w-100"
onclick="this.textContent='Yükleniyor...';this.disabled=true;this.form.submit()">
<i class="bi bi-cloud-upload"></i> BunnyCDN'e Yükle
</button>
<div class="form-text mt-2">BunnyCDN'de <code>intro/site-intro.mp4</code> yoluna kaydedilir.</div>
</form>
</div>
</div>
{{-- SMTP / E-posta --}}
<div class="card mb-5">
<div class="card-header">
<i class="bi bi-envelope-fill" style="color:var(--accent2)"></i>
<h6>SMTP / E-posta Ayarları</h6>
</div>
<div class="card-body">
@if(session('mail_success'))
<div class="alert alert-success mb-3"><i class="bi bi-check-circle-fill"></i> {{ session('mail_success') }}</div>
@endif
@if(session('mail_error'))
<div class="alert alert-danger mb-3"><i class="bi bi-x-circle-fill"></i> {{ session('mail_error') }}</div>
@endif
<form method="POST" action="{{ route('admin.settings.update') }}">
@csrf @method('POST')
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">SMTP Host</label>
<input type="text" name="mail_host" class="form-control" placeholder="smtp.gmail.com" value="{{ $settings['mail_host']->value ?? '' }}">
</div>
<div class="col-md-3">
<label class="form-label">Port</label>
<input type="number" name="mail_port" class="form-control" placeholder="587" value="{{ $settings['mail_port']->value ?? '587' }}">
</div>
<div class="col-md-3">
<label class="form-label">Şifreleme</label>
<select name="mail_encryption" class="form-select">
<option value="tls" {{ ($settings['mail_encryption']->value ?? 'tls') === 'tls' ? 'selected' : '' }}>TLS</option>
<option value="ssl" {{ ($settings['mail_encryption']->value ?? '') === 'ssl' ? 'selected' : '' }}>SSL</option>
<option value="" {{ ($settings['mail_encryption']->value ?? '') === '' ? 'selected' : '' }}>Yok</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">Kullanıcı Adı</label>
<input type="text" name="mail_username" class="form-control" placeholder="ornek@gmail.com" value="{{ $settings['mail_username']->value ?? '' }}">
</div>
<div class="col-md-6">
<label class="form-label">Şifre</label>
<input type="password" name="mail_password" class="form-control" placeholder="••••••••" value="{{ $settings['mail_password']->value ?? '' }}" autocomplete="new-password">
</div>
<div class="col-md-6">
<label class="form-label">Gönderen Adı</label>
<input type="text" name="mail_from_name" class="form-control" placeholder="Animexe" value="{{ $settings['mail_from_name']->value ?? '' }}">
</div>
<div class="col-md-6">
<label class="form-label">Gönderen E-posta</label>
<input type="email" name="mail_from_address" class="form-control" placeholder="noreply@animexe.com" value="{{ $settings['mail_from_address']->value ?? '' }}">
</div>
</div>
<button type="submit" class="btn btn-primary mt-3">
<i class="bi bi-floppy-fill"></i> SMTP Ayarlarını Kaydet
</button>
</form>
<hr style="border-color:rgba(255,255,255,.08);margin:24px 0">
<form method="POST" action="{{ route('admin.settings.mail.test') }}">
@csrf
<label class="form-label fw-bold">Test E-postası Gönder</label>
<div class="input-group">
<input type="email" name="test_mail_to" class="form-control" placeholder="test@ornek.com" required>
<button type="submit" class="btn btn-outline-info">
<i class="bi bi-send-fill"></i> Gönder
</button>
</div>
<div class="form-text">Ayarları kaydettikten sonra test göndererek SMTP bağlantısını doğrulayın.</div>
</form>
</div>
</div>
</div>
</div>
@endsection