set result and timetable pages
This commit is contained in:
parent
5d76c711f7
commit
41934b31fc
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\Result;
|
||||||
|
|
||||||
|
class ResultsController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
// 1. Session එකෙන් ID එක ලබා ගැනීම
|
||||||
|
$studentLogId = session('student_log_id') ?? session('student_id');
|
||||||
|
|
||||||
|
// Session එකේ ID එකක් නොමැති නම් Login එකට Redirect කිරීම
|
||||||
|
if (!$studentLogId) {
|
||||||
|
return redirect('/signin')->with('error', 'Please login first!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Log වී සිටින Student ගේ student_log_id එකට අදාළව දත්ත ලබා ගැනීම
|
||||||
|
$results = Result::where('student_log_id', $studentLogId)->get();
|
||||||
|
|
||||||
|
// 3. Calculations
|
||||||
|
$totalModules = $results->count();
|
||||||
|
|
||||||
|
$passedModules = $results->filter(function ($item) {
|
||||||
|
return strtolower(trim($item->status)) === 'pass';
|
||||||
|
})->count();
|
||||||
|
|
||||||
|
$averageMarks = $totalModules > 0 ? round($results->avg('marks'), 1) : 0;
|
||||||
|
|
||||||
|
// View එකට Data Pass කිරීම
|
||||||
|
return view('results', compact('results', 'totalModules', 'passedModules', 'averageMarks'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\Timetable;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
class TimetableController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
// Session Check
|
||||||
|
$studentLogId = session('student_log_id') ?? session('student_id');
|
||||||
|
|
||||||
|
if (!$studentLogId) {
|
||||||
|
return redirect('/signin')->with('error', 'Please login first!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. All Timetable Records Get
|
||||||
|
// (තනි Student ට අදාළ දත්ත හෝ පොදු Timetable දත්ත)
|
||||||
|
$rawTimetables = Timetable::whereNull('student_log_id')
|
||||||
|
->orWhere('student_log_id', $studentLogId)
|
||||||
|
->orderBy('sort_order', 'asc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Data එක Table එකට ලෙහෙසියෙන් Group කර ගැනීම
|
||||||
|
// Array structure: $schedule[TimeSlot][Day] = Item
|
||||||
|
$schedule = [];
|
||||||
|
$timeSlots = [];
|
||||||
|
|
||||||
|
foreach ($rawTimetables as $item) {
|
||||||
|
if (!in_array($item->time_slot, $timeSlots)) {
|
||||||
|
$timeSlots[] = $item->time_slot;
|
||||||
|
}
|
||||||
|
$schedule[$item->time_slot][$item->day] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Today's Schedule (අද දවසේ පන්ති පමණක් ලබා ගැනීම)
|
||||||
|
$todayName = Carbon::now()->format('l'); // Monday, Tuesday etc.
|
||||||
|
$todaySchedule = Timetable::where('day', $todayName)
|
||||||
|
->where(function($q) use ($studentLogId) {
|
||||||
|
$q->whereNull('student_log_id')
|
||||||
|
->orWhere('student_log_id', $studentLogId);
|
||||||
|
})
|
||||||
|
->where('type', '!=', 'Break')
|
||||||
|
->orderBy('sort_order', 'asc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
|
||||||
|
|
||||||
|
return view('timetable', compact('schedule', 'timeSlots', 'days', 'todaySchedule', 'todayName'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Result extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'results';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'student_log_id',
|
||||||
|
'module_code',
|
||||||
|
'academic_year',
|
||||||
|
'semester',
|
||||||
|
'module_name',
|
||||||
|
'marks',
|
||||||
|
'grade',
|
||||||
|
'status',
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Timetable extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'timetables';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'student_log_id',
|
||||||
|
'time_slot',
|
||||||
|
'day',
|
||||||
|
'subject_name',
|
||||||
|
'type',
|
||||||
|
'sort_order',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('results', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('student_log_id')->constrained('student_portal_logs')->onDelete('cascade');
|
||||||
|
$table->string('module_code');
|
||||||
|
$table->string('academic_year');
|
||||||
|
$table->string('semester');
|
||||||
|
$table->string('module_name');
|
||||||
|
$table->integer('marks');
|
||||||
|
$table->string('grade'); // e.g., 'A+', 'A', 'B', 'C', 'F'
|
||||||
|
$table->string('status')->default('Pass'); // 'Pass' or 'Fail'
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('results');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('timetables', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('student_log_id')->nullable(); // Student-specific Timetable එකක් නම්
|
||||||
|
$table->string('time_slot');
|
||||||
|
$table->string('day');
|
||||||
|
$table->string('subject_name');
|
||||||
|
$table->enum('type', ['Theory', 'Practical', 'Workshop', 'Break'])->default('Theory');
|
||||||
|
$table->integer('sort_order')->default(1);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('timetables');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
<!-- Google Font -->
|
<!-- Google Font -->
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- html2pdf Library for Client-side PDF Generation -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--theme-navy: #2D355B; /* Primary Navy */
|
--theme-navy: #2D355B; /* Primary Navy */
|
||||||
|
|
@ -152,6 +155,11 @@ Result Table
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-fail {
|
||||||
|
color: #dc3545;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
/* =======================
|
/* =======================
|
||||||
Progress
|
Progress
|
||||||
======================= */
|
======================= */
|
||||||
|
|
@ -169,6 +177,11 @@ Progress
|
||||||
background-color: var(--theme-red) !important;
|
background-color: var(--theme-red) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align-items-stretch {
|
||||||
|
align-items: stretch !important;
|
||||||
|
padding-top: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
/* =======================
|
/* =======================
|
||||||
Download Card
|
Download Card
|
||||||
======================= */
|
======================= */
|
||||||
|
|
@ -216,163 +229,195 @@ Download Card
|
||||||
|
|
||||||
<div class="container py-4">
|
<div class="container py-4">
|
||||||
|
|
||||||
<!-- Hero Section -->
|
<!-- Printable Area Container -->
|
||||||
<div class="result-hero">
|
<div id="pdf-download-area">
|
||||||
<h2>
|
|
||||||
<i class="fas fa-award me-2" style="color: var(--theme-yellow);"></i>
|
|
||||||
Academic Results
|
|
||||||
</h2>
|
|
||||||
<p>
|
|
||||||
View your examination results and overall academic performance.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Summary Cards -->
|
<!-- Hero Section -->
|
||||||
<div class="row g-4">
|
<div class="result-hero">
|
||||||
<div class="col-md-4">
|
<h2>
|
||||||
<div class="summary-card">
|
<i class="fas fa-award me-2" style="color: var(--theme-yellow);"></i>
|
||||||
<i class="fas fa-chart-line"></i>
|
Academic Results
|
||||||
<h3>82%</h3>
|
</h2>
|
||||||
<small>Overall Average</small>
|
<p>
|
||||||
</div>
|
View your examination results and overall academic performance.
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="summary-card">
|
|
||||||
<i class="fas fa-medal"></i>
|
|
||||||
<h3>3.65</h3>
|
|
||||||
<small>Current GPA</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="summary-card">
|
|
||||||
<i class="fas fa-book-open"></i>
|
|
||||||
<h3>6 / 6</h3>
|
|
||||||
<small>Modules Passed</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Result Table -->
|
|
||||||
<div class="result-card">
|
|
||||||
<div class="table-head">
|
|
||||||
<h5 class="mb-0 fw-bold">
|
|
||||||
Semester Results
|
|
||||||
</h5>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-hover align-middle">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Module</th>
|
|
||||||
<th>Marks</th>
|
|
||||||
<th>Grade</th>
|
|
||||||
<th>Status</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="fw-semibold" style="color: var(--theme-navy);">Engine Technology</td>
|
|
||||||
<td>91</td>
|
|
||||||
<td>
|
|
||||||
<span class="grade a">A+</span>
|
|
||||||
</td>
|
|
||||||
<td><span class="status-pass"><i class="fas fa-check-circle me-1"></i>Pass</span></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="fw-semibold" style="color: var(--theme-navy);">Brake Systems</td>
|
|
||||||
<td>84</td>
|
|
||||||
<td>
|
|
||||||
<span class="grade a">A</span>
|
|
||||||
</td>
|
|
||||||
<td><span class="status-pass"><i class="fas fa-check-circle me-1"></i>Pass</span></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="fw-semibold" style="color: var(--theme-navy);">Electrical Systems</td>
|
|
||||||
<td>79</td>
|
|
||||||
<td>
|
|
||||||
<span class="grade b">B+</span>
|
|
||||||
</td>
|
|
||||||
<td><span class="status-pass"><i class="fas fa-check-circle me-1"></i>Pass</span></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="fw-semibold" style="color: var(--theme-navy);">Transmission Systems</td>
|
|
||||||
<td>74</td>
|
|
||||||
<td>
|
|
||||||
<span class="grade b">B</span>
|
|
||||||
</td>
|
|
||||||
<td><span class="status-pass"><i class="fas fa-check-circle me-1"></i>Pass</span></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="fw-semibold" style="color: var(--theme-navy);">Workshop Practice</td>
|
|
||||||
<td>88</td>
|
|
||||||
<td>
|
|
||||||
<span class="grade a">A</span>
|
|
||||||
</td>
|
|
||||||
<td><span class="status-pass"><i class="fas fa-check-circle me-1"></i>Pass</span></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="fw-semibold" style="color: var(--theme-navy);">Industrial Safety</td>
|
|
||||||
<td>81</td>
|
|
||||||
<td>
|
|
||||||
<span class="grade a">A-</span>
|
|
||||||
</td>
|
|
||||||
<td><span class="status-pass"><i class="fas fa-check-circle me-1"></i>Pass</span></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Performance Bars -->
|
|
||||||
<div class="result-card">
|
|
||||||
<div class="table-head">
|
|
||||||
<h5 class="mb-0 fw-bold">
|
|
||||||
Overall Performance
|
|
||||||
</h5>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-4">
|
|
||||||
<div class="d-flex justify-content-between mb-2">
|
|
||||||
<span class="fw-semibold" style="color: var(--theme-navy);">Course Completion</span>
|
|
||||||
<span class="fw-bold" style="color: var(--theme-navy);">82%</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress mb-4">
|
|
||||||
<div class="progress-bar progress-bar-navy" style="width:82%"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex justify-content-between mb-2">
|
|
||||||
<span class="fw-semibold" style="color: var(--theme-navy);">Attendance Score</span>
|
|
||||||
<span class="fw-bold" style="color: var(--theme-red);">90%</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress">
|
|
||||||
<div class="progress-bar progress-bar-red" style="width:90%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Download Section -->
|
|
||||||
<div class="download-card">
|
|
||||||
<div>
|
|
||||||
<h4>Download Official Result Sheet</h4>
|
|
||||||
<p class="mb-0">
|
|
||||||
Get your latest semester examination results in official PDF format.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-result shadow-sm">
|
<!-- Summary Cards -->
|
||||||
<i class="fas fa-download me-2"></i>Download PDF
|
<div class="row g-4">
|
||||||
</button>
|
<div class="col-md-4">
|
||||||
|
<div class="summary-card">
|
||||||
|
<i class="fas fa-chart-line"></i>
|
||||||
|
<h3>{{ $averageMarks ?? 0 }}%</h3>
|
||||||
|
<small>Overall Average</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="summary-card">
|
||||||
|
<i class="fas fa-medal"></i>
|
||||||
|
<h3>{{ $gpa ?? '3.65' }}</h3>
|
||||||
|
<small>Current GPA</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="summary-card">
|
||||||
|
<i class="fas fa-book-open"></i>
|
||||||
|
<h3>{{ $passedModules ?? 0 }} / {{ $totalModules ?? 0 }}</h3>
|
||||||
|
<small>Modules Passed</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Result Table -->
|
||||||
|
<div class="result-card">
|
||||||
|
<div class="table-head d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="mb-0 fw-bold">
|
||||||
|
Semester Results
|
||||||
|
</h5>
|
||||||
|
@if(isset($results) && $results->isNotEmpty())
|
||||||
|
<span class="badge bg-light text-dark">
|
||||||
|
{{ optional($results->first())->academic_year }} | {{ optional($results->first())->semester }}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover align-middle">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Module Code</th>
|
||||||
|
<th>Module Name</th>
|
||||||
|
<th>Marks</th>
|
||||||
|
<th>Grade</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
@forelse ($results ?? [] as $item)
|
||||||
|
<tr>
|
||||||
|
<td class="fw-bold" style="color: var(--theme-navy);">{{ $item->module_code }}</td>
|
||||||
|
<td class="fw-semibold">{{ $item->module_name }}</td>
|
||||||
|
<td>{{ $item->marks }}</td>
|
||||||
|
<td>
|
||||||
|
@php
|
||||||
|
$gradeClass = 'b';
|
||||||
|
$upperGrade = strtoupper($item->grade ?? '');
|
||||||
|
|
||||||
|
if(str_contains($upperGrade, 'A')) {
|
||||||
|
$gradeClass = 'a';
|
||||||
|
} elseif(str_contains($upperGrade, 'F')) {
|
||||||
|
$gradeClass = 'fail';
|
||||||
|
} elseif(str_contains($upperGrade, 'C')) {
|
||||||
|
$gradeClass = 'c';
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
<span class="grade {{ $gradeClass }}">{{ $item->grade }}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@if(strtolower($item->status ?? '') == 'pass')
|
||||||
|
<span class="status-pass"><i class="fas fa-check-circle me-1"></i>Pass</span>
|
||||||
|
@else
|
||||||
|
<span class="status-fail"><i class="fas fa-times-circle me-1"></i>Fail</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="text-center py-4 text-muted">
|
||||||
|
<i class="fas fa-info-circle me-1"></i> No result records found for your account.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div> <!-- End Printable Area Container -->
|
||||||
|
|
||||||
|
<!-- Performance & Download Section (Side by Side) -->
|
||||||
|
<div class="row g-4 align-items-stretch">
|
||||||
|
|
||||||
|
<!-- Overall Performance Card -->
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="result-card h-100 mt-0">
|
||||||
|
<div class="table-head">
|
||||||
|
<h5 class="mb-0 fw-bold">
|
||||||
|
Overall Performance
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 d-flex flex-column justify-content-center">
|
||||||
|
<div class="d-flex justify-content-between mb-2">
|
||||||
|
<span class="fw-semibold" style="color: var(--theme-navy);">Course Completion</span>
|
||||||
|
<span class="fw-bold" style="color: var(--theme-navy);">{{ $averageMarks ?? 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress mb-4">
|
||||||
|
<div class="progress-bar progress-bar-navy" style="width: {{ $averageMarks ?? 0 }}%"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between mb-2">
|
||||||
|
<span class="fw-semibold" style="color: var(--theme-navy);">Attendance Score</span>
|
||||||
|
<span class="fw-bold" style="color: var(--theme-red);">90%</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress">
|
||||||
|
<div class="progress-bar progress-bar-red" style="width: 90%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Download Section Card -->
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="download-card h-100 mt-0 flex-column justify-content-between align-items-start text-start">
|
||||||
|
<div>
|
||||||
|
<h4 class="mb-3">Download Official Result Sheet</h4>
|
||||||
|
<p class="mb-4">
|
||||||
|
Get your latest semester examination results in official PDF format.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="download-pdf-btn" onclick="generatePDF()" class="btn btn-result shadow-sm w-100">
|
||||||
|
<i class="fas fa-download me-2"></i>Download PDF
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- JavaScript to handle PDF Download -->
|
||||||
|
<script>
|
||||||
|
function generatePDF() {
|
||||||
|
const element = document.getElementById('pdf-download-area');
|
||||||
|
const button = document.getElementById('download-pdf-btn');
|
||||||
|
|
||||||
|
// Button status change while generating
|
||||||
|
button.disabled = true;
|
||||||
|
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Generating PDF...';
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
margin: [10, 10, 10, 10],
|
||||||
|
filename: 'Official_Result_Sheet.pdf',
|
||||||
|
image: { type: 'jpeg', quality: 0.98 },
|
||||||
|
html2canvas: { scale: 2, useCORS: true },
|
||||||
|
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generate PDF and restore button state
|
||||||
|
html2pdf().set(options).from(element).save().then(() => {
|
||||||
|
button.disabled = false;
|
||||||
|
button.innerHTML = '<i class="fas fa-download me-2"></i>Download PDF';
|
||||||
|
}).catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
button.disabled = false;
|
||||||
|
button.innerHTML = '<i class="fas fa-download me-2"></i>Download PDF';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -202,26 +202,33 @@ body {
|
||||||
<div class="today-card">
|
<div class="today-card">
|
||||||
<h5 class="mb-3">
|
<h5 class="mb-3">
|
||||||
<i class="fas fa-clock me-2" style="color: var(--theme-red);"></i>
|
<i class="fas fa-clock me-2" style="color: var(--theme-red);"></i>
|
||||||
Today's Schedule
|
Today's Schedule ({{ $todayName ?? 'Today' }})
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<div class="mb-3 p-2 rounded" style="background: #f8fafc; border-left: 3px solid var(--theme-navy);">
|
@forelse($todaySchedule ?? [] as $todayItem)
|
||||||
<strong>08:30 - 10:30</strong><br>
|
@php
|
||||||
<span class="badge badge-theory me-1">Theory</span>
|
$borderStyle = 'var(--theme-navy)';
|
||||||
<span>Engine Fundamentals</span>
|
$badgeClass = 'badge-theory';
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3 p-2 rounded" style="background: #f8fafc; border-left: 3px solid #e67e22;">
|
if(strtolower($todayItem->type) == 'practical') {
|
||||||
<strong>10:45 - 12:30</strong><br>
|
$borderStyle = 'var(--theme-red)';
|
||||||
<span class="badge badge-workshop me-1">Workshop</span>
|
$badgeClass = 'badge-practical';
|
||||||
<span>Practical Session</span>
|
} elseif(strtolower($todayItem->type) == 'workshop') {
|
||||||
</div>
|
$borderStyle = '#e67e22';
|
||||||
|
$badgeClass = 'badge-workshop';
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
|
||||||
<div class="p-2 rounded" style="background: #f8fafc; border-left: 3px solid var(--theme-red);">
|
<div class="mb-3 p-2 rounded" style="background: #f8fafc; border-left: 3px solid {{ $borderStyle }};">
|
||||||
<strong>01:30 - 03:30</strong><br>
|
<strong>{{ $todayItem->time_slot }}</strong><br>
|
||||||
<span class="badge badge-practical me-1">Practical</span>
|
<span class="badge {{ $badgeClass }} me-1">{{ $todayItem->type }}</span>
|
||||||
<span>Electrical System</span>
|
<span>{{ $todayItem->subject_name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@empty
|
||||||
|
<div class="p-3 text-center text-muted border rounded">
|
||||||
|
<i class="fas fa-coffee me-1"></i> No classes scheduled for today!
|
||||||
|
</div>
|
||||||
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -269,92 +276,65 @@ body {
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Time</th>
|
<th>Time</th>
|
||||||
<th>Monday</th>
|
@foreach($days as $day)
|
||||||
<th>Tuesday</th>
|
<th class="{{ ($todayName ?? '') == $day ? 'bg-danger text-white' : '' }}">
|
||||||
<th>Wednesday</th>
|
{{ $day }} {{ ($todayName ?? '') == $day ? '(Today)' : '' }}
|
||||||
<th>Thursday</th>
|
</th>
|
||||||
<th>Friday</th>
|
@endforeach
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
@forelse($timeSlots as $slot)
|
||||||
<th>08:30 - 10:30</th>
|
@php
|
||||||
<td>
|
// Lunch/Break Check
|
||||||
<span class="badge badge-theory mb-1">Theory</span><br>
|
$isBreakRow = false;
|
||||||
Engine Fundamentals
|
foreach($days as $d) {
|
||||||
</td>
|
if(isset($schedule[$slot][$d]) && strtolower($schedule[$slot][$d]->type) == 'break') {
|
||||||
<td>
|
$isBreakRow = true;
|
||||||
<span class="badge badge-practical mb-1">Practical</span><br>
|
break;
|
||||||
Engine Lab
|
}
|
||||||
</td>
|
}
|
||||||
<td>
|
@endphp
|
||||||
<span class="badge badge-theory mb-1">Theory</span><br>
|
|
||||||
Transmission
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="badge badge-workshop mb-1">Workshop</span><br>
|
|
||||||
Engine Repair
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="badge badge-theory mb-1">Theory</span><br>
|
|
||||||
Vehicle Safety
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
@if($isBreakRow)
|
||||||
<th>10:45 - 12:30</th>
|
<tr class="lunch-row">
|
||||||
<td>
|
<th>{{ $slot }}</th>
|
||||||
<span class="badge badge-workshop mb-1">Workshop</span><br>
|
<td colspan="5">
|
||||||
Service Practice
|
🍴 LUNCH BREAK / REST TIME
|
||||||
</td>
|
</td>
|
||||||
<td>
|
</tr>
|
||||||
<span class="badge badge-theory mb-1">Theory</span><br>
|
@else
|
||||||
Electrical
|
<tr>
|
||||||
</td>
|
<th>{{ $slot }}</th>
|
||||||
<td>
|
@foreach($days as $day)
|
||||||
<span class="badge badge-practical mb-1">Practical</span><br>
|
<td>
|
||||||
Diagnostics
|
@if(isset($schedule[$slot][$day]))
|
||||||
</td>
|
@php
|
||||||
<td>
|
$cell = $schedule[$slot][$day];
|
||||||
<span class="badge badge-theory mb-1">Theory</span><br>
|
$typeClass = 'badge-theory';
|
||||||
Fuel System
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="badge badge-workshop mb-1">Workshop</span><br>
|
|
||||||
Engine Assembly
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr class="lunch-row">
|
if(strtolower($cell->type) == 'practical') {
|
||||||
<th>12:30 - 01:30</th>
|
$typeClass = 'badge-practical';
|
||||||
<td colspan="5">
|
} elseif(strtolower($cell->type) == 'workshop') {
|
||||||
🍴 LUNCH BREAK
|
$typeClass = 'badge-workshop';
|
||||||
</td>
|
}
|
||||||
</tr>
|
@endphp
|
||||||
|
<span class="badge {{ $typeClass }} mb-1">{{ $cell->type }}</span><br>
|
||||||
<tr>
|
{{ $cell->subject_name }}
|
||||||
<th>01:30 - 03:30</th>
|
@else
|
||||||
<td>
|
<span class="text-muted">-</span>
|
||||||
<span class="badge badge-practical mb-1">Practical</span><br>
|
@endif
|
||||||
Electrical System
|
</td>
|
||||||
</td>
|
@endforeach
|
||||||
<td>
|
</tr>
|
||||||
<span class="badge badge-workshop mb-1">Workshop</span><br>
|
@endif
|
||||||
Welding
|
@empty
|
||||||
</td>
|
<tr>
|
||||||
<td>
|
<td colspan="6" class="text-center py-4 text-muted">
|
||||||
<span class="badge badge-theory mb-1">Theory</span><br>
|
<i class="fas fa-info-circle me-1"></i> No timetable data available right now.
|
||||||
Auto Electronics
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
<td>
|
@endforelse
|
||||||
<span class="badge badge-practical mb-1">Practical</span><br>
|
|
||||||
Brake System
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="badge badge-theory mb-1">Theory</span><br>
|
|
||||||
Revision
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ use App\Http\Controllers\studentportalnavController;
|
||||||
use App\Http\Controllers\Auth\ForgotPasswordController;
|
use App\Http\Controllers\Auth\ForgotPasswordController;
|
||||||
use App\Http\Controllers\coursesController;
|
use App\Http\Controllers\coursesController;
|
||||||
use App\Http\Controllers\ApplyController;
|
use App\Http\Controllers\ApplyController;
|
||||||
|
use App\Http\Controllers\ResultsController;
|
||||||
|
use App\Http\Controllers\TimetableController; // 1. TimetableController එක Import කළා
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -78,49 +80,44 @@ Route::post('/studentlogout', [StudentPortalController::class, 'studentlogout'])
|
||||||
// Student Portal Section (Protected by Student Session Check)
|
// Student Portal Section (Protected by Student Session Check)
|
||||||
Route::middleware(['web'])->group(function () {
|
Route::middleware(['web'])->group(function () {
|
||||||
|
|
||||||
// Main Portal Landing Page
|
|
||||||
Route::get('/student-portal', function () {
|
Route::get('/student-portal', function () {
|
||||||
if (!session()->has('student_id')) {
|
if (!session()->has('student_id') && !session()->has('student_log_id')) {
|
||||||
return redirect('/signin')->with('error', 'Please login first!');
|
return redirect('/signin')->with('error', 'Please login first!');
|
||||||
}
|
}
|
||||||
return view('StudentPortal');
|
return view('StudentPortal');
|
||||||
})->name('student.portal');
|
})->name('student.portal');
|
||||||
|
|
||||||
// Profile Page (DB Dynamic Data)
|
|
||||||
Route::get('/StudentProfile', [StudentPortalController::class, 'showProfile'])->name('StudentProfile');
|
Route::get('/StudentProfile', [StudentPortalController::class, 'showProfile'])->name('StudentProfile');
|
||||||
|
|
||||||
// Other Navigation Sub-pages
|
|
||||||
|
Route::get('/results', [ResultsController::class, 'index'])->name('results');
|
||||||
|
|
||||||
|
|
||||||
Route::get('/Dashboard', function () {
|
Route::get('/Dashboard', function () {
|
||||||
if (!session()->has('student_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
if (!session()->has('student_id') && !session()->has('student_log_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
||||||
return view('StudentPortal');
|
return view('StudentPortal');
|
||||||
})->name('Dashboard');
|
})->name('Dashboard');
|
||||||
|
|
||||||
Route::get('/mycourse', function () {
|
Route::get('/mycourse', function () {
|
||||||
if (!session()->has('student_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
if (!session()->has('student_id') && !session()->has('student_log_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
||||||
return view('mycourse');
|
return view('mycourse');
|
||||||
})->name('mycourse');
|
})->name('mycourse');
|
||||||
|
|
||||||
Route::get('/timetable', function () {
|
// 2. Dynamic Timetable Controller Route එක මෙතැනට යෙදුවා
|
||||||
if (!session()->has('student_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
Route::get('/timetable', [TimetableController::class, 'index'])->name('timetable');
|
||||||
return view('timetable');
|
|
||||||
})->name('timetable');
|
|
||||||
|
|
||||||
Route::get('/Assignments', function () {
|
Route::get('/Assignments', function () {
|
||||||
if (!session()->has('student_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
if (!session()->has('student_id') && !session()->has('student_log_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
||||||
return view('Assignments');
|
return view('Assignments');
|
||||||
})->name('Assignments');
|
})->name('Assignments');
|
||||||
|
|
||||||
Route::get('/Studentguidelines', function () {
|
Route::get('/Studentguidelines', function () {
|
||||||
if (!session()->has('student_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
if (!session()->has('student_id') && !session()->has('student_log_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
||||||
return view('Studentguidelines');
|
return view('Studentguidelines');
|
||||||
})->name('Studentguidelines');
|
})->name('Studentguidelines');
|
||||||
|
|
||||||
Route::get('/results', function () {
|
|
||||||
if (!session()->has('student_id')) { return redirect('/signin')->with('error', 'Please login first!'); }
|
|
||||||
return view('results');
|
|
||||||
})->name('results');
|
|
||||||
|
|
||||||
|
|
||||||
Route::get('/Feedback&Complain', [FeedbackController::class, 'index'])->name('feedback.index');
|
Route::get('/Feedback&Complain', [FeedbackController::class, 'index'])->name('feedback.index');
|
||||||
Route::post('/Feedback&Complain/store', [FeedbackController::class, 'store'])->name('feedback.store');
|
Route::post('/Feedback&Complain/store', [FeedbackController::class, 'store'])->name('feedback.store');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue