<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\NewspaperController;
use App\Http\Controllers\ArchiveController;
use App\Http\Controllers\StaticPageController;
use App\Http\Controllers\Admin;
// ─── Frontend ────────────────────────────────────────────────────────────────
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('/archive', [ArchiveController::class, 'index'])->name('archive');
Route::get('/page/{slug}', [StaticPageController::class, 'show'])->name('page.show');
Route::get('/newspaper/{date}', [NewspaperController::class, 'show'])
->name('newspaper.show')
->where('date', '\d{4}-\d{2}-\d{2}');
// ─── Auth ─────────────────────────────────────────────────────────────────────
Auth::routes(['register' => false]);
// ─── Admin ────────────────────────────────────────────────────────────────────
Route::prefix('admin')->name('admin.')->middleware(['auth', 'admin'])->group(function () {
Route::get('/', [Admin\DashboardController::class, 'index'])->name('dashboard');
// Newspapers
Route::get('/newspapers', [Admin\NewspaperController::class, 'index'])->name('newspapers.index');
Route::get('/newspapers/create', [Admin\NewspaperController::class, 'create'])->name('newspapers.create');
Route::post('/newspapers', [Admin\NewspaperController::class, 'store'])->name('newspapers.store');
Route::get('/newspapers/{newspaper}/edit', [Admin\NewspaperController::class, 'edit'])->name('newspapers.edit');
Route::put('/newspapers/{newspaper}', [Admin\NewspaperController::class, 'update'])->name('newspapers.update');
Route::delete('/newspapers/{newspaper}', [Admin\NewspaperController::class, 'destroy'])->name('newspapers.destroy');
Route::get('/newspapers/{newspaper}/pages', [Admin\NewspaperController::class, 'pages'])->name('newspapers.pages');
// Pages
Route::post('/newspapers/{newspaper}/pages', [Admin\PageController::class, 'store'])->name('pages.store');
Route::put('/pages/{page}', [Admin\PageController::class, 'update'])->name('pages.update');
Route::delete('/pages/{page}', [Admin\PageController::class, 'destroy'])->name('pages.destroy');
Route::post('/pages/reorder', [Admin\PageController::class, 'reorder'])->name('pages.reorder');
// Hotspots
Route::get('/pages/{page}/hotspots', [Admin\HotspotController::class, 'index'])->name('hotspots.index');
Route::post('/pages/{page}/hotspots', [Admin\HotspotController::class, 'store'])->name('hotspots.store');
Route::put('/hotspots/{hotspot}', [Admin\HotspotController::class, 'update'])->name('hotspots.update');
Route::delete('/hotspots/{hotspot}', [Admin\HotspotController::class, 'destroy'])->name('hotspots.destroy');
// Static Pages (prefix: /site-pages — avoids conflict with newspaper /pages routes)
Route::get('/site-pages', [Admin\StaticPageController::class, 'index']) ->name('static-pages.index');
Route::get('/site-pages/create', [Admin\StaticPageController::class, 'create']) ->name('static-pages.create');
Route::post('/site-pages', [Admin\StaticPageController::class, 'store']) ->name('static-pages.store');
Route::get('/site-pages/{staticPage}/edit', [Admin\StaticPageController::class, 'edit']) ->name('static-pages.edit');
Route::put('/site-pages/{staticPage}', [Admin\StaticPageController::class, 'update']) ->name('static-pages.update');
Route::delete('/site-pages/{staticPage}', [Admin\StaticPageController::class, 'destroy'])->name('static-pages.destroy');
// Menu
Route::get('/menu', [Admin\MenuController::class, 'index']) ->name('menu.index');
Route::post('/menu', [Admin\MenuController::class, 'store']) ->name('menu.store');
Route::put('/menu/{item}', [Admin\MenuController::class, 'update']) ->name('menu.update');
Route::delete('/menu/{item}', [Admin\MenuController::class, 'destroy'])->name('menu.destroy');
Route::post('/menu/reorder', [Admin\MenuController::class, 'reorder'])->name('menu.reorder');
// Media Gallery
Route::get('/media', [Admin\MediaController::class, 'index']) ->name('media.index');
Route::post('/media', [Admin\MediaController::class, 'store']) ->name('media.store');
Route::patch('/media/{medium}', [Admin\MediaController::class, 'update']) ->name('media.update');
Route::delete('/media/{medium}', [Admin\MediaController::class, 'destroy'])->name('media.destroy');
// Settings
Route::get('/settings', [Admin\SettingController::class, 'index'])->name('settings.index');
Route::post('/settings', [Admin\SettingController::class, 'update'])->name('settings.update');
// Profile / Password
Route::get('/profile', [Admin\ProfileController::class, 'edit'])->name('profile.edit');
Route::put('/profile', [Admin\ProfileController::class, 'update'])->name('profile.update');
Route::put('/profile/password', [Admin\ProfileController::class, 'updatePassword'])->name('profile.password');
});
// ─── Storage fallback ─────────────────────────────────────────────────────────
// Serves uploaded images when the public/storage symlink is missing or not
// followed by the host (common on shared cPanel). Harmless when the symlink
// works — Apache serves the real file and never reaches this route.
Route::get('/storage/{path}', function (string $path) {
abort_if(str_contains($path, '..'), 404);
$full = storage_path('app/public/' . $path);
abort_unless(is_file($full), 404);
return response()->file($full, [
'Cache-Control' => 'public, max-age=31536000',
]);
})->where('path', '.*')->name('storage.fallback');
// ─── Sitemap ──────────────────────────────────────────────────────────────────
Route::get('/sitemap.xml', function () {
$sitemap = \Spatie\Sitemap\Sitemap::create()
->add(\Spatie\Sitemap\Tags\Url::create('/'))
->add(\Spatie\Sitemap\Tags\Url::create('/archive'));
\App\Models\Newspaper::published()
->orderByDesc('publish_date')
->each(function ($newspaper) use ($sitemap) {
$sitemap->add(
\Spatie\Sitemap\Tags\Url::create('/newspaper/' . $newspaper->publish_date->format('Y-m-d'))
->setLastModificationDate($newspaper->updated_at)
->setChangeFrequency('daily')
->setPriority(0.9)
);
});
return response($sitemap->render(), 200, ['Content-Type' => 'application/xml']);
})->name('sitemap');