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,142 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\ActivationCode;
use App\Models\MembershipPlan;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ActivationCodeController extends Controller
{
public function index(Request $request)
{
$query = ActivationCode::with(['plan', 'usedBy', 'createdBy'])->latest();
if ($request->filled('plan_id')) {
$query->where('plan_id', $request->plan_id);
}
if ($request->filled('batch')) {
$query->where('batch', $request->batch);
}
match ($request->status) {
'used' => $query->whereNotNull('used_at'),
'unused' => $query->whereNull('used_at'),
default => null,
};
$codes = $query->paginate(50)->withQueryString();
$plans = MembershipPlan::where('is_active', true)->orderBy('sort_order')->get();
$batches = ActivationCode::select('batch')->whereNotNull('batch')
->distinct()->orderBy('batch', 'desc')->pluck('batch');
$stats = [
'total' => ActivationCode::count(),
'used' => ActivationCode::whereNotNull('used_at')->count(),
'unused' => ActivationCode::whereNull('used_at')->count(),
];
return view('admin.activation-codes.index', compact('codes', 'plans', 'stats', 'batches'));
}
public function generate(Request $request)
{
$request->validate([
'plan_id' => 'required|exists:membership_plans,id',
'quantity' => 'required|integer|min:1|max:500',
'expires_at' => 'nullable|date|after:today',
'notes' => 'nullable|string|max:500',
'batch' => 'nullable|string|max:64',
]);
$batch = $request->batch ?: 'toplu-' . now()->format('Ymd-His');
$generated = [];
DB::transaction(function () use ($request, $batch, &$generated) {
for ($i = 0; $i < $request->quantity; $i++) {
$code = ActivationCode::create([
'code' => ActivationCode::generateCode(),
'plan_id' => $request->plan_id,
'expires_at' => $request->expires_at ?: null,
'batch' => $batch,
'notes' => $request->notes,
'created_by' => auth()->id(),
]);
$generated[] = $code->code;
}
});
return back()
->with('generated_codes', $generated)
->with('success', count($generated) . ' adet aktivasyon kodu oluşturuldu. (Batch: ' . $batch . ')');
}
public function destroy(ActivationCode $activationCode)
{
if ($activationCode->isUsed()) {
return back()->withErrors(['error' => 'Kullanılmış kodlar silinemez.']);
}
$activationCode->delete();
return back()->with('success', 'Aktivasyon kodu silindi.');
}
public function destroyBatch(Request $request)
{
$request->validate(['batch' => 'required|string|max:64']);
$count = ActivationCode::where('batch', $request->batch)
->whereNull('used_at')
->delete();
return back()->with('success', $count . ' adet kullanılmamış kod silindi.');
}
public function destroySelected(Request $request)
{
$request->validate(['ids' => 'required|array|min:1', 'ids.*' => 'integer|exists:activation_codes,id']);
$count = ActivationCode::whereIn('id', $request->ids)
->whereNull('used_at')
->delete();
return back()->with('success', $count . ' adet aktivasyon kodu silindi.');
}
public function export(Request $request)
{
$query = ActivationCode::with('plan')->whereNull('used_at');
if ($request->filled('plan_id')) {
$query->where('plan_id', $request->plan_id);
}
if ($request->filled('batch')) {
$query->where('batch', $request->batch);
}
$codes = $query->orderBy('batch')->orderBy('created_at')->get();
$csv = "\xEF\xBB\xBF"; // UTF-8 BOM (Excel için)
$csv .= "Kod,Plan,Batch,Son Kullanma,Oluşturulma\n";
foreach ($codes as $code) {
$csv .= implode(',', [
$code->code,
'"' . str_replace('"', '""', $code->plan->name) . '"',
$code->batch ?? '-',
$code->expires_at?->format('d.m.Y') ?? '-',
$code->created_at->format('d.m.Y H:i'),
]) . "\n";
}
return response($csv, 200, [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="aktivasyon-kodlari-' . now()->format('Ymd') . '.csv"',
]);
}
}