This commit is contained in:
KaviSaparamadu 2026-08-10 11:04:54 +05:30
parent 8d357652e7
commit 6f1ef07048
7 changed files with 1898 additions and 704 deletions

View File

@ -80,14 +80,126 @@ class StudentPortalController extends Controller
return view('StudentProfile', compact('student')); return view('StudentProfile', compact('student'));
} }
public function studentlogout(Request $request) public function updateProfile(Request $request)
{ {
$request->session()->forget(['student_id', 'student_log_id', 'student_name']); $log_id = $request->session()->get('student_log_id');
$request->session()->invalidate(); $student_code = $request->session()->get('student_id');
$request->session()->regenerateToken();
return response()->json(['success' => true]); if (!$log_id && !$student_code) {
return redirect('/')->with('error', 'Please login first!');
} }
$request->validate([
'full_name' => 'required|string|max:255',
'nic_passport' => 'nullable|string|max:100',
'date_of_birth' => 'nullable|date',
'gender' => 'nullable|string|max:20',
'email' => 'required|email|max:255',
'phone' => 'nullable|string|max:50',
'qualification' => 'nullable|string|max:255',
'institute' => 'nullable|string|max:255',
'year_completed' => 'nullable|string|max:50',
'profile_image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:5120',
]);
$student = DB::table('student_details')
->where(function ($query) use ($log_id, $student_code) {
if ($log_id) {
$query->where('student_portal_log_id', $log_id);
}
if ($student_code) {
if ($log_id) {
$query->orWhere('student_id', $student_code);
} else {
$query->where('student_id', $student_code);
}
}
})
->first();
if (!$student) {
return redirect()->back()->with('error', 'Student profile record not found!');
}
$updateData = [
'full_name' => $request->full_name,
'nic_passport' => $request->nic_passport,
'date_of_birth' => $request->date_of_birth,
'gender' => $request->gender,
'email' => $request->email,
'phone' => $request->phone,
'qualification' => $request->qualification,
'institute' => $request->institute,
'year_completed' => $request->year_completed,
'updated_at' => now(),
];
// 1. Check if user requested to REMOVE image
if ($request->input('remove_profile_image') == '1') {
if (!empty($student->image) && file_exists(public_path($student->image))) {
@unlink(public_path($student->image));
}
$updateData['image'] = null;
}
// 2. Check if user provided CROPPED Base64 image
elseif (!empty($request->input('cropped_image_data'))) {
$base64Image = $request->input('cropped_image_data');
if (preg_match('/^data:image\/(\w+);base64,/', $base64Image, $type)) {
$data = substr($base64Image, strpos($base64Image, ',') + 1);
$type = strtolower($type[1]);
if (in_array($type, ['jpg', 'jpeg', 'gif', 'png'])) {
$data = base64_decode($data);
if ($data !== false) {
$filename = time() . '_' . uniqid() . '.png';
$destinationPath = public_path('uploads/student_images');
if (!file_exists($destinationPath)) {
mkdir($destinationPath, 0777, true);
}
file_put_contents($destinationPath . '/' . $filename, $data);
// Delete old image if existed
if (!empty($student->image) && file_exists(public_path($student->image))) {
@unlink(public_path($student->image));
}
$updateData['image'] = 'uploads/student_images/' . $filename;
}
}
}
}
// 3. Fallback to normal direct file upload
elseif ($request->hasFile('profile_image')) {
$file = $request->file('profile_image');
$filename = time() . '_' . uniqid() . '.' . $file->getClientOriginalExtension();
$destinationPath = public_path('uploads/student_images');
if (!file_exists($destinationPath)) {
mkdir($destinationPath, 0777, true);
}
$file->move($destinationPath, $filename);
if (!empty($student->image) && file_exists(public_path($student->image))) {
@unlink(public_path($student->image));
}
$updateData['image'] = 'uploads/student_images/' . $filename;
}
DB::table('student_details')
->where('id', $student->id)
->update($updateData);
if (!empty($student->student_portal_log_id)) {
DB::table('student_portal_logs')
->where('id', $student->student_portal_log_id)
->update([
'email' => $request->email,
'updated_at' => now(),
]);
}
$request->session()->put('student_name', $request->full_name);
$request->session()->put('student_email', $request->email);
return redirect()->back()->with('success', 'Profile updated successfully!');
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,344 +1,493 @@
@extends('layouts.studentportalnav') @extends('layouts.studentportalnav')
@section('title', 'Dashboard') @section('title', 'Student Dashboard')
@section('content') @section('content')
<style> <style>
:root { :root {
--theme-navy: #2D355B; /* Primary Dark Navy */ --theme-navy: #1E233E;
--theme-footer-navy: #1F2541; /* Darker Navy */ --theme-navy-dark: #15182C;
--theme-red: #822424; /* Primary Accent Red */ --theme-red: #822424;
--theme-red-hover: #df2c3e; /* Red Hover State */ --theme-red-hover: #df2c3e;
--theme-yellow: #FFEA85; /* Accent Gold/Yellow */ --theme-yellow: #FFEA85;
--theme-bg: #F6F6F6; /* Page Background */ --theme-bg: #F4F6F9;
--text-dark: #333333; --text-dark: #1E293B;
} }
body { /* Welcome Banner */
background-color: var(--theme-bg); .welcome-banner {
color: var(--text-dark); background: linear-gradient(135deg, #1E233E 0%, #2A1F3B 50%, #4A1A24 100%);
position: relative;
overflow: hidden;
border: none;
box-shadow: 0 10px 30px rgba(30, 35, 62, 0.15);
} }
/* Header */ .welcome-banner::before {
.dashboard-header { content: '';
display: flex; position: absolute;
justify-content: space-between; top: -50%;
align-items: center; right: -10%;
margin-bottom: 30px; width: 350px;
padding-bottom: 15px; height: 350px;
border-bottom: 2px solid #e2e8f0; background: radial-gradient(circle, rgba(255, 234, 133, 0.12) 0%, rgba(255, 234, 133, 0) 70%);
}
.dashboard-header h2 {
font-weight: 700;
color: var(--theme-navy);
margin-bottom: 5px;
}
.dashboard-header p {
color: #6c757d;
margin: 0;
font-size: 0.95rem;
}
.avatar {
width: 55px;
height: 55px;
border-radius: 50%; border-radius: 50%;
background: var(--theme-navy); pointer-events: none;
color: var(--theme-yellow); }
.user-avatar-badge {
box-shadow: 0 4px 15px rgba(0,0,0,0.15);
}
.avatar-circle {
width: 52px;
height: 52px;
border-radius: 14px;
background: linear-gradient(135deg, #FFEA85 0%, #F59E0B 100%);
color: #1E233E;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-weight: bold; font-weight: 800;
font-size: 20px; font-size: 22px;
box-shadow: 0 4px 10px rgba(0,0,0,0.1); box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);
} }
/* Statistic Cards */ /* Stat Cards Modern */
.stat-card { .stat-card-modern {
background: #ffffff; background: #ffffff;
border-radius: 12px; border-radius: 16px;
padding: 24px; padding: 24px;
box-shadow: 0 4px 12px rgba(0,0,0,0.05); border: 1px solid #E2E8F0;
transition: all 0.3s ease; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.03);
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
position: relative;
height: 100%; height: 100%;
border: 1px solid #e2e8f0; display: flex;
flex-direction: column;
justify-content: space-between;
} }
.stat-card:hover { .stat-card-modern:hover {
transform: translateY(-5px); transform: translateY(-5px);
box-shadow: 0 8px 20px rgba(45, 53, 91, 0.12); box-shadow: 0 12px 28px rgba(30, 35, 62, 0.1);
border-color: var(--theme-navy); border-color: rgba(30, 35, 62, 0.2);
} }
.stat-icon { .stat-icon-wrapper {
width: 55px; width: 52px;
height: 55px; height: 52px;
border-radius: 10px; border-radius: 14px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: #ffffff; color: #ffffff;
font-size: 22px; font-size: 22px;
margin-bottom: 16px; box-shadow: 0 6px 14px rgba(0,0,0,0.12);
} }
.stat-card h3 { .stat-number {
font-weight: 700; font-size: 2.1rem;
color: var(--theme-navy); font-weight: 800;
margin-bottom: 4px; color: #0F172A;
line-height: 1.2;
margin-bottom: 2px;
letter-spacing: -0.5px;
} }
.stat-card p { .stat-label {
color: #6c757d; color: #64748B;
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 600; font-weight: 600;
margin: 0;
} }
/* Services */ /* Section Title Accent */
.section-title { .title-accent {
font-size: 22px; width: 6px;
font-weight: 700; height: 24px;
color: var(--theme-navy); background: linear-gradient(180deg, var(--theme-red) 0%, var(--theme-red-hover) 100%);
margin: 40px 0 20px; border-radius: 4px;
display: inline-block;
}
/* Modern Service Card */
.service-card-modern {
background: #ffffff;
border-radius: 16px;
padding: 28px 24px;
border: 1px solid #E2E8F0;
box-shadow: 0 4px 16px rgba(0,0,0,0.03);
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
text-decoration: none !important;
}
.service-card-modern:hover {
transform: translateY(-6px);
box-shadow: 0 16px 32px rgba(130, 36, 36, 0.1);
border-color: rgba(130, 36, 36, 0.3);
}
.service-icon-box {
width: 56px;
height: 56px;
border-radius: 14px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; justify-content: center;
} font-size: 24px;
margin-bottom: 20px;
.section-title::before { background: rgba(130, 36, 36, 0.08);
content: '';
display: inline-block;
width: 5px;
height: 24px;
background-color: var(--theme-red);
border-radius: 2px;
}
.service-card {
background: #ffffff;
border-radius: 12px;
padding: 30px 20px;
text-align: center;
transition: all 0.3s ease;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
height: 100%;
border: 1px solid #e2e8f0;
}
.service-card:hover {
transform: translateY(-6px);
box-shadow: 0 8px 22px rgba(0,0,0,0.1);
border-color: var(--theme-red);
}
.service-card i {
font-size: 40px;
color: var(--theme-red); color: var(--theme-red);
margin-bottom: 16px; transition: all 0.3s ease;
transition: transform 0.3s ease, color 0.3s ease;
} }
.service-card:hover i { .service-card-modern:hover .service-icon-box {
transform: scale(1.1); background: var(--theme-red);
color: #ffffff;
transform: scale(1.08);
box-shadow: 0 6px 16px rgba(130, 36, 36, 0.3);
}
.service-card-modern h5 {
font-weight: 700;
color: #0F172A;
font-size: 1.1rem;
margin-bottom: 8px;
}
.service-card-modern p {
color: #64748B;
font-size: 0.88rem;
margin: 0;
line-height: 1.55;
}
.action-link {
font-weight: 700;
font-size: 0.85rem;
color: var(--theme-red);
display: inline-flex;
align-items: center;
gap: 6px;
margin-top: 18px;
transition: gap 0.2s ease, color 0.2s ease;
}
.service-card-modern:hover .action-link {
gap: 10px;
color: var(--theme-red-hover); color: var(--theme-red-hover);
} }
.service-card h5 { /* Document Card */
font-weight: 700; .doc-card {
color: var(--theme-navy); background: #ffffff;
margin-bottom: 10px; border-radius: 16px;
padding: 24px 20px;
border: 1px solid #E2E8F0;
box-shadow: 0 4px 16px rgba(0,0,0,0.03);
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
height: 100%;
} }
.service-card p { .doc-card:hover {
color: #6c757d; transform: translateY(-5px);
font-size: 13.5px; box-shadow: 0 12px 24px rgba(0,0,0,0.08);
margin: 0; border-color: #CBD5E1;
line-height: 1.5; }
.doc-icon-badge {
width: 52px;
height: 52px;
border-radius: 14px;
background: #FEF2F2;
color: #DC2626;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
margin: 0 auto 16px;
} }
</style> </style>
<div class="container-fluid"> <div class="portal-content-container">
<!-- Dashboard Header --> <!-- Welcome Hero Banner -->
<div class="dashboard-header"> <div class="welcome-banner card rounded-4 mb-4">
<div> <div class="card-body p-4 p-lg-5 d-flex align-items-center justify-content-between flex-wrap gap-3 position-relative" style="z-index: 1;">
<h2>Welcome Back, {{ Auth::check() ? Auth::user()->first_name : 'Student' }}!</h2> <div>
<p>Manage your academic activities and course updates from your dashboard.</p> <div class="d-flex align-items-center gap-2 mb-2 flex-wrap">
</div> <span class="badge bg-success bg-opacity-20 text-success border border-success border-opacity-20 px-3 py-2 rounded-pill fw-semibold" style="font-size: 0.78rem;">
<i class="fa-solid fa-circle me-1" style="font-size: 7px; vertical-align: middle;"></i> Active Academic Year 2026
@if(Auth::check()) </span>
<div class="avatar" title="{{ Auth::user()->first_name }}"> <span class="text-white-50 small"><i class="fa-regular fa-calendar me-1"></i> {{ date('l, F j, Y') }}</span>
{{ strtoupper(substr(Auth::user()->first_name, 0, 1)) }} </div>
<h2 class="fw-bold text-white mb-2" style="letter-spacing: -0.5px;">
Welcome Back, {{ Auth::check() ? Auth::user()->first_name : 'Student' }}! 👋
</h2>
<p class="text-white-50 mb-0 fs-6" style="max-width: 580px;">
Manage your academic activities, course schedules, and exam performance directly from your portal dashboard.
</p>
</div> </div>
@endif
@if(Auth::check())
<div class="user-avatar-badge d-flex align-items-center gap-3 bg-white bg-opacity-10 p-3 rounded-4 backdrop-blur border border-white border-opacity-10">
<div class="avatar-circle">
{{ strtoupper(substr(Auth::user()->first_name, 0, 1)) }}
</div>
<div class="text-white d-none d-sm-block">
<div class="fw-bold fs-6">{{ Auth::user()->first_name }} {{ Auth::user()->last_name }}</div>
<div class="small fst-italic text-warning opacity-75" style="font-size: 11px;">{{ Auth::user()->email }}</div>
</div>
</div>
@endif
</div>
</div> </div>
<!-- Statistics Cards --> <!-- Key Performance Metrics (Stat Cards) -->
<div class="row g-4"> <div class="row g-3 g-lg-4 mb-4">
<div class="col-lg-3 col-md-6"> <div class="col-xl-3 col-md-6">
<div class="stat-card"> <div class="stat-card-modern">
<div class="stat-icon" style="background: var(--theme-navy);"> <div class="d-flex align-items-center justify-content-between mb-3">
<i class="fa-solid fa-book"></i> <div class="stat-icon-wrapper" style="background: linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%);">
<i class="fa-solid fa-book-open-reader"></i>
</div>
<span class="badge bg-primary-subtle text-primary border border-primary-subtle px-2.5 py-1.5 rounded-pill fw-semibold" style="font-size: 0.75rem;">
<i class="fa-solid fa-circle-check me-1"></i> Active
</span>
</div>
<div>
<div class="stat-number">6</div>
<div class="stat-label">Enrolled Courses</div>
</div> </div>
<h3>6</h3>
<p>Enrolled Courses</p>
</div> </div>
</div> </div>
<div class="col-lg-3 col-md-6"> <div class="col-xl-3 col-md-6">
<div class="stat-card"> <div class="stat-card-modern">
<div class="stat-icon" style="background: #0d9488;"> <div class="d-flex align-items-center justify-content-between mb-3">
<i class="fa-solid fa-file-lines"></i> <div class="stat-icon-wrapper" style="background: linear-gradient(135deg, #10B981 0%, #047857 100%);">
<i class="fa-solid fa-file-signature"></i>
</div>
<span class="badge bg-warning-subtle text-warning border border-warning-subtle px-2.5 py-1.5 rounded-pill fw-semibold" style="font-size: 0.75rem;">
<i class="fa-solid fa-clock me-1"></i> Pending
</span>
</div>
<div>
<div class="stat-number">3</div>
<div class="stat-label">Assignments Due</div>
</div> </div>
<h3>3</h3>
<p>Assignments</p>
</div> </div>
</div> </div>
<div class="col-lg-3 col-md-6"> <div class="col-xl-3 col-md-6">
<div class="stat-card"> <div class="stat-card-modern">
<div class="stat-icon" style="background: #d97706;"> <div class="d-flex align-items-center justify-content-between mb-3">
<i class="fa-solid fa-chart-column"></i> <div class="stat-icon-wrapper" style="background: linear-gradient(135deg, #F59E0B 0%, #B45309 100%);">
<i class="fa-solid fa-chart-line"></i>
</div>
<span class="badge bg-success-subtle text-success border border-success-subtle px-2.5 py-1.5 rounded-pill fw-semibold" style="font-size: 0.75rem;">
<i class="fa-solid fa-arrow-trend-up me-1"></i> Grade B+
</span>
</div>
<div>
<div class="stat-number">78%</div>
<div class="stat-label">Average Result</div>
</div> </div>
<h3>78%</h3>
<p>Average Result</p>
</div> </div>
</div> </div>
<div class="col-lg-3 col-md-6"> <div class="col-xl-3 col-md-6">
<div class="stat-card"> <div class="stat-card-modern">
<div class="stat-icon" style="background: var(--theme-red);"> <div class="d-flex align-items-center justify-content-between mb-3">
<i class="fa-solid fa-bell"></i> <div class="stat-icon-wrapper" style="background: linear-gradient(135deg, #EF4444 0%, #B91C1C 100%);">
<i class="fa-solid fa-bell"></i>
</div>
<span class="badge bg-danger-subtle text-danger border border-danger-subtle px-2.5 py-1.5 rounded-pill fw-semibold" style="font-size: 0.75rem;">
<i class="fa-solid fa-bullhorn me-1"></i> Upcoming
</span>
</div>
<div>
<div class="stat-number">2</div>
<div class="stat-label">Exam Notices</div>
</div> </div>
<h3>2</h3>
<p>Exam Notices</p>
</div> </div>
</div> </div>
</div> </div>
<!-- Student Services Section --> <!-- Student Services Grid -->
<div class="section-title"> <div class="mb-4">
Student Services <h5 class="fw-bold text-dark mb-3 d-flex align-items-center gap-2">
<span class="title-accent"></span> Student Services & Quick Actions
</h5>
<div class="row g-3 g-lg-4">
<div class="col-lg-4 col-md-6">
<a href="/mycourse" class="service-card-modern">
<div>
<div class="service-icon-box">
<i class="fa-solid fa-book-bookmark"></i>
</div>
<h5>My Courses</h5>
<p>Access all registered learning modules, video lectures, and syllabus materials.</p>
</div>
<div class="action-link">
Explore Courses <i class="fa-solid fa-arrow-right"></i>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6">
<a href="/timetable" class="service-card-modern">
<div>
<div class="service-icon-box">
<i class="fa-solid fa-calendar-days"></i>
</div>
<h5>Class Timetable</h5>
<p>Check your weekly lecture schedules, classroom locations, and timing updates.</p>
</div>
<div class="action-link">
View Schedule <i class="fa-solid fa-arrow-right"></i>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6">
<a href="/results" class="service-card-modern">
<div>
<div class="service-icon-box">
<i class="fa-solid fa-award"></i>
</div>
<h5>Exam Results</h5>
<p>Review semester examination grades, transcript records, and academic progress.</p>
</div>
<div class="action-link">
View Marks <i class="fa-solid fa-arrow-right"></i>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6">
<a href="/Studentguidelines" class="service-card-modern">
<div>
<div class="service-icon-box">
<i class="fa-solid fa-book-open"></i>
</div>
<h5>Student Guidelines</h5>
<p>Read campus rules, academic regulations, safety procedures, and code of conduct.</p>
</div>
<div class="action-link">
Read Guidelines <i class="fa-solid fa-arrow-right"></i>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6">
<a href="/Feedback&Complain" class="service-card-modern">
<div>
<div class="service-icon-box">
<i class="fa-solid fa-comments"></i>
</div>
<h5>Feedback & Complaints</h5>
<p>Submit inquiries, suggestions, or complaints directly to the student support team.</p>
</div>
<div class="action-link">
Submit Inquiry <i class="fa-solid fa-arrow-right"></i>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6">
<a href="/StudentProfile" class="service-card-modern">
<div>
<div class="service-icon-box">
<i class="fa-solid fa-id-card"></i>
</div>
<h5>Student Profile</h5>
<p>View and update your personal contact details, credentials, and security PIN.</p>
</div>
<div class="action-link">
Manage Profile <i class="fa-solid fa-arrow-right"></i>
</div>
</a>
</div>
</div>
</div> </div>
<div class="row g-4"> <!-- Official Document Downloads Section -->
<div class="mb-5">
<h5 class="fw-bold text-dark mb-3 d-flex align-items-center gap-2">
<span class="title-accent"></span> Official Academic Documents (PDF)
</h5>
<div class="col-lg-4 col-md-6"> <div class="row g-3 g-lg-4">
<a href="/mycourse" class="text-decoration-none"> <div class="col-xl-3 col-md-6">
<div class="service-card"> <a href="{{ route('student.download.calendar') }}" class="text-decoration-none" target="_blank">
<i class="fa-solid fa-book"></i> <div class="doc-card text-center">
<h5>My Courses</h5> <div class="doc-icon-badge">
<p>Access all learning materials, lectures, and course content.</p> <i class="fa-solid fa-file-pdf"></i>
</div> </div>
</a> <h6 class="fw-bold text-dark mb-1">Academic Calendar</h6>
</div> <small class="text-muted d-block mb-3">Semester dates & holidays</small>
<span class="btn btn-sm btn-outline-danger rounded-pill px-3 fw-semibold">
<i class="fa-solid fa-download me-1"></i> Download PDF
</span>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6"> <div class="col-xl-3 col-md-6">
<a href="/timetable" class="text-decoration-none"> <a href="{{ route('student.download.handbook') }}" class="text-decoration-none" target="_blank">
<div class="service-card"> <div class="doc-card text-center">
<i class="fa-solid fa-calendar-days"></i> <div class="doc-icon-badge">
<h5>Class Timetable</h5> <i class="fa-solid fa-file-pdf"></i>
<p>View your weekly lecture schedule and upcoming classes.</p> </div>
</div> <h6 class="fw-bold text-dark mb-1">Student Handbook</h6>
</a> <small class="text-muted d-block mb-3">Campus rules & policies</small>
</div> <span class="btn btn-sm btn-outline-danger rounded-pill px-3 fw-semibold">
<i class="fa-solid fa-download me-1"></i> Download PDF
</span>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6"> <div class="col-xl-3 col-md-6">
<a href="/results" class="text-decoration-none"> <a href="{{ route('student.download.examcode') }}" class="text-decoration-none" target="_blank">
<div class="service-card"> <div class="doc-card text-center">
<i class="fa-solid fa-square-poll-vertical"></i> <div class="doc-icon-badge">
<h5>Exam Results</h5> <i class="fa-solid fa-file-pdf"></i>
<p>Check semester examination marks and performance reports.</p> </div>
</div> <h6 class="fw-bold text-dark mb-1">Exam Code of Conduct</h6>
</a> <small class="text-muted d-block mb-3">Examination guidelines</small>
</div> <span class="btn btn-sm btn-outline-danger rounded-pill px-3 fw-semibold">
<i class="fa-solid fa-download me-1"></i> Download PDF
</span>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6"> <div class="col-xl-3 col-md-6">
<a href="/Studentguidelines" class="text-decoration-none"> <a href="{{ route('student.download.helpdesk') }}" class="text-decoration-none" target="_blank">
<div class="service-card"> <div class="doc-card text-center">
<i class="fa-solid fa-book-open"></i> <div class="doc-icon-badge">
<h5>Student Guidelines</h5> <i class="fa-solid fa-file-pdf"></i>
<p>Read campus rules, regulations, and academic guidelines.</p> </div>
</div> <h6 class="fw-bold text-dark mb-1">Helpdesk Support Guide</h6>
</a> <small class="text-muted d-block mb-3">IT & portal assistance</small>
</div> <span class="btn btn-sm btn-outline-danger rounded-pill px-3 fw-semibold">
<i class="fa-solid fa-download me-1"></i> Download PDF
<div class="col-lg-4 col-md-6"> </span>
<a href="/Feedback&Complain" class="text-decoration-none"> </div>
<div class="service-card"> </a>
<i class="fa-solid fa-comments"></i> </div>
<h5>Feedback & Complaint</h5>
<p>Send feedback or submit inquiries directly to administration.</p>
</div>
</a>
</div>
<div class="col-lg-4 col-md-6">
<a href="/StudentProfile" class="text-decoration-none">
<div class="service-card">
<i class="fa-solid fa-user"></i>
<h5>Student Profile</h5>
<p>Manage and update your personal student profile details.</p>
</div>
</a>
</div>
</div>
<!-- Official Document Downloads (PDF) Section -->
<div class="section-title">
Official Document Downloads (PDF)
</div>
<div class="row g-4 mb-5">
<div class="col-lg-3 col-md-6">
<a href="{{ route('student.download.calendar') }}" class="text-decoration-none" target="_blank">
<div class="service-card text-center p-4">
<i class="fa-solid fa-file-pdf text-danger mb-3" style="font-size: 38px;"></i>
<h6 class="fw-bold text-dark">Academic Calendar</h6>
<small class="text-muted d-block mb-3">Semester dates & holidays</small>
<span class="btn btn-sm btn-outline-danger rounded-pill px-3"><i class="fa-solid fa-download me-1"></i> Download PDF</span>
</div>
</a>
</div>
<div class="col-lg-3 col-md-6">
<a href="{{ route('student.download.handbook') }}" class="text-decoration-none" target="_blank">
<div class="service-card text-center p-4">
<i class="fa-solid fa-file-pdf text-danger mb-3" style="font-size: 38px;"></i>
<h6 class="fw-bold text-dark">Student Handbook</h6>
<small class="text-muted d-block mb-3">Rules & academic policies</small>
<span class="btn btn-sm btn-outline-danger rounded-pill px-3"><i class="fa-solid fa-download me-1"></i> Download PDF</span>
</div>
</a>
</div>
<div class="col-lg-3 col-md-6">
<a href="{{ route('student.download.examcode') }}" class="text-decoration-none" target="_blank">
<div class="service-card text-center p-4">
<i class="fa-solid fa-file-pdf text-danger mb-3" style="font-size: 38px;"></i>
<h6 class="fw-bold text-dark">Exam Code of Conduct</h6>
<small class="text-muted d-block mb-3">Rules & exam guidelines</small>
<span class="btn btn-sm btn-outline-danger rounded-pill px-3"><i class="fa-solid fa-download me-1"></i> Download PDF</span>
</div>
</a>
</div>
<div class="col-lg-3 col-md-6">
<a href="{{ route('student.download.helpdesk') }}" class="text-decoration-none" target="_blank">
<div class="service-card text-center p-4">
<i class="fa-solid fa-file-pdf text-danger mb-3" style="font-size: 38px;"></i>
<h6 class="fw-bold text-dark">Helpdesk Support Guide</h6>
<small class="text-muted d-block mb-3">Technical assistance guide</small>
<span class="btn btn-sm btn-outline-danger rounded-pill px-3"><i class="fa-solid fa-download me-1"></i> Download PDF</span>
</div>
</a>
</div> </div>
</div> </div>

File diff suppressed because it is too large Load Diff

View File

@ -6,27 +6,28 @@
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<title>@yield('title', 'Student Portal - Automobile Academic')</title> <title>@yield('title', 'Student Portal - Automobile Academic')</title>
<!-- Font Awesome Icons & Bootstrap 5 --> <!-- Google Fonts & Font Awesome Icons & Bootstrap 5 -->
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<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">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style> <style>
:root { :root {
--theme-navy: #2D355B; --theme-navy: #1E233E;
--theme-footer-navy: #1F2541; --theme-footer-navy: #15182C;
--theme-red: #822424; --theme-red: #822424;
--theme-red-hover: #df2c3e; --theme-red-hover: #df2c3e;
--theme-yellow: #FFEA85; --theme-yellow: #FFEA85;
--theme-bg: #F6F6F6; --theme-bg: #F4F6F9;
--sidebar-width: 260px; --sidebar-width: 260px;
--text-dark: #333333; --text-dark: #1E293B;
} }
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
box-sizing: border-box; box-sizing: border-box;
font-family: 'Segoe UI', sans-serif; font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
} }
body { body {
@ -40,28 +41,61 @@
.sidebar { .sidebar {
width: var(--sidebar-width); width: var(--sidebar-width);
height: 100vh; height: 100vh;
background: var(--theme-navy); background: linear-gradient(180deg, #1E233E 0%, #15182C 100%);
color: #fff; color: #fff;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
padding: 24px 0; padding: 24px 0;
transition: all 0.3s ease; transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
z-index: 1030; z-index: 1030;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
box-shadow: 2px 0 10px rgba(0,0,0,0.1); box-shadow: 4px 0 20px rgba(0,0,0,0.08);
} }
.sidebar .brand { .sidebar .brand {
padding: 0 24px 20px; padding: 0 20px 22px;
font-weight: 700;
font-size: 1.25rem;
color: #ffffff;
border-bottom: 1px solid rgba(255,255,255,.15);
margin-bottom: 12px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px;
border-bottom: 1px solid rgba(255,255,255,.08);
margin-bottom: 20px;
}
.brand-logo-icon {
width: 42px;
height: 42px;
border-radius: 12px;
background: linear-gradient(135deg, var(--theme-red) 0%, var(--theme-red-hover) 100%);
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
box-shadow: 0 6px 16px rgba(130, 36, 36, 0.35);
}
.brand-text {
display: flex;
flex-direction: column;
line-height: 1.1;
}
.brand-text span {
font-weight: 800;
font-size: 1.25rem;
color: #ffffff;
letter-spacing: -0.5px;
}
.brand-sub {
font-size: 0.65rem;
font-weight: 700;
color: var(--theme-yellow);
letter-spacing: 1.5px;
opacity: 0.85;
margin-top: 2px;
} }
.sidebar .nav { .sidebar .nav {
@ -69,67 +103,196 @@
flex-direction: column; flex-direction: column;
flex-grow: 1; flex-grow: 1;
overflow-y: auto; overflow-y: auto;
padding: 0 14px;
gap: 4px;
} }
.sidebar .nav-link { .sidebar .nav-link {
color: rgba(255, 255, 255, 0.85); color: rgba(255, 255, 255, 0.75);
padding: 14px 24px; padding: 13px 18px;
font-size: 0.95rem; font-size: 0.93rem;
font-weight: 600; font-weight: 600;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; gap: 14px;
transition: all 0.2s ease; transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
border-left: 4px solid transparent; border-radius: 14px;
text-decoration: none; text-decoration: none;
position: relative;
} }
.sidebar .nav-link i { .sidebar .nav-link i {
width: 20px; width: 22px;
text-align: center; text-align: center;
font-size: 1.1rem;
transition: transform 0.25s ease, color 0.25s ease;
} }
.sidebar .nav-link:hover { .sidebar .nav-link:hover {
background: rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.08);
color: var(--theme-yellow) !important; color: var(--theme-yellow) !important;
padding-left: 28px; transform: translateX(4px);
}
.sidebar .nav-link:hover i {
transform: scale(1.15);
color: var(--theme-yellow);
} }
.sidebar .nav-link.active { .sidebar .nav-link.active {
background: var(--theme-footer-navy); background: linear-gradient(90deg, rgba(255, 234, 133, 0.16) 0%, rgba(255, 234, 133, 0.06) 100%);
color: var(--theme-yellow) !important; color: var(--theme-yellow) !important;
border-left: 4px solid #F73F52;
font-weight: 700; font-weight: 700;
border-left: 4px solid var(--theme-yellow);
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
border-radius: 4px 14px 14px 4px;
}
.sidebar .nav-link.active i {
color: var(--theme-yellow);
} }
.sidebar-user-profile { .sidebar-user-profile {
padding: 15px 24px; padding: 16px 18px;
border-top: 1px solid rgba(255,255,255,.15); border-top: 1px solid rgba(255,255,255,.08);
margin-top: auto; margin-top: auto;
background: var(--theme-footer-navy); background: rgba(0, 0, 0, 0.25);
} }
.sidebar-user-profile .user-dropdown-toggle { .sidebar-user-profile .user-dropdown-toggle {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 12px;
color: #fff; color: #fff;
text-decoration: none; text-decoration: none;
font-size: 0.95rem; transition: all 0.2s ease;
transition: color 0.2s ease; padding: 8px 10px;
border-radius: 12px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.08);
} }
.sidebar-user-profile .user-dropdown-toggle:hover { .sidebar-user-profile .user-dropdown-toggle:hover {
background: rgba(255, 255, 255, 0.12);
border-color: rgba(255, 234, 133, 0.3);
color: #ffffff;
}
.user-avatar-badge-sm {
width: 38px;
height: 38px;
border-radius: 50%;
background: linear-gradient(135deg, var(--theme-navy) 0%, var(--theme-footer-navy) 100%);
border: 2px solid var(--theme-yellow);
color: var(--theme-yellow); color: var(--theme-yellow);
display: flex;
align-items: center;
justify-content: center;
font-weight: 800;
font-size: 0.95rem;
flex-shrink: 0;
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
}
.user-info-text {
display: flex;
flex-direction: column;
overflow: hidden;
text-align: left;
}
.user-name-text {
font-weight: 700;
font-size: 0.88rem;
color: #ffffff;
line-height: 1.2;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.user-email-text {
font-size: 0.72rem;
font-style: italic;
color: rgba(255, 255, 255, 0.7);
line-height: 1.2;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Dark Glassmorphic User Dropdown Popup */
.user-dropdown-menu {
background: linear-gradient(145deg, #1A1E36 0%, #111428 100%) !important;
border: 1px solid rgba(255, 255, 255, 0.12) !important;
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5) !important;
border-radius: 16px !important;
margin-bottom: 12px !important;
padding: 8px !important;
width: 220px;
backdrop-filter: blur(16px);
}
.user-dropdown-item {
display: flex;
align-items: center;
gap: 12px;
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
color: #ffffff !important;
text-decoration: none;
padding: 10px 12px;
border-radius: 12px;
}
.user-dropdown-item:hover {
background: rgba(255, 255, 255, 0.08) !important;
transform: translateX(3px);
}
.dropdown-item-icon-blue {
width: 36px;
height: 36px;
border-radius: 10px;
background: rgba(59, 130, 246, 0.15);
color: #60A5FA;
border: 1px solid rgba(59, 130, 246, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.95rem;
flex-shrink: 0;
}
.dropdown-item-icon-red {
width: 36px;
height: 36px;
border-radius: 10px;
background: rgba(239, 68, 68, 0.15);
color: #F87171;
border: 1px solid rgba(239, 68, 68, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.95rem;
flex-shrink: 0;
} }
.main { .main {
margin-left: var(--sidebar-width); margin-left: var(--sidebar-width);
width: calc(100% - var(--sidebar-width)); width: calc(100% - var(--sidebar-width));
min-height: 100vh; min-height: 100vh;
padding: 40px; padding: 32px 40px;
background: var(--theme-bg); background: var(--theme-bg);
transition: all 0.3s ease; transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
}
.portal-content-container {
width: 100%;
max-width: 1280px;
margin: 0 auto;
} }
.mobile-header { .mobile-header {
@ -250,11 +413,17 @@
<!-- Sidebar Navigation --> <!-- Sidebar Navigation -->
<aside class="sidebar" id="sidebar"> <aside class="sidebar" id="sidebar">
<div class="brand"> <div class="brand">
<i class="fa-solid fa-car-side me-2"></i> AutoEdu <div class="brand-logo-icon">
<i class="fa-solid fa-car-side"></i>
</div>
<div class="brand-text">
<span>AutoEdu</span>
<small class="brand-sub">STUDENT ACADEMY</small>
</div>
</div> </div>
<nav class="nav"> <nav class="nav">
<a href="/Dashboard" class="nav-link {{ request()->is('Dashboard*') ? 'active' : '' }}"> <a href="/student-portal" class="nav-link {{ request()->is('Dashboard*') || request()->is('student-portal*') ? 'active' : '' }}">
<i class="fa-solid fa-gauge"></i> Dashboard <i class="fa-solid fa-gauge"></i> Dashboard
</a> </a>
<a href="/mycourse" class="nav-link {{ request()->is('mycourse*') ? 'active' : '' }}"> <a href="/mycourse" class="nav-link {{ request()->is('mycourse*') ? 'active' : '' }}">
@ -281,27 +450,44 @@
@if(session()->has('student_id')) @if(session()->has('student_id'))
<div class="dropdown dropup"> <div class="dropdown dropup">
<a class="user-dropdown-toggle dropdown-toggle" href="#" role="button" id="userMenuDesktop" data-bs-toggle="dropdown" aria-expanded="false"> <a class="user-dropdown-toggle dropdown-toggle" href="#" role="button" id="userMenuDesktop" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fa-solid fa-circle-user" style="font-size: 24px; color: var(--theme-yellow);"></i> <div class="user-avatar-badge-sm">
<span class="text-truncate" style="max-width: 150px;">{{ session('student_name') }}</span> {{ strtoupper(substr(session('student_name', 'S'), 0, 1)) }}
</div>
<div class="user-info-text">
<span class="user-name-text">{{ session('student_name', 'Student') }}</span>
<span class="user-email-text">Active Session</span>
</div>
</a> </a>
<ul class="dropdown-menu dropdown-menu-start shadow w-100" aria-labelledby="userMenuDesktop"> <ul class="dropdown-menu user-dropdown-menu shadow-lg p-2 animate slideIn" aria-labelledby="userMenuDesktop">
<li> <li>
<a class="dropdown-item" href="{{ route('StudentProfile') }}"> <a class="dropdown-item user-dropdown-item py-2.5 px-3 rounded-3" href="{{ route('StudentProfile') }}">
<i class="fa-solid fa-user me-2"></i> Profile <div class="dropdown-item-icon-blue">
<i class="fa-solid fa-user-gear"></i>
</div>
<div>
<span class="fw-bold d-block text-white" style="font-size: 0.88rem;">My Profile</span>
<small class="text-white-50" style="font-size: 0.72rem;">View & edit details</small>
</div>
</a> </a>
</li> </li>
<li><hr class="dropdown-divider"></li> <li><hr class="dropdown-divider border-white opacity-10 my-1"></li>
<li> <li>
<button type="button" onclick="submitLogout()" class="dropdown-item text-danger border-0 bg-transparent w-100 text-start"> <button type="button" onclick="submitLogout()" class="dropdown-item user-dropdown-item py-2.5 px-3 rounded-3 border-0 bg-transparent w-100 text-start">
<i class="fa-solid fa-right-from-bracket me-2"></i> Logout <div class="dropdown-item-icon-red">
<i class="fa-solid fa-right-from-bracket"></i>
</div>
<div>
<span class="fw-bold d-block text-danger" style="font-size: 0.88rem;">Logout</span>
<small class="text-danger-subtle opacity-75" style="font-size: 0.72rem;">Sign out of session</small>
</div>
</button> </button>
</li> </li>
</ul> </ul>
</div> </div>
@else @else
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<a href="/" class="btn btn-outline-light btn-sm w-100">Sign In</a> <a href="/" class="btn btn-outline-light btn-sm w-100 rounded-pill">Sign In</a>
</div> </div>
@endif @endif
</div> </div>

View File

@ -4,281 +4,463 @@
@section('content') @section('content')
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Google Font -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<style> <style>
:root { :root {
--theme-navy: #2D355B; /* Primary Navy */ --theme-navy: #1E233E;
--theme-navy-dark: #1F2541; /* Dark Navy */ --theme-navy-dark: #15182C;
--theme-red: #822424; /* Primary Accent Red */ --theme-red: #822424;
--theme-red-hover: #df2c3e; /* Red Hover */ --theme-red-hover: #df2c3e;
--theme-yellow: #FFEA85; /* Accent Yellow/Gold */ --theme-yellow: #FFEA85;
--bg-light: #F6F6F6; /* Page Background */ --theme-bg: #F4F6F9;
--white: #ffffff; --text-dark: #1E293B;
} }
body { /* Page Header Hero */
font-family: 'Poppins', sans-serif; .timetable-hero {
background: var(--bg-light); background: linear-gradient(135deg, #1E233E 0%, #2A1F3B 50%, #4A1A24 100%);
} border-radius: 20px;
padding: 32px 38px;
/* Page Header Hero Section */ margin-bottom: 28px;
.page-header { box-shadow: 0 12px 32px rgba(30, 35, 62, 0.16);
background: linear-gradient(135deg, #2B293F 0%, #94A6F959 100%) !important; position: relative;
color: var(--white);
padding: 35px 30px;
border-radius: 16px;
margin-bottom: 30px;
box-shadow: 0 8px 25px rgba(31, 37, 65, 0.15);
border-left: 5px solid var(--theme-red);
}
.page-header h2 {
font-weight: 700;
}
.page-header p {
opacity: .85;
}
/* Info Cards & Wrapper */
.info-card {
background: var(--white);
border: 1px solid #e2e8f0;
border-radius: 16px;
box-shadow: 0 4px 15px rgba(0, 0, 0, .04);
}
.today-card {
background: var(--white);
border: 1px solid #e2e8f0;
border-radius: 16px;
box-shadow: 0 4px 15px rgba(0, 0, 0, .04);
padding: 25px;
height: 100%;
}
.today-card h5,
.info-card h5 {
font-weight: 600;
color: var(--theme-navy);
}
/* Timetable Card Section */
.table-card {
background: var(--white);
border: 1px solid #e2e8f0;
border-radius: 16px;
box-shadow: 0 4px 15px rgba(0, 0, 0, .04);
overflow: hidden; overflow: hidden;
} }
.table thead { .timetable-hero::before {
background: var(--theme-navy); content: '';
color: var(--white); position: absolute;
top: -50%;
right: -10%;
width: 350px;
height: 350px;
background: radial-gradient(circle, rgba(255, 234, 133, 0.15) 0%, rgba(255, 234, 133, 0) 70%);
border-radius: 50%;
pointer-events: none;
} }
.table thead th { .btn-print {
font-weight: 600; background: #ffffff;
padding: 15px 10px; color: #1E233E;
font-weight: 700;
padding: 11px 26px;
border-radius: 50px;
border: none;
box-shadow: 0 6px 18px rgba(0,0,0,0.12);
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
} }
.table td, .btn-print:hover {
.table th { background: var(--theme-yellow);
color: #1E233E;
transform: translateY(-2px);
box-shadow: 0 10px 24px rgba(255, 234, 133, 0.4);
}
/* Top Cards */
.top-info-card {
background: #ffffff;
border: 1px solid #E2E8F0;
border-radius: 20px;
padding: 26px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03);
height: 100%;
}
.card-title-heading {
font-size: 1.05rem;
font-weight: 700;
color: #0F172A;
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 20px;
}
/* Timeline Item for Today */
.today-class-item {
border-radius: 14px;
padding: 14px 18px;
margin-bottom: 12px;
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.today-class-item:hover {
transform: translateX(4px);
}
.today-class-item.theory {
background: linear-gradient(135deg, #EFF6FF 0%, #E0E7FF 100%);
border: 1px solid #C7D2FE;
}
.today-class-item.practical {
background: linear-gradient(135deg, #FEF2F2 0%, #FEE2E2 100%);
border: 1px solid #FCA5A5;
}
.today-class-item.workshop {
background: linear-gradient(135deg, #FFFBEB 0%, #FEF3C7 100%);
border: 1px solid #FDE68A;
}
/* Legend Badges */
.legend-pill {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 9px 18px;
border-radius: 50px;
font-size: 0.84rem;
font-weight: 700;
margin-right: 10px;
margin-bottom: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}
.legend-pill.theory {
background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);
color: #1E40AF;
border: 1px solid #BFDBFE;
}
.legend-pill.practical {
background: linear-gradient(135deg, #FEF2F2 0%, #FEE2E2 100%);
color: #991B1B;
border: 1px solid #FCA5A5;
}
.legend-pill.workshop {
background: linear-gradient(135deg, #FFFBEB 0%, #FEF3C7 100%);
color: #92400E;
border: 1px solid #FDE68A;
}
.legend-pill.break {
background: linear-gradient(135deg, #FEFCE8 0%, #FEF08A 100%);
color: #713F12;
border: 1px solid #FDE047;
}
/* Timetable Grid Container */
.timetable-wrapper {
background: #ffffff;
border-radius: 20px;
border: 1px solid #E2E8F0;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.04);
overflow: hidden;
}
.table-modern {
margin-bottom: 0;
border-collapse: separate;
border-spacing: 0;
}
.table-modern thead tr {
background: linear-gradient(135deg, #1E233E 0%, #2D355B 100%);
color: #ffffff;
}
.table-modern thead th {
padding: 20px 16px;
font-size: 0.88rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.6px;
border: none;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
min-width: 140px;
} }
.table tbody th { .table-modern thead th.today-header {
background-color: #f8fafc; background: linear-gradient(180deg, rgba(255, 234, 133, 0.22) 0%, rgba(255, 234, 133, 0.1) 100%);
color: var(--theme-navy); color: var(--theme-yellow);
font-weight: 600; border-bottom: 4px solid var(--theme-yellow);
} }
/* Updated Status Badges */ .table-modern tbody th.time-column {
.badge-theory { background: #F8FAFC;
background: var(--theme-navy) !important; color: #334155;
color: var(--white) !important; font-weight: 700;
font-size: 0.85rem;
padding: 20px 14px;
text-align: center;
vertical-align: middle;
border-right: 1px solid #E2E8F0;
border-bottom: 1px solid #E2E8F0;
width: 150px;
} }
.badge-practical { .table-modern tbody td {
background: var(--theme-red) !important; padding: 14px;
color: var(--white) !important; vertical-align: middle;
text-align: center;
border-right: 1px solid #F1F5F9;
border-bottom: 1px solid #E2E8F0;
background: #ffffff;
transition: background 0.2s ease;
min-width: 165px;
} }
.badge-workshop { .table-modern tbody td.today-cell {
background: #e67e22 !important; /* Workshop Accent */ background: rgba(255, 234, 133, 0.05);
color: var(--white) !important;
} }
.badge-break { .table-modern tbody tr:hover td {
background: var(--theme-yellow) !important; background: rgba(248, 250, 252, 0.85);
color: var(--theme-navy-dark) !important;
font-weight: 600;
} }
.table tbody tr:hover { /* Vibrant Class Cards inside Cells */
background: rgba(45, 53, 91, 0.02); .class-cell-card {
transition: .3s; border-radius: 14px;
padding: 12px 14px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
transition: all 0.28s cubic-bezier(0.16, 1, 0.3, 1);
cursor: default;
position: relative;
} }
.lunch-row { .class-cell-card:hover {
background-color: rgba(255, 234, 133, 0.25) !important; transform: translateY(-4px) scale(1.02);
color: var(--theme-navy-dark); box-shadow: 0 10px 24px rgba(0, 0, 0, 0.1);
font-weight: 600;
} }
.legend span { .class-cell-card.theory {
margin-right: 12px; background: linear-gradient(135deg, #EFF6FF 0%, #E0E7FF 100%);
display: inline-block; border: 1px solid #C7D2FE;
}
.class-cell-card.practical {
background: linear-gradient(135deg, #FEF2F2 0%, #FEE2E2 100%);
border: 1px solid #FCA5A5;
}
.class-cell-card.workshop {
background: linear-gradient(135deg, #FFFBEB 0%, #FEF3C7 100%);
border: 1px solid #FDE68A;
}
/* Badges inside Class Cell */
.type-tag-modern {
font-size: 0.72rem;
font-weight: 800;
padding: 4px 12px;
border-radius: 50px;
display: inline-flex;
align-items: center;
gap: 4px;
margin-bottom: 8px; margin-bottom: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
} }
.legend .badge { .type-tag-modern.theory {
padding: 8px 14px; background: #ffffff;
font-size: 12px; color: #1E40AF;
border: 1px solid #BFDBFE;
} }
/* Custom Buttons */ .type-tag-modern.practical {
.download-btn { background: #ffffff;
border-radius: 8px; color: #991B1B;
padding: 10px 22px; border: 1px solid #FCA5A5;
background-color: var(--theme-red) !important;
color: var(--white) !important;
border: none;
font-weight: 500;
transition: all 0.2s ease;
} }
.download-btn:hover { .type-tag-modern.workshop {
background-color: var(--theme-red-hover) !important; background: #ffffff;
color: var(--white) !important; color: #92400E;
border: 1px solid #FDE68A;
} }
@media(max-width:768px) { .subject-title {
.table td, font-weight: 800;
.table th { font-size: 0.9rem;
font-size: 13px; line-height: 1.35;
min-width: 120px; letter-spacing: -0.2px;
}
.subject-title.theory { color: #1E1B4B; }
.subject-title.practical { color: #822424; }
.subject-title.workshop { color: #78350F; }
.empty-cell-badge {
color: #94A3B8;
font-size: 0.82rem;
font-weight: 600;
display: inline-flex;
align-items: center;
gap: 4px;
opacity: 0.6;
}
/* Lunch Break Row */
.lunch-break-row td {
background: linear-gradient(90deg, #FEFCE8 0%, #FEF3C7 50%, #FEFCE8 100%) !important;
color: #713F12;
font-weight: 800;
font-size: 0.9rem;
padding: 16px !important;
border-bottom: 1px solid #FDE047 !important;
letter-spacing: 0.4px;
}
/* Print Optimization */
@media print {
.sidebar, .mobile-header, .btn-print, .title-accent {
display: none !important;
} }
.main {
.page-header { margin-left: 0 !important;
padding: 25px; padding: 0 !important;
width: 100% !important;
}
.portal-content-container {
max-width: 100% !important;
}
.timetable-hero {
background: #1E233E !important;
color: #ffffff !important;
-webkit-print-color-adjust: exact;
} }
} }
</style> </style>
<div class="container py-4"> <div class="portal-content-container">
<!-- Header --> <!-- Hero Header -->
<div class="page-header"> <div class="timetable-hero d-flex align-items-center justify-content-between flex-wrap gap-3">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-3"> <div class="position-relative" style="z-index: 1;">
<div> <div class="d-flex align-items-center gap-2 mb-2">
<h2 class="mb-1"><i class="fas fa-calendar-alt me-2" style="color: var(--theme-yellow);"></i>My Class Timetable</h2> <span class="badge bg-warning bg-opacity-20 text-warning border border-warning border-opacity-20 px-3 py-1.5 rounded-pill fw-semibold" style="font-size: 0.78rem;">
<p class="mb-0"> <i class="fa-solid fa-calendar-days me-1"></i> Weekly Academic Schedule
Automobile Engineering Academy Student Portal </span>
</p>
</div> </div>
<h2 class="fw-bold text-white mb-1" style="letter-spacing: -0.5px;">
<button class="btn download-btn shadow-sm" onclick="window.print()"> My Class Timetable
<i class="fas fa-print me-2"></i>Print Timetable </h2>
</button> <p class="text-white-50 mb-0 fs-6">
Automobile Engineering Academy Student Academic Schedule 2026
</p>
</div> </div>
<button class="btn btn-print shadow-sm" onclick="window.print()">
<i class="fa-solid fa-print me-2"></i>Print Timetable
</button>
</div> </div>
<!-- Top Grid Info --> <!-- Top Grid Info Cards -->
<div class="row g-4 mb-4"> <div class="row g-3 g-lg-4 mb-4">
<!-- Today's Schedule Card --> <!-- Today's Schedule Card -->
<div class="col-lg-4"> <div class="col-lg-5">
<div class="today-card"> <div class="top-info-card">
<h5 class="mb-3"> <div class="card-title-heading">
<i class="fas fa-clock me-2" style="color: var(--theme-red);"></i> <div class="rounded-3 bg-danger bg-opacity-10 text-danger p-2.5 d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
Today's Schedule ({{ $todayName ?? 'Today' }}) <i class="fa-solid fa-clock-rotate-left fs-5"></i>
</h5> </div>
<div>
Today's Schedule
<span class="badge bg-danger-subtle text-danger border border-danger-subtle ms-1 fw-bold rounded-pill" style="font-size: 0.72rem;">
{{ $todayName ?? 'Today' }}
</span>
</div>
</div>
@forelse($todaySchedule ?? [] as $todayItem) @forelse($todaySchedule ?? [] as $todayItem)
@php @php
$borderStyle = 'var(--theme-navy)'; $typeClass = 'theory';
$badgeClass = 'badge-theory'; $iconClass = 'fa-book-open';
if(strtolower($todayItem->type) == 'practical') { if(strtolower($todayItem->type) == 'practical') {
$borderStyle = 'var(--theme-red)'; $typeClass = 'practical';
$badgeClass = 'badge-practical'; $iconClass = 'fa-flask';
} elseif(strtolower($todayItem->type) == 'workshop') { } elseif(strtolower($todayItem->type) == 'workshop') {
$borderStyle = '#e67e22'; $typeClass = 'workshop';
$badgeClass = 'badge-workshop'; $iconClass = 'fa-screwdriver-wrench';
} }
@endphp @endphp
<div class="mb-3 p-2 rounded" style="background: #f8fafc; border-left: 3px solid {{ $borderStyle }};"> <div class="today-class-item {{ $typeClass }}">
<strong>{{ $todayItem->time_slot }}</strong><br> <div class="d-flex align-items-center justify-content-between mb-1">
<span class="badge {{ $badgeClass }} me-1">{{ $todayItem->type }}</span> <span class="fw-bold text-dark small"><i class="fa-regular fa-clock me-1 text-secondary"></i> {{ $todayItem->time_slot }}</span>
<span>{{ $todayItem->subject_name }}</span> <span class="type-tag-modern {{ $typeClass }} mb-0">
<i class="fa-solid {{ $iconClass }}"></i> {{ $todayItem->type }}
</span>
</div>
<div class="subject-title {{ $typeClass }}">{{ $todayItem->subject_name }}</div>
</div> </div>
@empty @empty
<div class="p-3 text-center text-muted border rounded"> <div class="p-4 text-center border rounded-4 bg-light bg-opacity-50">
<i class="fas fa-coffee me-1"></i> No classes scheduled for today! <div class="rounded-circle bg-warning bg-opacity-20 text-warning d-inline-flex align-items-center justify-content-center p-3 mb-2" style="width: 54px; height: 54px;">
<i class="fa-solid fa-mug-hot fs-3"></i>
</div>
<h6 class="fw-bold text-dark mb-1">No classes scheduled for today!</h6>
<p class="small text-muted mb-0">Take time to review your course materials or relax.</p>
</div> </div>
@endforelse @endforelse
</div> </div>
</div> </div>
<!-- Legend Card --> <!-- Timetable Legend & Guidelines Card -->
<div class="col-lg-8"> <div class="col-lg-7">
<div class="info-card p-4 h-100 d-flex flex-column justify-content-between"> <div class="top-info-card d-flex flex-column justify-content-between">
<div> <div>
<h5 class="mb-3"> <div class="card-title-heading">
<i class="fas fa-info-circle me-2" style="color: var(--theme-navy);"></i> <div class="rounded-3 bg-primary bg-opacity-10 text-primary p-2.5 d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
Timetable Legend <i class="fa-solid fa-sliders fs-5"></i>
</h5> </div>
<span>Timetable Legend & Session Types</span>
</div>
<div class="legend mb-2"> <div class="mb-3">
<span> <span class="legend-pill theory">
<span class="badge badge-theory">Theory</span> <i class="fa-solid fa-book-open"></i> Theory Session
</span> </span>
<span> <span class="legend-pill practical">
<span class="badge badge-practical">Practical</span> <i class="fa-solid fa-flask"></i> Practical Session
</span> </span>
<span> <span class="legend-pill workshop">
<span class="badge badge-workshop">Workshop</span> <i class="fa-solid fa-screwdriver-wrench"></i> Workshop Training
</span> </span>
<span> <span class="legend-pill break">
<span class="badge badge-break">Break</span> <i class="fa-solid fa-utensils"></i> Rest / Lunch Break
</span> </span>
</div> </div>
</div> </div>
<div> <div class="pt-3 border-top border-slate-100 mt-2">
<hr class="text-muted"> <div class="p-3 rounded-4 bg-danger bg-opacity-10 text-danger border border-danger border-opacity-10 d-flex align-items-center gap-3">
<p class="mb-0 text-muted small"> <div class="rounded-circle bg-danger text-white p-2 d-flex align-items-center justify-content-center flex-shrink-0" style="width: 32px; height: 32px;">
<i class="fas fa-exclamation-circle me-1" style="color: var(--theme-red);"></i> <i class="fa-solid fa-exclamation" style="font-size: 14px;"></i>
Please arrive at least 15 minutes before each class. Attendance is compulsory for all practical sessions. </div>
</p> <span class="small fw-semibold">
Please arrive at least 15 minutes before each session. 100% attendance is mandatory for practical and workshop modules.
</span>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Timetable Grid --> <!-- Main Timetable Grid -->
<div class="table-card"> <div class="timetable-wrapper mb-5">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered align-middle mb-0"> <table class="table table-modern align-middle mb-0">
<thead> <thead>
<tr> <tr>
<th>Time</th> <th style="width: 150px;">
<i class="fa-regular fa-clock me-1"></i> Time
</th>
@foreach($days as $day) @foreach($days as $day)
<th class="{{ ($todayName ?? '') == $day ? 'bg-danger text-white' : '' }}"> @php
{{ $day }} {{ ($todayName ?? '') == $day ? '(Today)' : '' }} $isToday = ($todayName ?? '') == $day;
@endphp
<th class="{{ $isToday ? 'today-header' : '' }}">
{{ $day }}
@if($isToday)
<span class="badge bg-warning text-dark px-2 py-1 rounded-pill ms-1 fw-bold" style="font-size: 0.7rem; box-shadow: 0 2px 8px rgba(255, 234, 133, 0.4);">
<i class="fa-solid fa-star me-1"></i>TODAY
</span>
@endif
</th> </th>
@endforeach @endforeach
</tr> </tr>
@ -286,7 +468,6 @@ body {
<tbody> <tbody>
@forelse($timeSlots as $slot) @forelse($timeSlots as $slot)
@php @php
// Lunch/Break Check
$isBreakRow = false; $isBreakRow = false;
foreach($days as $d) { foreach($days as $d) {
if(isset($schedule[$slot][$d]) && strtolower($schedule[$slot][$d]->type) == 'break') { if(isset($schedule[$slot][$d]) && strtolower($schedule[$slot][$d]->type) == 'break') {
@ -297,32 +478,49 @@ body {
@endphp @endphp
@if($isBreakRow) @if($isBreakRow)
<tr class="lunch-row"> <tr class="lunch-break-row">
<th>{{ $slot }}</th> <th class="time-column">{{ $slot }}</th>
<td colspan="5"> <td colspan="5" class="text-center">
🍴 LUNCH BREAK / REST TIME <i class="fa-solid fa-mug-hot me-2 text-warning"></i> LUNCH BREAK & REST TIME (12:30 PM - 01:30 PM)
</td> </td>
</tr> </tr>
@else @else
<tr> <tr>
<th>{{ $slot }}</th> <th class="time-column">
<div class="d-flex align-items-center justify-content-center gap-1">
<i class="fa-regular fa-clock text-muted opacity-75" style="font-size: 0.8rem;"></i>
<span>{{ $slot }}</span>
</div>
</th>
@foreach($days as $day) @foreach($days as $day)
<td> @php
$isToday = ($todayName ?? '') == $day;
@endphp
<td class="{{ $isToday ? 'today-cell' : '' }}">
@if(isset($schedule[$slot][$day])) @if(isset($schedule[$slot][$day]))
@php @php
$cell = $schedule[$slot][$day]; $cell = $schedule[$slot][$day];
$typeClass = 'badge-theory'; $typeClass = 'theory';
$iconClass = 'fa-book-open';
if(strtolower($cell->type) == 'practical') { if(strtolower($cell->type) == 'practical') {
$typeClass = 'badge-practical'; $typeClass = 'practical';
$iconClass = 'fa-flask';
} elseif(strtolower($cell->type) == 'workshop') { } elseif(strtolower($cell->type) == 'workshop') {
$typeClass = 'badge-workshop'; $typeClass = 'workshop';
$iconClass = 'fa-screwdriver-wrench';
} }
@endphp @endphp
<span class="badge {{ $typeClass }} mb-1">{{ $cell->type }}</span><br> <div class="class-cell-card {{ $typeClass }}">
{{ $cell->subject_name }} <div class="type-tag-modern {{ $typeClass }}">
<i class="fa-solid {{ $iconClass }}"></i> {{ $cell->type }}
</div>
<div class="subject-title {{ $typeClass }}">{{ $cell->subject_name }}</div>
</div>
@else @else
<span class="text-muted">-</span> <div class="empty-cell-badge">
<i class="fa-solid fa-minus"></i>
</div>
@endif @endif
</td> </td>
@endforeach @endforeach
@ -330,8 +528,9 @@ body {
@endif @endif
@empty @empty
<tr> <tr>
<td colspan="6" class="text-center py-4 text-muted"> <td colspan="6" class="text-center py-5 text-muted">
<i class="fas fa-info-circle me-1"></i> No timetable data available right now. <i class="fa-solid fa-calendar-xmark text-secondary mb-2 fs-2 d-block"></i>
<span class="fw-semibold">No timetable data available for this week.</span>
</td> </td>
</tr> </tr>
@endforelse @endforelse

View File

@ -99,6 +99,7 @@ Route::middleware(['web'])->group(function () {
})->name('student.portal'); })->name('student.portal');
Route::get('/StudentProfile', [StudentPortalController::class, 'showProfile'])->name('StudentProfile'); Route::get('/StudentProfile', [StudentPortalController::class, 'showProfile'])->name('StudentProfile');
Route::post('/StudentProfile/update', [StudentPortalController::class, 'updateProfile'])->name('student.profile.update');
Route::get('/results', [ResultsController::class, 'index'])->name('results'); Route::get('/results', [ResultsController::class, 'index'])->name('results');
Route::get('/Dashboard', function () { Route::get('/Dashboard', function () {