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,230 @@
@extends('admin.layouts.app')
@section('title', 'Bölüm Ekle')
@section('page-title', 'Bölüm Ekle')
@push('styles')
<style>
.section-card { background:var(--bg2); border:1px solid var(--border); border-radius:var(--radius); margin-bottom:16px; overflow:hidden; }
.section-header { display:flex; align-items:center; gap:10px; padding:14px 20px; border-bottom:1px solid var(--border); }
.section-header h6 { font-size:13.5px; font-weight:700; color:var(--text); margin:0; }
.section-body { padding:20px; }
</style>
@endpush
@section('content')
<div class="mb-4">
<a href="{{ route('admin.episodes.index') }}" class="btn btn-secondary btn-sm">
<i class="bi bi-arrow-left"></i> Bölümlere Dön
</a>
</div>
<form method="POST" action="{{ route('admin.episodes.store') }}" enctype="multipart/form-data">
@csrf
<div class="row g-4">
<div class="col-xl-8 col-lg-7">
{{-- Bölüm Bilgileri --}}
<div class="section-card">
<div class="section-header">
<i class="bi bi-collection-play" style="color:var(--accent-lt)"></i>
<h6>Bölüm Bilgileri</h6>
</div>
<div class="section-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Anime <span style="color:var(--danger)">*</span></label>
<select name="anime_id" class="form-select" id="animeSelect" required onchange="loadSeasons(this.value)">
<option value=""> Anime Seç </option>
@foreach($animes as $anime)
<option value="{{ $anime->id }}"
{{ (request('anime_id')==$anime->id || old('anime_id')==$anime->id) ? 'selected' : '' }}>
{{ $anime->title }}
</option>
@endforeach
</select>
</div>
<div class="col-md-3">
<label class="form-label">Sezon <span style="color:var(--danger)">*</span></label>
<select name="season_id" class="form-select" id="seasonSelect" required>
<option value=""> Sezon Seç </option>
@foreach($seasons as $season)
<option value="{{ $season->id }}"
{{ (request('season_id')==$season->id || old('season_id')==$season->id) ? 'selected' : '' }}>
{{ $season->season_number }}. Sezon
</option>
@endforeach
</select>
</div>
<div class="col-md-3">
<label class="form-label">Bölüm No <span style="color:var(--danger)">*</span></label>
<input type="number" name="episode_number" class="form-control"
value="{{ old('episode_number', 1) }}" min="1" required>
</div>
<div class="col-md-8">
<label class="form-label">Başlık <span style="color:var(--text2);font-size:11px">(opsiyonel)</span></label>
<input type="text" name="title" class="form-control"
value="{{ old('title') }}" placeholder="Bölüm adı...">
</div>
<div class="col-md-4">
<label class="form-label">Süre (saniye)</label>
<input type="number" name="duration" class="form-control"
value="{{ old('duration') }}" placeholder="1440">
</div>
<div class="col-12">
<label class="form-label">Açıklama</label>
<textarea name="description" class="form-control" rows="3"
placeholder="Bölüm özeti...">{{ old('description') }}</textarea>
</div>
</div>
</div>
</div>
{{-- Video Kaynağı --}}
<div class="section-card">
<div class="section-header">
<i class="bi bi-play-btn" style="color:var(--info)"></i>
<h6>Video Kaynağı</h6>
</div>
<div class="section-body">
<div class="mb-4">
<label class="form-label">Kaynak Tipi</label>
<div class="d-flex gap-2 flex-wrap">
@foreach(['bunnycdn'=>'BunnyCDN','external'=>'External URL','direct'=>'Direct M3U8'] as $val => $lbl)
<label style="display:flex;align-items:center;gap:7px;padding:8px 14px;border-radius:8px;border:1px solid var(--border2);cursor:pointer;transition:all .12s;font-size:13px;font-weight:600;color:var(--text2)" class="source-opt">
<input type="radio" name="source" value="{{ $val }}"
{{ old('source','bunnycdn')===$val?'checked':'' }}
style="accent-color:var(--accent)" onchange="toggleSource('{{ $val }}')">
{{ $lbl }}
</label>
@endforeach
</div>
</div>
<div id="sourceUrlField">
<div class="row g-3">
<div class="col-12">
<label class="form-label">M3U8 / Video URL</label>
<input type="text" name="source_url" class="form-control"
value="{{ old('source_url') }}"
placeholder="https://f.aniziumserver.sbs/.../master.m3u8">
</div>
<div class="col-md-6">
<label class="form-label">Video URL (Pull CDN)</label>
<input type="text" name="video_url" class="form-control" value="{{ old('video_url') }}">
</div>
<div class="col-md-6">
<label class="form-label">M3U8 URL</label>
<input type="text" name="m3u8_url" class="form-control" value="{{ old('m3u8_url') }}">
</div>
</div>
</div>
</div>
</div>
{{-- İzinler --}}
@if(isset($permissions) && count($permissions))
<div class="section-card">
<div class="section-header">
<i class="bi bi-shield-lock" style="color:var(--success)"></i>
<h6>İzin Ayarları</h6>
<span style="font-size:12px;color:var(--text2)"> Boş bırakınca anime/global ayarları geçerli olur</span>
</div>
<div class="section-body p-0">
@foreach($permissions as $perm)
<div class="perm-row">
<div>
<div class="perm-name">{{ $perm->label }}</div>
</div>
<div class="perm-toggle">
<input type="radio" name="permissions[{{ $perm->key }}]"
id="ep_{{ $perm->key }}_free" value="free" checked>
<label for="ep_{{ $perm->key }}_free" class="free">Ücretsiz</label>
<input type="radio" name="permissions[{{ $perm->key }}]"
id="ep_{{ $perm->key }}_prem" value="premium">
<label for="ep_{{ $perm->key }}_prem" class="premium">Premium</label>
</div>
</div>
@endforeach
</div>
</div>
@endif
</div>
{{-- Sağ --}}
<div class="col-xl-4 col-lg-5">
{{-- Thumbnail --}}
<div class="section-card">
<div class="section-header">
<i class="bi bi-image" style="color:var(--info)"></i>
<h6>Thumbnail</h6>
</div>
<div class="section-body">
<input type="file" name="thumbnail" class="form-control" accept="image/*">
<div class="form-text">Önerilen: 1280×720px</div>
</div>
</div>
{{-- Yayın --}}
<div class="section-card">
<div class="section-header">
<i class="bi bi-toggle-on" style="color:var(--success)"></i>
<h6>Yayın Ayarı</h6>
</div>
<div class="section-body">
<div class="d-flex align-items-center justify-content-between">
<div>
<div style="font-size:13.5px;font-weight:600;color:var(--text)">Yayınla</div>
<div style="font-size:12px;color:var(--text2)">Kullanıcılara görünür yap</div>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" name="is_published"
value="1" id="is_published" role="switch">
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary w-100 btn-lg">
<i class="bi bi-plus-circle"></i> Bölüm Ekle
</button>
<a href="{{ route('admin.episodes.index') }}" class="btn btn-secondary w-100 mt-2">İptal</a>
</div>
</div>
</form>
@endsection
@push('scripts')
<script>
function loadSeasons(animeId) {
if (!animeId) return;
fetch('/admin/animes/' + animeId + '/seasons-json')
.then(r => r.json())
.then(data => {
const sel = document.getElementById('seasonSelect');
sel.innerHTML = '<option value="">— Sezon Seç —</option>';
data.forEach(s => {
sel.innerHTML += `<option value="${s.id}">${s.season_number}. Sezon</option>`;
});
});
}
function toggleSource(val) {
// Seçili source opt'u vurgula
document.querySelectorAll('.source-opt').forEach(el => {
const inp = el.querySelector('input');
el.style.borderColor = inp.value === val ? 'var(--accent)' : 'var(--border2)';
el.style.background = inp.value === val ? 'var(--accent-dim)' : '';
el.style.color = inp.value === val ? 'var(--accent-lt)' : 'var(--text2)';
});
}
// Init on load
document.addEventListener('DOMContentLoaded', () => {
const checked = document.querySelector('[name="source"]:checked');
if (checked) toggleSource(checked.value);
});
</script>
@endpush