Initial commit: Animexe Laravel platform
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user