Proje dosyaları eklendi

This commit is contained in:
2026-08-29 15:53:53 +03:00
commit d3313400ca
440 changed files with 24827 additions and 0 deletions
@@ -0,0 +1,99 @@
<?php
namespace App\Http\Controllers;
use App\Enums\ProjectStatus;
use App\Http\Requests\StoreProjectRequest;
use App\Http\Requests\UpdateProjectRequest;
use App\Models\Project;
use App\Services\ProjectUrlNormalizer;
use Illuminate\Database\QueryException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
class ProjectController extends Controller
{
public function index(Request $request): View
{
$this->authorize('viewAny', Project::class);
$archived = $request->string('filter')->toString() === 'archived';
$projects = $request->user()->projects()
->where('status', $archived ? ProjectStatus::Archived : ProjectStatus::Active)
->withCount(['keywords' => fn ($query) => $query->active()])
->orderByDesc('id')->paginate(15)->withQueryString();
return view('projects.index', compact('projects', 'archived'));
}
public function create(): View
{
$this->authorize('create', Project::class);
return view('projects.create');
}
public function store(StoreProjectRequest $request, ProjectUrlNormalizer $normalizer): RedirectResponse
{
$normalized = $normalizer->normalize($request->string('website_url')->toString());
try {
$project = $request->user()->projects()->create([
'name' => $request->string('name')->trim()->toString(),
'domain' => $normalized->domain,
'url' => $normalized->url,
]);
} catch (QueryException $exception) {
$this->throwDuplicateValidation($exception);
}
return redirect()->route('projects.show', $project)->with('status', 'Proje oluşturuldu.');
}
public function show(Project $customerProject): View
{
$this->authorize('view', $customerProject);
$customerProject->load(['keywords' => fn ($q) => $q->active()->orderBy('phrase'), 'keywords.serpChecks' => fn ($q) => $q->where('status', 'completed')->latest('checked_at')->with(['results' => fn ($r) => $r->where('is_project_domain', true)->orderBy('position')])]);
$rows = $customerProject->keywords->map(function ($keyword) { $checks=$keyword->serpChecks->filter(fn($c)=>$c->results->isNotEmpty())->values();$current=$checks->get(0);$previous=$checks->get(1);$rank=$current?->results->min('position');$prior=$previous?->results->min('position');return ['current'=>$rank,'change'=>($rank&&$prior)?$prior-$rank:null,'checked_at'=>$current?->checked_at]; });
$measured=$rows->whereNotNull('current');
return view('projects.show', ['project'=>$customerProject,'summary'=>['keywords'=>$customerProject->keywords->count(),'last_check'=>$rows->max('checked_at'),'average'=>$measured->isNotEmpty()?round($measured->avg('current'),1):null,'top10'=>$measured->where('current','<=',10)->count(),'winners'=>$rows->where('change','>',0)->count(),'losers'=>$rows->where('change','<',0)->count()]]);
}
public function edit(Project $customerProject): View
{
$this->authorize('update', $customerProject);
return view('projects.edit', ['project' => $customerProject]);
}
public function update(UpdateProjectRequest $request, Project $customerProject, ProjectUrlNormalizer $normalizer): RedirectResponse
{
$normalized = $normalizer->normalize($request->string('website_url')->toString());
try {
$customerProject->update([
'name' => $request->string('name')->trim()->toString(),
'domain' => $normalized->domain,
'url' => $normalized->url,
]);
} catch (QueryException $exception) {
$this->throwDuplicateValidation($exception);
}
return redirect()->route('projects.show', $customerProject)->with('status', 'Proje güncellendi.');
}
public function archive(Project $customerProject): RedirectResponse
{
$this->authorize('archive', $customerProject);
$customerProject->archive();
return redirect()->route('projects.index')->with('status', 'Proje arşivlendi.');
}
public function restore(Project $customerProject): RedirectResponse
{
$this->authorize('restore', $customerProject);
$customerProject->restoreProject();
return redirect()->route('projects.show', $customerProject)->with('status', 'Proje yeniden etkinleştirildi.');
}
private function throwDuplicateValidation(QueryException $exception): never
{
if (! in_array((string) $exception->getCode(), ['23000', '19'], true)) throw $exception;
throw ValidationException::withMessages(['website_url' => 'Bu alan adı hesabınızda zaten kayıtlı.']);
}
}