This commit is contained in:
Saufi
2026-06-02 17:35:45 +08:00
commit 4ef99b1f81
148 changed files with 21134 additions and 0 deletions

8
routes/console.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');

114
routes/web.php Normal file
View File

@@ -0,0 +1,114 @@
<?php
use App\Http\Controllers\Admin\AuditLogController;
use App\Http\Controllers\Admin\DashboardController as AdminDashboardController;
use App\Http\Controllers\Admin\ProjectMetadataController;
use App\Http\Controllers\Admin\UserController as AdminUserController;
use App\Http\Controllers\Auth\AuthenticatedSessionController;
use App\Http\Controllers\User\AudioController;
use App\Http\Controllers\User\CollaboratorController;
use App\Http\Controllers\User\CommentController;
use App\Http\Controllers\User\DashboardController as UserDashboardController;
use App\Http\Controllers\User\ProjectController;
use App\Http\Controllers\User\TranscriptController;
use App\Http\Controllers\User\TranscriptVersionController;
use Illuminate\Support\Facades\Route;
// ============================================================
// Root redirect
// ============================================================
Route::get('/', function () {
if (auth()->check()) {
return auth()->user()->isAdmin()
? redirect()->route('admin.dashboard')
: redirect()->route('user.dashboard');
}
return redirect()->route('login');
});
// ============================================================
// Authentication
// ============================================================
Route::middleware('guest')->group(function () {
Route::get('/login', [AuthenticatedSessionController::class, 'create'])->name('login');
Route::post('/login', [AuthenticatedSessionController::class, 'store'])
->middleware('throttle:login');
});
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
->middleware('auth')
->name('logout');
// ============================================================
// Admin Routes — /admin/*
// ============================================================
Route::middleware(['auth', 'active', 'admin'])
->prefix('admin')
->name('admin.')
->group(function () {
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
// User Management
Route::prefix('users')->name('users.')->group(function () {
Route::get('/', [AdminUserController::class, 'index'])->name('index');
Route::get('/create', [AdminUserController::class, 'create'])->name('create');
Route::post('/', [AdminUserController::class, 'store'])->name('store');
Route::get('/{user}/edit', [AdminUserController::class, 'edit'])->name('edit');
Route::patch('/{user}/email', [AdminUserController::class, 'updateEmail'])->name('update-email');
Route::patch('/{user}/activate', [AdminUserController::class, 'activate'])->name('activate');
Route::patch('/{user}/deactivate', [AdminUserController::class, 'deactivate'])->name('deactivate');
Route::delete('/{user}', [AdminUserController::class, 'destroy'])->name('destroy');
});
// Project Metadata (metadata sahaja — tiada kandungan)
Route::get('/projects', [ProjectMetadataController::class, 'index'])->name('projects.index');
Route::post('/projects/{project}/transfer-owner', [ProjectMetadataController::class, 'transferOwner'])->name('projects.transfer-owner');
// Audit Logs
Route::get('/audit-logs', [AuditLogController::class, 'index'])->name('audit-logs.index');
Route::get('/audit-logs/export', [AuditLogController::class, 'export'])->name('audit-logs.export');
});
// ============================================================
// User Routes — /dashboard & /projects
// ============================================================
Route::middleware(['auth', 'active'])
->name('user.')
->group(function () {
Route::get('/dashboard', [UserDashboardController::class, 'index'])->name('dashboard');
// Projects
Route::prefix('projects')->name('projects.')->group(function () {
Route::get('/create', [ProjectController::class, 'create'])->name('create');
Route::post('/', [ProjectController::class, 'store'])->name('store')->middleware('throttle:upload');
Route::get('/{project:uuid}', [ProjectController::class, 'show'])->name('show');
Route::delete('/{project:uuid}', [ProjectController::class, 'destroy'])->name('destroy');
// Status polling (JSON)
Route::get('/{project:uuid}/status', [ProjectController::class, 'status'])->name('status');
// Retry transcription
Route::post('/{project:uuid}/retry', [ProjectController::class, 'retry'])->name('retry');
// Audio stream (melalui controller — bukan direct URL)
Route::get('/{project:uuid}/audio', [AudioController::class, 'stream'])->name('audio.stream');
// Transcript editor
Route::patch('/{project:uuid}/transcript', [TranscriptController::class, 'update'])->name('transcript.update');
Route::post('/{project:uuid}/transcript/upload', [TranscriptController::class, 'uploadExternal'])->name('transcript.upload');
// Version history
Route::get('/{project:uuid}/versions', [TranscriptVersionController::class, 'index'])->name('versions.index');
Route::post('/{project:uuid}/versions/{version}/restore', [TranscriptVersionController::class, 'restore'])->name('versions.restore');
// Comments
Route::post('/{project:uuid}/comments', [CommentController::class, 'store'])->name('comments.store');
Route::delete('/{project:uuid}/comments/{comment}', [CommentController::class, 'destroy'])->name('comments.destroy');
// Collaborators
Route::post('/{project:uuid}/collaborators', [CollaboratorController::class, 'store'])->name('collaborators.store');
Route::delete('/{project:uuid}/collaborators/{user}', [CollaboratorController::class, 'destroy'])->name('collaborators.destroy');
});
});