diff --git a/app/Http/Controllers/Student/DashboardController.php b/app/Http/Controllers/Student/DashboardController.php new file mode 100644 index 0000000..deda557 --- /dev/null +++ b/app/Http/Controllers/Student/DashboardController.php @@ -0,0 +1,15 @@ +json($user); + } +} diff --git a/app/Http/Controllers/Student/DiscussionController.php b/app/Http/Controllers/Student/DiscussionController.php new file mode 100644 index 0000000..e5945b7 --- /dev/null +++ b/app/Http/Controllers/Student/DiscussionController.php @@ -0,0 +1,31 @@ +latest()->get(); + return response()->json(['messages' => $messages]); + } + + public function store(Request $request) + { + $request->validate([ + 'message' => 'required|string|max:1000', + ]); + + Discussion::create([ + 'user_id' => Auth::id(), + 'message' => $request->message, + ]); + + return response()->json(['message' => 'Message posted.']); + } +} diff --git a/app/Http/Controllers/Student/FeedbackController.php b/app/Http/Controllers/Student/FeedbackController.php new file mode 100644 index 0000000..531d82b --- /dev/null +++ b/app/Http/Controllers/Student/FeedbackController.php @@ -0,0 +1,15 @@ +works()->with('feedback')->get(); + return response()->json(['feedback' => $feedback]); + } +} diff --git a/app/Http/Controllers/Student/ProfileController.php b/app/Http/Controllers/Student/ProfileController.php new file mode 100644 index 0000000..9858931 --- /dev/null +++ b/app/Http/Controllers/Student/ProfileController.php @@ -0,0 +1,30 @@ +json(Auth::user()); + } + + public function update(Request $request) + { + $user = Auth::user(); + + $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email,' . $user->id, + 'phone' => 'nullable|string|max:20', + ]); + + $user->update($request->only('name', 'email', 'phone')); + + return response()->json(['message' => 'Profile updated successfully.']); + } +} diff --git a/app/Http/Controllers/Student/SubmissionController.php b/app/Http/Controllers/Student/SubmissionController.php new file mode 100644 index 0000000..f3ad1c0 --- /dev/null +++ b/app/Http/Controllers/Student/SubmissionController.php @@ -0,0 +1,34 @@ +works()->latest()->first(); + return response()->json(['work' => $work]); + } + + public function store(Request $request) + { + $request->validate([ + 'title' => 'required|string|max:255', + 'file' => 'required|file|mimes:pdf,zip|max:10240', // 10MB + ]); + + $path = $request->file('file')->store('submissions'); + + $work = $request->user()->works()->create([ + 'title' => $request->title, + 'file_path' => $path, + ]); + + return response()->json(['message' => 'Submission uploaded successfully.']); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php new file mode 100644 index 0000000..c9f5f25 --- /dev/null +++ b/app/Http/Kernel.php @@ -0,0 +1,47 @@ + [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + + 'api' => [ + 'throttle:api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + ]; + + protected \$routeMiddleware = [ + 'auth' => \App\Http\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, + 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'role' => \App\Http\Middleware\RoleMiddleware::class, // custom role middleware + ]; +} diff --git a/app/Http/Middleware/RoleMiddleware.php b/app/Http/Middleware/RoleMiddleware.php new file mode 100644 index 0000000..ab432d1 --- /dev/null +++ b/app/Http/Middleware/RoleMiddleware.php @@ -0,0 +1,19 @@ +// app/Http/Middleware/RoleMiddleware.php + +namespace App\Http\Middleware; + +use Closure; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; + +class RoleMiddleware +{ + public function handle(Request $request, Closure $next, $role) + { + if (!Auth::check() || Auth::user()->role !== $role) { + abort(403, 'Unauthorized.'); + } + + return $next($request); + } +} diff --git a/app/Models/Discussion.php b/app/Models/Discussion.php new file mode 100644 index 0000000..69486ae --- /dev/null +++ b/app/Models/Discussion.php @@ -0,0 +1,15 @@ +// app/Models/Discussion.php + +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; + +class Discussion extends Model +{ + protected $fillable = ['user_id', 'message']; + + public function user() + { + return $this->belongsTo(User::class); + } +} diff --git a/app/Models/Work.php b/app/Models/Work.php new file mode 100644 index 0000000..fd783b3 --- /dev/null +++ b/app/Models/Work.php @@ -0,0 +1,20 @@ +// app/Models/Work.php + +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; + +class Work extends Model +{ + protected $fillable = ['title', 'file_path', 'user_id']; + + public function user() + { + return $this->belongsTo(User::class); + } + + public function feedback() + { + return $this->hasOne(Feedback::class); + } +} diff --git a/resources/js/Pages/Student/Dashboard.vue b/resources/js/Pages/Student/Dashboard.vue new file mode 100644 index 0000000..f1e1362 --- /dev/null +++ b/resources/js/Pages/Student/Dashboard.vue @@ -0,0 +1,18 @@ + + + diff --git a/resources/js/Pages/Student/Discussion.vue b/resources/js/Pages/Student/Discussion.vue new file mode 100644 index 0000000..e638352 --- /dev/null +++ b/resources/js/Pages/Student/Discussion.vue @@ -0,0 +1,40 @@ + + + diff --git a/resources/js/Pages/Student/Feedback.vue b/resources/js/Pages/Student/Feedback.vue new file mode 100644 index 0000000..9122508 --- /dev/null +++ b/resources/js/Pages/Student/Feedback.vue @@ -0,0 +1,25 @@ + + + diff --git a/resources/js/Pages/Student/Profile.vue b/resources/js/Pages/Student/Profile.vue new file mode 100644 index 0000000..c8fa2ea --- /dev/null +++ b/resources/js/Pages/Student/Profile.vue @@ -0,0 +1,30 @@ + + + diff --git a/resources/js/Pages/Student/Submission.vue b/resources/js/Pages/Student/Submission.vue new file mode 100644 index 0000000..459d739 --- /dev/null +++ b/resources/js/Pages/Student/Submission.vue @@ -0,0 +1,29 @@ + + + diff --git a/routes/student.php b/routes/student.php new file mode 100644 index 0000000..18040e4 --- /dev/null +++ b/routes/student.php @@ -0,0 +1,22 @@ +prefix('student')->name('student.')->group(function () { + + // Pages rendered with Vue via Inertia + Route::get('/dashboard', fn() => Inertia::render('Student/Dashboard'))->name('dashboard'); + Route::get('/submission', fn() => Inertia::render('Student/Submission'))->name('submission'); + Route::get('/feedback', fn() => Inertia::render('Student/Feedback'))->name('feedback'); + Route::get('/profile', fn() => Inertia::render('Student/Profile'))->name('profile'); + Route::get('/discussion', fn() => Inertia::render('Student/Discussion'))->name('discussion'); + + // POST actions handled by controllers + Route::post('/submission', [SubmissionController::class, 'store'])->name('submission.store'); + Route::post('/profile', [ProfileController::class, 'update'])->name('profile.update'); + Route::post('/discussion', [DiscussionController::class, 'store'])->name('discussion.store'); +}); diff --git a/routes/web.php b/routes/web.php index 7889ff1..ef17caf 100644 --- a/routes/web.php +++ b/routes/web.php @@ -53,3 +53,4 @@ }); require __DIR__ . '/auth.php'; +require __DIR__.'/student.php';