set admin
This commit is contained in:
parent
97cf0f72d2
commit
d6e1fe2c5d
|
|
@ -3,36 +3,71 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Timetable;
|
||||
use App\Models\User;
|
||||
use App\Models\Notification;
|
||||
use App\Models\Timetable;
|
||||
use App\Models\StudentPortalLog;
|
||||
use Exception;
|
||||
|
||||
class AdminDashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (!session()->has('admin_id')) {
|
||||
return redirect()->route('admin.login')->with('error', 'Please login first.');
|
||||
}
|
||||
try {
|
||||
// 1. Fetch Users
|
||||
$users = User::all();
|
||||
|
||||
// 2. Fetch Notifications
|
||||
$notifications = Notification::orderBy('created_at', 'desc')->get();
|
||||
$unreadNotifications = Notification::where('is_read', false)->count();
|
||||
|
||||
$totalTimetableSlots = Timetable::count();
|
||||
// 3. Fetch Timetable Slots Count
|
||||
$totalTimetableSlots = class_exists(Timetable::class) ? Timetable::count() : 0;
|
||||
|
||||
$unreadNotifications = Notification::where('target_role', 'admin')
|
||||
->where('is_read', false)
|
||||
->count();
|
||||
// 4. Fetch Portal Logs with user eager loaded
|
||||
$portalLogs = class_exists(StudentPortalLog::class)
|
||||
? StudentPortalLog::with('user')->get()
|
||||
: [];
|
||||
|
||||
$notifications = Notification::where('target_role', 'admin')
|
||||
->orderBy('created_at', 'desc')
|
||||
->take(5)
|
||||
->get();
|
||||
|
||||
return view('admin.admindashboard', compact(
|
||||
'totalTimetableSlots',
|
||||
return view('admin.AdminDashboard', compact(
|
||||
'users',
|
||||
'notifications',
|
||||
'unreadNotifications',
|
||||
'notifications'
|
||||
'totalTimetableSlots',
|
||||
'portalLogs'
|
||||
));
|
||||
|
||||
} catch (Exception $e) {
|
||||
\Log::error('Admin Dashboard Error: ' . $e->getMessage());
|
||||
|
||||
if (config('app.debug')) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return back()->with('error', 'Something went wrong: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Notifications Store
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'message' => 'required|string',
|
||||
'type' => 'required|in:info,success,warning',
|
||||
]);
|
||||
|
||||
Notification::create([
|
||||
'title' => $request->title,
|
||||
'message' => $request->message,
|
||||
'type' => $request->type,
|
||||
'is_read' => false,
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'Notification created successfully!');
|
||||
}
|
||||
|
||||
// Mark as Read
|
||||
public function markAsRead($id)
|
||||
{
|
||||
$notification = Notification::findOrFail($id);
|
||||
|
|
@ -40,4 +75,57 @@ class AdminDashboardController extends Controller
|
|||
|
||||
return redirect()->back()->with('success', 'Notification marked as read!');
|
||||
}
|
||||
|
||||
// Update Notification
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'message' => 'required|string',
|
||||
'type' => 'required|in:info,success,warning',
|
||||
]);
|
||||
|
||||
$notification = Notification::findOrFail($id);
|
||||
$notification->update($request->only(['title', 'message', 'type']));
|
||||
|
||||
return redirect()->back()->with('success', 'Notification updated successfully!');
|
||||
}
|
||||
|
||||
// Delete Notification
|
||||
public function destroy($id)
|
||||
{
|
||||
$notification = Notification::findOrFail($id);
|
||||
$notification->delete();
|
||||
|
||||
return redirect()->back()->with('success', 'Notification deleted successfully!');
|
||||
}
|
||||
|
||||
// Send User to Portal Log
|
||||
public function sendToPortalLog($userId)
|
||||
{
|
||||
try {
|
||||
$user = User::findOrFail($userId);
|
||||
|
||||
// Check if user is already logged
|
||||
$exists = StudentPortalLog::where('user_id', $user->id)->exists();
|
||||
if ($exists) {
|
||||
return redirect()->back()->with('error', 'This user is already in Portal Logs!');
|
||||
}
|
||||
|
||||
// Create new portal log
|
||||
StudentPortalLog::create([
|
||||
'user_id' => $user->id,
|
||||
'first_name' => $user->first_name ?? '',
|
||||
'last_name' => $user->last_name ?? '',
|
||||
'email' => $user->email,
|
||||
'phone' => $user->phone ?? null,
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'User successfully added to Portal Logs!');
|
||||
} catch (Exception $e) {
|
||||
\Log::error('Send to Portal Log Error: ' . $e->getMessage());
|
||||
|
||||
return redirect()->back()->with('error', 'Failed to add user to Portal Log.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,9 +5,23 @@ namespace App\Http\Controllers;
|
|||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use App\Models\Notification;
|
||||
|
||||
class StudentPortalController extends Controller
|
||||
{
|
||||
{public function index(Request $request)
|
||||
{
|
||||
|
||||
if (!session()->has('student_id') && !session()->has('student_log_id')) {
|
||||
return redirect('/signin')->with('error', 'Please login first!');
|
||||
}
|
||||
|
||||
|
||||
$notifications = Notification::latest()->take(10)->get();
|
||||
$unreadNotifications = Notification::where('is_read', 0)->count();
|
||||
|
||||
|
||||
return view('StudentPortal', compact('notifications', 'unreadNotifications'));
|
||||
}
|
||||
|
||||
public function studentlogin(Request $request)
|
||||
{
|
||||
|
|
@ -202,4 +216,22 @@ class StudentPortalController extends Controller
|
|||
|
||||
return redirect()->back()->with('success', 'Profile updated successfully!');
|
||||
}
|
||||
|
||||
public function studentlogout(Request $request)
|
||||
{
|
||||
|
||||
$request->session()->forget(['student_id', 'student_log_id', 'student_name', 'student_email']);
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
|
||||
if ($request->wantsJson() || $request->ajax()) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Logged out successfully!'
|
||||
], 200);
|
||||
}
|
||||
|
||||
return redirect('/')->with('success', 'Logged out successfully!');
|
||||
}
|
||||
}
|
||||
|
|
@ -18,3 +18,4 @@ class Notification extends Model
|
|||
'target_role',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,24 +2,37 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class StudentPortalLog extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'student_portal_logs';
|
||||
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'phone',
|
||||
'studentid',
|
||||
'password',
|
||||
'pin',
|
||||
'status',
|
||||
];
|
||||
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'pin',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the user associated with this portal log.
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -11,12 +11,18 @@ return new class extends Migration
|
|||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('student_portal_logs', function (Blueprint $table) {
|
||||
$table->foreignId('user_id')
|
||||
->nullable()
|
||||
->after('email')
|
||||
->constrained('users')
|
||||
->onDelete('cascade');
|
||||
Schema::create('student_portal_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->nullable()->constrained('users')->onDelete('cascade');
|
||||
$table->string('first_name')->nullable();
|
||||
$table->string('last_name')->nullable();
|
||||
$table->string('email');
|
||||
$table->string('phone')->nullable();
|
||||
$table->string('studentid')->nullable();
|
||||
$table->string('password')->nullable();
|
||||
$table->string('pin')->nullable();
|
||||
$table->string('status')->default('active');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -25,9 +31,6 @@ return new class extends Migration
|
|||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('student_portal_logs', function (Blueprint $table) {
|
||||
$table->dropForeign(['user_id']);
|
||||
$table->dropColumn('user_id');
|
||||
});
|
||||
Schema::dropIfExists('student_portal_logs');
|
||||
}
|
||||
};
|
||||
|
|
@ -321,6 +321,65 @@
|
|||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-lg-5" id="notifications-section" style="width: 100%;">
|
||||
<div class="card border-0 shadow-sm rounded-3 h-100">
|
||||
<div class="card-header bg-white py-3 border-0 d-flex justify-content-between align-items-center">
|
||||
<h5 class="fw-bold mb-0 text-dark">
|
||||
<i class="fa-solid fa-bell text-danger me-2"></i>System Notifications
|
||||
</h5>
|
||||
<span class="badge bg-danger rounded-pill">{{ $unreadNotifications ?? 0 }} Unread</span>
|
||||
</div>
|
||||
<div class="card-body p-0" style="max-height: 450px; overflow-y: auto;">
|
||||
<ul class="list-group list-group-flush">
|
||||
@forelse($notifications ?? [] as $notification)
|
||||
<li class="list-group-item p-3 border-bottom {{ $notification->is_read ? 'bg-light text-muted' : 'bg-white' }}">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="me-2">
|
||||
{{-- Type Badge --}}
|
||||
@if($notification->type == 'success')
|
||||
<span class="badge bg-success mb-1">Success</span>
|
||||
@elseif($notification->type == 'warning')
|
||||
<span class="badge bg-warning text-dark mb-1">Warning</span>
|
||||
@else
|
||||
<span class="badge bg-info text-dark mb-1">Info</span>
|
||||
@endif
|
||||
|
||||
<h6 class="fw-bold mb-1 {{ $notification->is_read ? 'text-secondary' : 'text-dark' }}">
|
||||
{{ $notification->title }}
|
||||
</h6>
|
||||
<p class="mb-1 text-muted small">{{ $notification->message }}</p>
|
||||
|
||||
|
||||
<small class="text-secondary opacity-75 d-block" style="font-size: 11px;">
|
||||
<i class="fa-regular fa-clock me-1"></i>{{ $notification->created_at->diffForHumans() }}
|
||||
</small>
|
||||
</div>
|
||||
|
||||
{{-- Mark as Read Button --}}
|
||||
@if(!$notification->is_read)
|
||||
<form action="{{ route('admin.notifications.read', $notification->id) }}" method="POST">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-outline-success border-0 rounded-circle" title="Mark as Read">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="text-muted" title="Read"><i class="fa-solid fa-check-double text-secondary"></i></span>
|
||||
@endif
|
||||
</div>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item text-center py-4 text-muted">
|
||||
<i class="fa-solid fa-inbox fs-3 d-block mb-2 text-secondary"></i>
|
||||
No notifications found.
|
||||
</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Student Services Grid -->
|
||||
<div class="mb-4">
|
||||
<h5 class="fw-bold text-dark mb-3 d-flex align-items-center gap-2">
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
@section('content')
|
||||
<style>
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
.welcome-card {
|
||||
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
|
||||
color: #ffffff;
|
||||
|
|
@ -26,19 +29,37 @@
|
|||
justify-content: center;
|
||||
font-size: 24px;
|
||||
}
|
||||
/* Edit Mode Control Styles */
|
||||
.edit-only {
|
||||
display: none !important;
|
||||
}
|
||||
.is-editing .edit-only {
|
||||
display: inline-block !important;
|
||||
}
|
||||
.is-editing div.edit-only {
|
||||
display: block !important;
|
||||
}
|
||||
.is-editing flex.edit-only,
|
||||
.is-editing .d-flex.edit-only {
|
||||
display: flex !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container-fluid py-4">
|
||||
<div class="container-fluid py-4" id="dashboardWrapper">
|
||||
|
||||
<!-- Welcome Banner -->
|
||||
<!-- Welcome Banner & Pin Unlock Header -->
|
||||
<div class="welcome-card p-4 mb-4 shadow-sm d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h3 class="fw-bold mb-1"><i class="fa-solid fa-gauge me-2"></i>Welcome to Admin Dashboard</h3>
|
||||
<p class="mb-0 text-white-50">Automobile Engineering Academy System Overview</p>
|
||||
</div>
|
||||
<div class="text-end d-none d-md-block">
|
||||
<span class="badge bg-danger fs-6 px-3 py-2 rounded-pill"><i class="fa-solid fa-shield-halved me-1"></i> System Active</span>
|
||||
</div>
|
||||
<!-- <div class="text-end d-flex align-items-center gap-2"> -->
|
||||
<!-- Pin Unlock Button -->
|
||||
<!-- <button id="btnLockToggle" class="btn btn-warning text-dark fw-bold rounded-pill px-3 py-2 shadow-sm" data-bs-toggle="modal" data-bs-target="#pinAuthModal">
|
||||
<i class="fa-solid fa-lock me-1" id="lockIcon"></i> <span id="lockStatusText">Unlock Edit Mode</span>
|
||||
</button>
|
||||
<span class="badge bg-danger fs-6 px-3 py-2 rounded-pill d-none d-md-inline-block"><i class="fa-solid fa-shield-halved me-1"></i> System Active</span>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<!-- Alert Messages -->
|
||||
|
|
@ -49,9 +70,15 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
<div class="alert alert-danger alert-dismissible fade show mb-4" role="alert">
|
||||
<i class="fa-solid fa-triangle-exclamation me-2"></i>{{ session('error') }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Quick Stats Cards Row -->
|
||||
<div class="row g-4 mb-4">
|
||||
<!-- Courses Card -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card stat-card shadow-sm h-100">
|
||||
<div class="card-body d-flex align-items-center justify-content-between p-4">
|
||||
|
|
@ -71,7 +98,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Timetable Card -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card stat-card shadow-sm h-100">
|
||||
<div class="card-body d-flex align-items-center justify-content-between p-4">
|
||||
|
|
@ -91,7 +117,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Exam Results Card -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card stat-card shadow-sm h-100">
|
||||
<div class="card-body d-flex align-items-center justify-content-between p-4">
|
||||
|
|
@ -111,7 +136,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notifications Card -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card stat-card shadow-sm h-100">
|
||||
<div class="card-body d-flex align-items-center justify-content-between p-4">
|
||||
|
|
@ -132,10 +156,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content Area: Quick Navigation & Live Notifications -->
|
||||
<div class="row g-4">
|
||||
|
||||
<!-- Quick Action Shortcuts Panel -->
|
||||
<!-- Main Content Area -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-lg-7">
|
||||
<div class="card border-0 shadow-sm rounded-3 h-100">
|
||||
<div class="card-header bg-white py-3 border-0">
|
||||
|
|
@ -186,37 +208,106 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Live Notifications Feed Panel -->
|
||||
<div class="col-lg-5" id="notifications-section">
|
||||
<div class="card border-0 shadow-sm rounded-3 h-100">
|
||||
<div class="card-header bg-white py-3 border-0 d-flex justify-content-between align-items-center">
|
||||
<h5 class="fw-bold mb-0 text-dark">
|
||||
<div>
|
||||
<h5 class="fw-bold mb-0 text-dark d-inline me-2">
|
||||
<i class="fa-solid fa-bell text-danger me-2"></i>System Notifications
|
||||
</h5>
|
||||
<span class="badge bg-danger rounded-pill">{{ $unreadNotifications ?? 0 }} Unread</span>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<button class="btn btn-sm btn-primary rounded-3 edit-only" data-bs-toggle="modal" data-bs-target="#addNotificationModal">
|
||||
<i class="fa-solid fa-plus me-1"></i> Add
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body p-0" style="max-height: 450px; overflow-y: auto;">
|
||||
<ul class="list-group list-group-flush">
|
||||
@forelse($notifications ?? [] as $notification)
|
||||
<li class="list-group-item p-3 border-bottom {{ $notification->is_read ? 'bg-light' : '' }}">
|
||||
<li class="list-group-item p-3 border-bottom {{ $notification->is_read ? 'bg-light text-muted' : 'bg-white' }}">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
<h6 class="fw-bold mb-1 text-dark">{{ $notification->title }}</h6>
|
||||
<div class="me-2">
|
||||
@if($notification->type == 'success')
|
||||
<span class="badge bg-success mb-1">Success</span>
|
||||
@elseif($notification->type == 'warning')
|
||||
<span class="badge bg-warning text-dark mb-1">Warning</span>
|
||||
@else
|
||||
<span class="badge bg-info text-dark mb-1">Info</span>
|
||||
@endif
|
||||
|
||||
<h6 class="fw-bold mb-1 {{ $notification->is_read ? 'text-secondary' : 'text-dark' }}">
|
||||
{{ $notification->title }}
|
||||
</h6>
|
||||
<p class="mb-1 text-muted small">{{ $notification->message }}</p>
|
||||
<small class="text-secondary opacity-75" style="font-size: 11px;">
|
||||
<i class="fa-regular fa-clock me-1"></i>{{ $notification->created_at->diffForHumans() }}
|
||||
|
||||
<small class="text-secondary opacity-75 d-block" style="font-size: 11px;">
|
||||
<i class="fa-regular fa-clock me-1"></i>{{ $notification->created_at ? $notification->created_at->diffForHumans() : '' }}
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-1 align-items-center edit-only">
|
||||
@if(!$notification->is_read)
|
||||
<form action="{{ route('admin.notifications.read', $notification->id) }}" method="POST">
|
||||
<form action="{{ route('admin.notifications.read', $notification->id) }}" method="POST" class="d-inline">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-outline-success" title="Mark as Read">
|
||||
<button type="submit" class="btn btn-sm btn-outline-success border-0 rounded-circle" title="Mark as Read">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="text-muted px-1" title="Read"><i class="fa-solid fa-check-double text-secondary"></i></span>
|
||||
@endif
|
||||
|
||||
<button class="btn btn-sm btn-outline-primary border-0 rounded-circle" data-bs-toggle="modal" data-bs-target="#editNotificationModal{{ $notification->id }}" title="Edit">
|
||||
<i class="fa-solid fa-pen-to-square"></i>
|
||||
</button>
|
||||
|
||||
<form action="{{ route('admin.notifications.destroy', $notification->id) }}" method="POST" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this notification?');">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger border-0 rounded-circle" title="Delete">
|
||||
<i class="fa-solid fa-trash-can"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<div class="modal fade" id="editNotificationModal{{ $notification->id }}" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><i class="fa-solid fa-pen-to-square me-2"></i>Edit Notification</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form action="{{ route('admin.notifications.update', $notification->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="modal-body p-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Notification Type</label>
|
||||
<select name="type" class="form-select" required>
|
||||
<option value="info" {{ $notification->type == 'info' ? 'selected' : '' }}>Info</option>
|
||||
<option value="success" {{ $notification->type == 'success' ? 'selected' : '' }}>Success</option>
|
||||
<option value="warning" {{ $notification->type == 'warning' ? 'selected' : '' }}>Warning</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Title</label>
|
||||
<input type="text" name="title" class="form-control" value="{{ $notification->title }}" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Message</label>
|
||||
<textarea name="message" class="form-control" rows="3" required>{{ $notification->message }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary"><i class="fa-solid fa-save me-1"></i> Update</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<li class="list-group-item text-center py-4 text-muted">
|
||||
<i class="fa-solid fa-inbox fs-3 d-block mb-2 text-secondary"></i>
|
||||
|
|
@ -227,7 +318,384 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Registered Users Table -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm rounded-3">
|
||||
<div class="card-header bg-white py-3 border-0 d-flex justify-content-between align-items-center">
|
||||
<h5 class="fw-bold mb-0 text-dark">
|
||||
<i class="fa-solid fa-users text-primary me-2"></i>Registered System Users List
|
||||
</h5>
|
||||
<span class="badge bg-primary rounded-pill">{{ count($users ?? []) }} Users</span>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th class="ps-3">ID</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Phone</th>
|
||||
<th class="text-center" style="min-width: 210px;">Portal PIN</th>
|
||||
<th>Created Date</th>
|
||||
<th class="text-end pe-3 edit-only">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($users ?? [] as $user)
|
||||
<tr>
|
||||
<td class="ps-3 fw-bold">#{{ $user->id }}</td>
|
||||
<td>{{ $user->first_name }} {{ $user->last_name }}</td>
|
||||
<td>{{ $user->email }}</td>
|
||||
<td>{{ $user->phone ?? 'N/A' }}</td>
|
||||
<!-- DIRECT PIN EDIT / ADD / DELETE CONTROLS INSIDE CELL -->
|
||||
<td class="text-center">
|
||||
<div class="d-flex align-items-center justify-content-center gap-2">
|
||||
@if(!empty($log->pin) && $log->pin !== 'N/A')
|
||||
<!-- Current PIN Badge -->
|
||||
<span class="badge bg-dark font-monospace fs-6 px-3 py-2 shadow-sm">
|
||||
<i class="fa-solid fa-key text-warning me-1"></i>{{ $log->pin }}
|
||||
</span>
|
||||
|
||||
<!-- Direct Edit PIN Button -->
|
||||
<button class="btn btn-sm btn-outline-primary border-0 rounded-circle"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#editPinModal{{ $log->id }}"
|
||||
title="Edit PIN">
|
||||
<i class="fa-solid fa-pen-to-square"></i>
|
||||
</button>
|
||||
|
||||
<!-- Direct Delete PIN Form/Button -->
|
||||
<form action="{{ route('admin.portallogs.update', $log->id) }}" method="POST" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this PIN?');">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<input type="hidden" name="pin" value="">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger border-0 rounded-circle" title="Delete PIN">
|
||||
<i class="fa-solid fa-trash-can"></i>
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<!-- N/A Badge -->
|
||||
<span class="badge bg-secondary font-monospace fs-6 px-3 py-2 opacity-75">
|
||||
<i class="fa-solid fa-key text-white-50 me-1"></i>N/A
|
||||
</span>
|
||||
|
||||
<!-- Direct Add New PIN Button -->
|
||||
<button class="btn btn-sm btn-success rounded-pill px-2 py-1"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#editPinModal{{ $log->id }}">
|
||||
<i class="fa-solid fa-plus me-1"></i>Add PIN
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ $log->created_at ? $log->created_at->format('Y-m-d H:i') : 'N/A' }}</td>
|
||||
<td class="text-end pe-3 edit-only">
|
||||
<form action="{{ route('admin.portallogs.send', $user->id) }}" method="POST" class="d-inline">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-primary rounded-2">
|
||||
<i class="fa-solid fa-paper-plane me-1"></i> Send to Portal Log
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="5" class="text-center py-4 text-muted">
|
||||
<i class="fa-solid fa-user-slash fs-3 d-block mb-2 text-secondary"></i>
|
||||
No registered users found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Student Portal Active Logs Table (PIN, Add, Edit & Delete) -->
|
||||
<div class="row g-4" id="portal-logs-section">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm rounded-3">
|
||||
<div class="card-header bg-white py-3 border-0 d-flex justify-content-between align-items-center">
|
||||
<h5 class="fw-bold mb-0 text-dark">
|
||||
<i class="fa-solid fa-address-card text-success me-2"></i>Student Portal Active Logs
|
||||
</h5>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="badge bg-success rounded-pill">{{ count($portalLogs ?? []) }} Active Student Logs</span>
|
||||
<!-- Add New Portal Log Button (Edit mode එකේදී විතරක් පෙනේ) -->
|
||||
<button class="btn btn-sm btn-success rounded-3 edit-only" data-bs-toggle="modal" data-bs-target="#addPortalLogModal">
|
||||
<i class="fa-solid fa-plus me-1"></i> Add Portal Log
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th class="ps-3">Log ID</th>
|
||||
<th>User ID</th>
|
||||
<th>Student Name</th>
|
||||
<th>Email</th>
|
||||
<th>Phone</th>
|
||||
<th class="text-center">Portal PIN</th>
|
||||
<th>Created Date</th>
|
||||
<th class="text-end pe-3">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($portalLogs ?? [] as $log)
|
||||
<tr>
|
||||
<td class="ps-3 fw-bold">#LOG-{{ $log->id }}</td>
|
||||
<td>#{{ $log->user_id }}</td>
|
||||
<td>
|
||||
<div class="fw-bold text-dark">
|
||||
@if(!empty($log->first_name) || !empty($log->last_name))
|
||||
{{ trim($log->first_name . ' ' . $log->last_name) }}
|
||||
@elseif($log->user)
|
||||
{{ $log->user->name ?? trim($log->user->first_name . ' ' . $log->user->last_name) }}
|
||||
@else
|
||||
<span class="text-muted">N/A</span>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ $log->email }}</td>
|
||||
<td>{{ $log->phone ?? ($log->user->phone ?? 'N/A') }}</td>
|
||||
|
||||
<!-- PIN Column -->
|
||||
<td class="text-center">
|
||||
<span class="badge bg-dark font-monospace fs-6 px-3 py-1">
|
||||
<i class="fa-solid fa-key me-1 text-warning"></i>{{ $log->pin ?? 'N/A' }}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td>{{ $log->created_at ? $log->created_at->format('Y-m-d H:i') : 'N/A' }}</td>
|
||||
|
||||
<td class="text-end pe-3">
|
||||
<!-- Edit / Delete (Edit mode නොමැති විට Status එක පමණක් පෙනේ) -->
|
||||
<span class="badge bg-success bg-opacity-10 text-success border border-success px-3 py-2 rounded-pill edit-hidden">
|
||||
<i class="fa-solid fa-circle-check me-1"></i> Active
|
||||
</span>
|
||||
|
||||
<div class="d-flex gap-1 justify-content-end edit-only">
|
||||
<!-- Edit PIN Modal Trigger Button -->
|
||||
<button class="btn btn-sm btn-outline-primary rounded-2" data-bs-toggle="modal" data-bs-target="#editPortalLogModal{{ $log->id }}" title="Edit Student PIN / Details">
|
||||
<i class="fa-solid fa-pen-to-square me-1"></i> Edit
|
||||
</button>
|
||||
|
||||
<!-- Delete Log Button -->
|
||||
<form action="{{ route('admin.portallogs.destroy', $log->id) }}" method="POST" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this Student Portal Log?');">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger rounded-2" title="Delete Log">
|
||||
<i class="fa-solid fa-trash-can"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Edit Portal Log Modal -->
|
||||
<div class="modal fade" id="editPortalLogModal{{ $log->id }}" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><i class="fa-solid fa-key me-2"></i>Edit Portal Log & PIN</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form action="{{ route('admin.portallogs.update', $log->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="modal-body p-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Student Name</label>
|
||||
<input type="text" class="form-control" value="{{ trim($log->first_name . ' ' . $log->last_name) }}" readonly disabled>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Email Address</label>
|
||||
<input type="email" name="email" class="form-control" value="{{ $log->email }}" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Phone Number</label>
|
||||
<input type="text" name="phone" class="form-control" value="{{ $log->phone }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold text-primary"><i class="fa-solid fa-lock me-1"></i> Student Portal PIN</label>
|
||||
<input type="text" name="pin" class="form-control fw-bold fs-5 text-center text-primary" maxlength="6" value="{{ $log->pin }}" placeholder="Enter PIN (e.g. 1234)" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary"><i class="fa-solid fa-save me-1"></i> Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="text-center py-4 text-muted">
|
||||
<i class="fa-solid fa-folder-open fs-3 d-block mb-2 text-secondary"></i>
|
||||
No active student portal logs found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Add New Portal Log Modal -->
|
||||
<div class="modal fade" id="addPortalLogModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-success text-white">
|
||||
<h5 class="modal-title fw-bold"><i class="fa-solid fa-user-plus me-2"></i>Add Student Portal Access</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form action="{{ route('admin.portallogs.store') }}" method="POST">
|
||||
@csrf
|
||||
<div class="modal-body p-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Select User / Student</label>
|
||||
<select name="user_id" class="form-select" required>
|
||||
<option value="">-- Choose System User --</option>
|
||||
@foreach($users ?? [] as $u)
|
||||
<option value="{{ $u->id }}">{{ $u->first_name }} {{ $u->last_name }} ({{ $u->email }})</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Email Address</label>
|
||||
<input type="email" name="email" class="form-control" placeholder="student@example.com" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Phone Number</label>
|
||||
<input type="text" name="phone" class="form-control" placeholder="07XXXXXXXX">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold text-success"><i class="fa-solid fa-key me-1"></i> Assign Portal PIN</label>
|
||||
<input type="text" name="pin" class="form-control fw-bold fs-5 text-center text-success" maxlength="6" placeholder="Enter PIN (e.g. 5678)" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-success"><i class="fa-solid fa-plus-circle me-1"></i> Create Access</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Notification Modal -->
|
||||
<div class="modal fade" id="addNotificationModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><i class="fa-solid fa-plus-circle me-2"></i>Create New Notification</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form action="{{ route('admin.notifications.store') }}" method="POST">
|
||||
@csrf
|
||||
<div class="modal-body p-4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Notification Type</label>
|
||||
<select name="type" class="form-select" required>
|
||||
<option value="info">Info</option>
|
||||
<option value="success">Success</option>
|
||||
<option value="warning">Warning</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Title</label>
|
||||
<input type="text" name="title" class="form-control" placeholder="Enter title" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Message</label>
|
||||
<textarea name="message" class="form-control" rows="3" placeholder="Enter notification message..." required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary"><i class="fa-solid fa-paper-plane me-1"></i> Send Notification</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const ADMIN_PIN = "1234";
|
||||
|
||||
const dashboardWrapper = document.getElementById("dashboardWrapper");
|
||||
const inputPin = document.getElementById("inputPin");
|
||||
const btnSubmitPin = document.getElementById("btnSubmitPin");
|
||||
const pinErrorMessage = document.getElementById("pinErrorMessage");
|
||||
const btnLockToggle = document.getElementById("btnLockToggle");
|
||||
const lockIcon = document.getElementById("lockIcon");
|
||||
const lockStatusText = document.getElementById("lockStatusText");
|
||||
const pinModal = new bootstrap.Modal(document.getElementById('pinAuthModal'));
|
||||
|
||||
if (sessionStorage.getItem("adminEditUnlocked") === "true") {
|
||||
enableEditMode();
|
||||
}
|
||||
|
||||
function verifyPin() {
|
||||
if (inputPin.value.trim() === ADMIN_PIN) {
|
||||
sessionStorage.setItem("adminEditUnlocked", "true");
|
||||
enableEditMode();
|
||||
pinModal.hide();
|
||||
inputPin.value = "";
|
||||
pinErrorMessage.classList.add("d-none");
|
||||
} else {
|
||||
pinErrorMessage.classList.remove("d-none");
|
||||
inputPin.value = "";
|
||||
inputPin.focus();
|
||||
}
|
||||
}
|
||||
|
||||
btnSubmitPin.addEventListener("click", verifyPin);
|
||||
inputPin.addEventListener("keypress", function (e) {
|
||||
if (e.key === "Enter") {
|
||||
verifyPin();
|
||||
}
|
||||
});
|
||||
|
||||
function enableEditMode() {
|
||||
dashboardWrapper.classList.add("is-editing");
|
||||
btnLockToggle.classList.replace("btn-warning", "btn-success");
|
||||
lockIcon.classList.replace("fa-lock", "fa-lock-open");
|
||||
lockStatusText.innerText = "Edit Mode Active";
|
||||
btnLockToggle.removeAttribute("data-bs-toggle");
|
||||
btnLockToggle.removeAttribute("data-bs-target");
|
||||
}
|
||||
|
||||
btnLockToggle.addEventListener("click", function () {
|
||||
if (dashboardWrapper.classList.contains("is-editing")) {
|
||||
sessionStorage.removeItem("adminEditUnlocked");
|
||||
dashboardWrapper.classList.remove("is-editing");
|
||||
btnLockToggle.classList.replace("btn-success", "btn-warning");
|
||||
lockIcon.classList.replace("fa-lock-open", "fa-lock");
|
||||
lockStatusText.innerText = "Unlock Edit Mode";
|
||||
btnLockToggle.setAttribute("data-bs-toggle", "modal");
|
||||
btnLockToggle.setAttribute("data-bs-target", "#pinAuthModal");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script> -->
|
||||
@endsection
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<title>@yield('title', 'Admin Portal - Automobile Academic')</title>
|
||||
|
||||
<!-- Font Awesome Icons & Bootstrap 5 -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -522,28 +522,50 @@
|
|||
// Logout Logic
|
||||
function submitLogout() {
|
||||
const tokenEl = document.querySelector('meta[name="csrf-token"]');
|
||||
const csrfToken = tokenEl ? tokenEl.getAttribute('content') : '';
|
||||
|
||||
if (!csrfToken) {
|
||||
console.error('CSRF token meta tag not found!');
|
||||
alert('Security token missing. Refreshing page...');
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/studentlogout', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-CSRF-TOKEN': tokenEl ? tokenEl.getAttribute('content') : ''
|
||||
'X-CSRF-TOKEN': csrfToken
|
||||
}
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
|
||||
if (res.status === 419) {
|
||||
alert('Session expired. Page will reload.');
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Server returned status ${res.status}`);
|
||||
}
|
||||
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
if (data && data.success) {
|
||||
window.location.href = '/';
|
||||
} else {
|
||||
alert('Logout failed. Please try again.');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Error:', err);
|
||||
alert('Server side error occurred during logout.');
|
||||
console.error('Logout Error:', err);
|
||||
alert('An error occurred during logout.');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -892,7 +892,7 @@ body {
|
|||
<p class="mb-4 text-white-90 fs-5">Driving Innovation Through Education, Research & Technology</p>
|
||||
|
||||
<div class="d-flex flex-wrap justify-content-center gap-3">
|
||||
<a href="{{ Route::has('apply') ? route('apply') : '#' }}" class="btn btn-theme">
|
||||
<a href="{{ Route::has('apply') ? route('apply') : '/apply' }}" class="btn btn-theme">
|
||||
<i class="fa-solid fa-user-plus me-2"></i>Apply Now
|
||||
</a>
|
||||
<a href="/courses" class="btn btn-outline-theme">
|
||||
|
|
@ -1150,7 +1150,7 @@ body {
|
|||
<p class="mb-4 max-width-600 mx-auto">Shape your technical career through modern innovation, practical mastery, and expert guidance.</p>
|
||||
|
||||
<div class="cta-actions">
|
||||
<a href="{{ Route::has('apply') ? route('apply') : '#' }}" class="btn btn-theme" style="background: #822424; border: 2px solid #FFF;">
|
||||
<a href="{{ Route::has('apply') ? route('apply') : '/apply' }}" class="btn btn-theme" style="background: #822424; border: 2px solid #FFF;">
|
||||
<i class="fa-solid fa-user-plus me-2"></i>Apply Now
|
||||
</a>
|
||||
<a href="/courses" class="btn btn-outline-theme">
|
||||
|
|
|
|||
|
|
@ -27,16 +27,7 @@ use App\Http\Controllers\DocumentDownloadController;
|
|||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Route::get('/', [welcomeController::class, 'index'])->name('welcome');
|
||||
|
||||
Route::get('/courses', [coursesController::class, 'index'])->name('courses.index');
|
||||
Route::view('/students', 'students')->name('students');
|
||||
Route::view('/abouts', 'abouts')->name('abouts');
|
||||
|
|
@ -91,12 +82,7 @@ Route::post('/student-login', [StudentPortalController::class, 'studentlogin'])-
|
|||
Route::post('/studentlogout', [StudentPortalController::class, 'studentlogout'])->name('student.logout');
|
||||
|
||||
Route::middleware(['web'])->group(function () {
|
||||
Route::get('/student-portal', function () {
|
||||
if (!session()->has('student_id') && !session()->has('student_log_id')) {
|
||||
return redirect('/signin')->with('error', 'Please login first!');
|
||||
}
|
||||
return view('StudentPortal');
|
||||
})->name('student.portal');
|
||||
Route::get('/student-portal', [StudentPortalController::class, 'index'])->name('student.portal');
|
||||
|
||||
Route::get('/StudentProfile', [StudentPortalController::class, 'showProfile'])->name('StudentProfile');
|
||||
Route::post('/StudentProfile/update', [StudentPortalController::class, 'updateProfile'])->name('student.profile.update');
|
||||
|
|
@ -150,8 +136,11 @@ Route::post('/admin/logout', [AdminAuthController::class, 'logout'])->name('admi
|
|||
|
||||
Route::middleware(['web'])->prefix('admin')->group(function () {
|
||||
|
||||
// Admin Dashboard Routes
|
||||
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('admin.admindashboard');
|
||||
// Admin Dashboard & Notifications Routes
|
||||
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('admin.dashboard');
|
||||
Route::post('/notifications', [AdminDashboardController::class, 'store'])->name('admin.notifications.store');
|
||||
Route::put('/notifications/{id}', [AdminDashboardController::class, 'update'])->name('admin.notifications.update');
|
||||
Route::delete('/notifications/{id}', [AdminDashboardController::class, 'destroy'])->name('admin.notifications.destroy');
|
||||
Route::post('/notifications/read/{id}', [AdminDashboardController::class, 'markAsRead'])->name('admin.notifications.read');
|
||||
|
||||
// Admin Courses
|
||||
|
|
@ -176,5 +165,13 @@ Route::middleware(['web'])->prefix('admin')->group(function () {
|
|||
Route::get('/profile', [AdminProfileController::class, 'index'])->name('admin.profile');
|
||||
Route::put('/profile/update', [AdminProfileController::class, 'update'])->name('admin.profile.update');
|
||||
Route::put('/profile/password', [AdminProfileController::class, 'updatePassword'])->name('admin.profile.password');
|
||||
Route::post('/admin/portal-log/store', [AdminDashboardController::class, 'storePortalLog'])->name('admin.portal.store');
|
||||
Route::post('/admin/portal-logs/send/{userId}', [AdminDashboardController::class, 'sendToPortalLog'])->name('admin.portallogs.send');
|
||||
|
||||
|
||||
Route::prefix('admin')->name('admin.')->group(function () {
|
||||
Route::post('/portal-logs', [PortalLogController::class, 'store'])->name('portallogs.store');
|
||||
Route::put('/portal-logs/{id}', [PortalLogController::class, 'update'])->name('portallogs.update');
|
||||
Route::delete('/portal-logs/{id}', [PortalLogController::class, 'destroy'])->name('portallogs.destroy');
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue