set my courses module 1
This commit is contained in:
parent
5a9580a568
commit
8c953d0e46
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class MyCoursesController extends Controller
|
||||
{
|
||||
public function showMyCourses()
|
||||
{
|
||||
|
||||
$userId = session('student_portal_log_id')
|
||||
?? session('student_id')
|
||||
?? session('id')
|
||||
?? Auth::id();
|
||||
|
||||
|
||||
$student = DB::table('student_details')
|
||||
->where('student_portal_log_id', $userId)
|
||||
->orWhere('id', $userId)
|
||||
->orWhere('student_id', $userId)
|
||||
->first();
|
||||
|
||||
|
||||
if (!$student) {
|
||||
return view('mycourse', [
|
||||
'courses' => collect([]),
|
||||
'student' => null
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$courses = DB::table('courses')
|
||||
->join('course_assign_student', 'courses.id', '=', 'course_assign_student.course_id')
|
||||
->whereIn('course_assign_student.student_id', [
|
||||
$student->id,
|
||||
$student->student_id,
|
||||
$student->student_portal_log_id
|
||||
])
|
||||
->select('courses.*', 'course_assign_student.assigned_at')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
return view('mycourse', compact('courses', 'student'));
|
||||
}
|
||||
|
||||
|
||||
public function showModule($course_id)
|
||||
{
|
||||
$course = DB::table('courses')->where('id', $course_id)->first();
|
||||
|
||||
if (!$course) {
|
||||
abort(404, 'Course not found');
|
||||
}
|
||||
|
||||
$modules = DB::table('modules')
|
||||
->where('course_id', $course_id)
|
||||
->get();
|
||||
|
||||
return view('module', compact('course', 'modules'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,6 +5,10 @@ namespace App\Http\Controllers;
|
|||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Models\CourseAssignStudent;
|
||||
use App\Models\Course;
|
||||
use App\Models\studentDetails;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class adminmycoursesController extends Controller
|
||||
{
|
||||
|
|
@ -25,7 +29,10 @@ class adminmycoursesController extends Controller
|
|||
->get();
|
||||
}
|
||||
|
||||
return view('admin.adminmycourses', compact('courses'));
|
||||
// Needed for the "Assign Course to Students" modal on this page
|
||||
$students = studentDetails::all();
|
||||
|
||||
return view('admin.adminmycourses', compact('courses', 'students'));
|
||||
}
|
||||
|
||||
// --- COURSE CRUD METHODS ---
|
||||
|
|
@ -69,50 +76,47 @@ class adminmycoursesController extends Controller
|
|||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'course_code' => 'required|string|max:50',
|
||||
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,webp|max:2048',
|
||||
'duration' => 'required|string',
|
||||
'level' => 'required|string',
|
||||
'status' => 'required|string',
|
||||
]);
|
||||
{
|
||||
$request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'course_code' => 'required|string|max:50',
|
||||
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,webp|max:2048',
|
||||
'duration' => 'required|string',
|
||||
'level' => 'required|string',
|
||||
'status' => 'required|string',
|
||||
]);
|
||||
|
||||
$course = DB::table('courses')->where('id', $id)->first();
|
||||
$course = DB::table('courses')->where('id', $id)->first();
|
||||
|
||||
if (!$course) {
|
||||
return redirect()->back()->with('error', 'Course not found!');
|
||||
}
|
||||
|
||||
$imagePath = $course->image;
|
||||
if ($request->hasFile('image')) {
|
||||
if ($course->image && Storage::disk('public')->exists($course->image)) {
|
||||
Storage::disk('public')->delete($course->image);
|
||||
if (!$course) {
|
||||
return redirect()->back()->with('error', 'Course not found!');
|
||||
}
|
||||
$imagePath = $request->file('image')->store('courses', 'public');
|
||||
|
||||
$imagePath = $course->image;
|
||||
if ($request->hasFile('image')) {
|
||||
if ($course->image && Storage::disk('public')->exists($course->image)) {
|
||||
Storage::disk('public')->delete($course->image);
|
||||
}
|
||||
$imagePath = $request->file('image')->store('courses', 'public');
|
||||
}
|
||||
|
||||
DB::table('courses')->where('id', $id)->update([
|
||||
'title' => $request->title,
|
||||
'course_code' => $request->course_code,
|
||||
'image' => $imagePath,
|
||||
'duration' => $request->duration,
|
||||
'level' => $request->level,
|
||||
'author' => $request->author ?? $course->author ?? 'Admin',
|
||||
'desc' => $request->desc ?? $request->description ?? $course->desc,
|
||||
'badge' => $request->badge ?? $course->badge,
|
||||
'trending' => $request->has('trending') ? 1 : 0,
|
||||
'status' => $request->status,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'Course updated successfully!');
|
||||
}
|
||||
|
||||
DB::table('courses')->where('id', $id)->update([
|
||||
'title' => $request->title,
|
||||
'course_code' => $request->course_code,
|
||||
'image' => $imagePath,
|
||||
'duration' => $request->duration,
|
||||
'level' => $request->level,
|
||||
|
||||
'author' => $request->author ?? $course->author ?? 'Admin',
|
||||
|
||||
'desc' => $request->desc ?? $request->description ?? $course->desc,
|
||||
'badge' => $request->badge ?? $course->badge,
|
||||
'trending' => $request->has('trending') ? 1 : 0,
|
||||
'status' => $request->status,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'Course updated successfully!');
|
||||
}
|
||||
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$course = DB::table('courses')->where('id', $id)->first();
|
||||
|
|
@ -186,4 +190,42 @@ class adminmycoursesController extends Controller
|
|||
DB::table('course_modules')->where('id', $id)->delete();
|
||||
return redirect()->back()->with('success', 'Module deleted successfully!');
|
||||
}
|
||||
}
|
||||
|
||||
// --- ASSIGN COURSE TO STUDENTS ---
|
||||
|
||||
/**
|
||||
* Handles the POST from the "Assign Course to Students" modal.
|
||||
* Route name: assign.course
|
||||
*/
|
||||
public function assignCourse(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'course_id' => 'required|exists:courses,id',
|
||||
'student_ids' => 'required|array|min:1',
|
||||
'student_ids.*' => 'exists:student_details,id',
|
||||
]);
|
||||
|
||||
foreach ($request->student_ids as $studentId) {
|
||||
|
||||
CourseAssignStudent::updateOrCreate(
|
||||
[
|
||||
'course_id' => $request->course_id,
|
||||
'student_id' => $studentId,
|
||||
]
|
||||
);
|
||||
// CourseAssignStudent::updateOrCreate(
|
||||
// [
|
||||
// 'course_id' => $request->course_id,
|
||||
// 'student_id' => $studentId,
|
||||
// ],
|
||||
// [
|
||||
// 'assigned_at' => now(),
|
||||
// ]
|
||||
// );
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', 'Course assigned to selected students successfully!');
|
||||
}
|
||||
}
|
||||
|
||||
Schema::getColumnListing('course_assign_student');
|
||||
|
|
@ -14,8 +14,9 @@ class CourseAssignStudent extends Model
|
|||
|
||||
// Mass assignable attributes
|
||||
protected $fillable = [
|
||||
'student_details_id',
|
||||
'student_id',
|
||||
'course_id',
|
||||
'assigned_at',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -23,7 +24,7 @@ class CourseAssignStudent extends Model
|
|||
*/
|
||||
public function studentDetail()
|
||||
{
|
||||
return $this->belongsTo(StudentDetail::class, 'student_details_id');
|
||||
return $this->belongsTo(StudentDetail::class, 'student_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -33,4 +34,4 @@ class CourseAssignStudent extends Model
|
|||
{
|
||||
return $this->belongsTo(Course::class, 'course_id');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?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::table('course_assign_student', function (Blueprint $table) {
|
||||
$table->foreignId('student_id')->constrained('student_details')->onDelete('cascade');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('course_assign_student', function (Blueprint $table) {
|
||||
$table->dropForeign(['student_id']);
|
||||
$table->dropColumn('student_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -5,11 +5,11 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>Course Management - Admin Portal</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 href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--theme-navy: #2D355B;
|
||||
|
|
@ -94,9 +94,9 @@
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebar .nav-link i {
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
.sidebar .nav-link i {
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover {
|
||||
|
|
@ -195,7 +195,7 @@
|
|||
<i class="fa-solid fa-car-side me-2"></i> AutoEdu
|
||||
<span class="admin-badge">Admin</span>
|
||||
</div>
|
||||
|
||||
|
||||
<nav class="nav">
|
||||
<a href="{{ route('admin.dashboard') }}" class="nav-link">
|
||||
<i class="fa-solid fa-chart-line"></i> Admin Dashboard
|
||||
|
|
@ -295,15 +295,15 @@
|
|||
<td class="text-center">
|
||||
<div class="d-flex justify-content-center gap-1">
|
||||
<!-- View Modules Button -->
|
||||
<button class="btn btn-sm btn-outline-info"
|
||||
data-bs-toggle="modal"
|
||||
<button class="btn btn-sm btn-outline-info"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modulesModal{{ $course->id }}">
|
||||
<i class="fa-solid fa-layer-group me-1"></i> Modules
|
||||
</button>
|
||||
|
||||
<!-- Edit Course Button -->
|
||||
<button class="btn btn-sm btn-outline-warning"
|
||||
data-bs-toggle="modal"
|
||||
<button class="btn btn-sm btn-outline-warning"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#editCourseModal{{ $course->id }}">
|
||||
<i class="fa-solid fa-pen-to-square"></i> Edit
|
||||
</button>
|
||||
|
|
@ -428,8 +428,8 @@
|
|||
@endif
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<button class="btn btn-sm btn-outline-warning"
|
||||
data-bs-toggle="collapse"
|
||||
<button class="btn btn-sm btn-outline-warning"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#editModuleCollapse{{ $module->id }}">
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</button>
|
||||
|
|
@ -508,12 +508,14 @@
|
|||
<div class="mb-3">
|
||||
<label class="form-label">Semester</label>
|
||||
<select name="semester" class="form-select" required>
|
||||
<option value="Semester 1">Semester 1</option>
|
||||
<option value="Semester 2">Semester 2</option>
|
||||
<option value="Semester 3">Semester 3</option>
|
||||
<option value="Semester 4">Semester 4</option>
|
||||
<option value="Year 1">Year 1</option>
|
||||
<option value="Year 2">Year 2</option>
|
||||
<option value="Semester 1.1">Semester 1.1</option>
|
||||
<option value="Semester 1.2">Semester 1.2</option>
|
||||
<option value="Semester 2.1">Semester 2.1</option>
|
||||
<option value="Semester 2.2">Semester 2.2</option>
|
||||
<option value="Semester 3.1">Semester 3.1</option>
|
||||
<option value="Semester 3.2">Semester 3.2</option>
|
||||
<option value="Semester 4.1">Semester 4.1</option>
|
||||
<option value="Semester 4.2">Semester 4.2</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
|
|
@ -554,8 +556,67 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Assign Courses to Students -->
|
||||
<div class="card border-0 shadow-sm rounded-3 mt-4">
|
||||
<div class="card-body d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h5 class="fw-bold mb-1"><i class="fa-solid fa-user-graduate me-2 text-primary"></i>Assign Courses to Students</h5>
|
||||
<p class="text-muted mb-0 small">Enroll one or more students into an existing course.</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#assignCourseModal">
|
||||
<i class="fa-solid fa-user-plus me-1"></i> Assign Course
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- ASSIGN COURSE TO STUDENTS MODAL -->
|
||||
<div class="modal fade" id="assignCourseModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header text-white" style="background-color: var(--theme-navy);">
|
||||
<h5 class="modal-title fw-bold text-white"><i class="fa-solid fa-user-plus me-2"></i>Assign Course to Students</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
|
||||
<!-- Route name: assign.course -->
|
||||
<form action="{{ route('assign.course') }}" method="POST">
|
||||
@csrf
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Select Course</label>
|
||||
<select name="course_id" class="form-select" required>
|
||||
<option value="" selected disabled>-- Choose Course --</option>
|
||||
@foreach($courses as $course)
|
||||
<option value="{{ $course->id }}">{{ $course->course_code }} - {{ $course->title }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">Select Student(s)</label>
|
||||
<select name="student_ids[]" class="form-select" multiple size="8" required>
|
||||
@forelse($students as $student)
|
||||
<option value="{{ $student->id }}">{{ $student->full_name }} ({{ $student->student_id ?? $student->email }})</option>
|
||||
@empty
|
||||
<option value="" disabled>No students found</option>
|
||||
@endforelse
|
||||
</select>
|
||||
<small class="text-muted">Hold Ctrl (Windows) / Cmd (Mac) to select multiple students.</small>
|
||||
</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-check me-1"></i> Assign Course
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ADD NEW COURSE MODAL -->
|
||||
<div class="modal fade" id="addCourseModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
|
|
|
|||
|
|
@ -1,358 +1,108 @@
|
|||
@extends('layouts.studentportalnav')
|
||||
|
||||
@section('title', 'My Course')
|
||||
@section('title', 'Course Modules')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--theme-navy: #2D355B; /* Primary Navy */
|
||||
--theme-navy-dark: #1F2541; /* Dark Navy */
|
||||
--theme-red: #822424; /* Primary Accent Red */
|
||||
--theme-red-hover: #df2c3e; /* Red Hover */
|
||||
--theme-yellow: #FFEA85; /* Accent Yellow/Gold */
|
||||
--bg-light: #F6F6F6; /* Page Background */
|
||||
--theme-navy: #2D355B;
|
||||
--theme-red: #822424;
|
||||
--theme-red-hover: #df2c3e;
|
||||
--bg-light: #F6F6F6;
|
||||
--white: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--bg-light);
|
||||
font-family: 'Segoe UI', sans-serif;
|
||||
}
|
||||
body { background: var(--bg-light); font-family: 'Segoe UI', sans-serif; }
|
||||
|
||||
.main-portal-content {
|
||||
padding: 10px 5px;
|
||||
min-height: 100vh;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Premium Hero Section */
|
||||
.hero {
|
||||
background: linear-gradient(135deg, #2B293F 0%, #94A6F959 100%) !important;
|
||||
color: var(--white) !important;
|
||||
.module-header {
|
||||
background: linear-gradient(135deg, #2B293F 0%, #94A6F959 100%);
|
||||
color: var(--white);
|
||||
border-radius: 16px;
|
||||
padding: 35px 30px;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 8px 25px rgba(31, 37, 65, 0.15);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 30px;
|
||||
margin-bottom: 25px;
|
||||
border-left: 5px solid var(--theme-red);
|
||||
}
|
||||
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -30%;
|
||||
right: -10%;
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Course Card */
|
||||
.course-card {
|
||||
border: 1px solid #e2e8f0 !important;
|
||||
border-radius: 16px !important;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05) !important;
|
||||
background: var(--white);
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.course-card img {
|
||||
height: 240px;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Sidebar Info Boxes */
|
||||
.info-box {
|
||||
border-radius: 12px !important;
|
||||
padding: 20px 24px;
|
||||
background: var(--white);
|
||||
box-shadow: 0 4px 12px rgba(219, 240, 99, 0.04) !important;
|
||||
border: 1px solid #e2e8f0 !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.info-box:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08) !important;
|
||||
border-color: var(--theme-navy) !important;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
font-size: 18px;
|
||||
background: var(--theme-red) !important;
|
||||
color: #ffff8d;
|
||||
}
|
||||
|
||||
/* Modules Card */
|
||||
.module-card {
|
||||
border: 1px solid #e2e8f0 !important;
|
||||
border-radius: 14px !important;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
background: var(--white);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03) !important;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.04);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.module-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.08) !important;
|
||||
border-color: var(--theme-red) !important;
|
||||
transform: translateY(-2px);
|
||||
border-color: var(--theme-navy);
|
||||
}
|
||||
|
||||
/* Progress bar customizations */
|
||||
.progress {
|
||||
height: 10px !important;
|
||||
border-radius: 50px !important;
|
||||
background-color: #e2e8f0 !important;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
border-radius: 50px !important;
|
||||
background: linear-gradient(90deg, var(--theme-red), var(--theme-red-hover)) !important;
|
||||
}
|
||||
|
||||
/* Status Badges */
|
||||
.status {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
padding: 6px 14px;
|
||||
border-radius: 50px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.completed { background: rgba(45, 53, 91, 0.12); color: var(--theme-navy); }
|
||||
.progressing { background: rgba(247, 63, 82, 0.15); color: var(--theme-red); }
|
||||
.locked { background: #e2e8f0; color: #64748b; }
|
||||
|
||||
/* Custom Buttons */
|
||||
.btn-theme-red {
|
||||
background-color: var(--theme-red) !important;
|
||||
border-color: var(--theme-red) !important;
|
||||
color: #fff !important;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.btn-theme-red:hover {
|
||||
background-color: var(--theme-red-hover) !important;
|
||||
border-color: var(--theme-red-hover) !important;
|
||||
}
|
||||
|
||||
.btn-theme-navy {
|
||||
background-color: var(--theme-navy) !important;
|
||||
border-color: var(--theme-navy) !important;
|
||||
color: #fff !important;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.btn-theme-navy:hover {
|
||||
background-color: var(--theme-navy-dark) !important;
|
||||
}
|
||||
|
||||
.btn-continue {
|
||||
background-color: var(--theme-red) !important;
|
||||
color: #ffffff !important;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.btn-continue:hover {
|
||||
background-color: var(--theme-red-hover) !important;
|
||||
}
|
||||
|
||||
/* Section Title Indicator */
|
||||
.section-title-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin: 30px 0 20px;
|
||||
}
|
||||
|
||||
.section-title-wrapper::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 5px;
|
||||
height: 24px;
|
||||
background-color: var(--theme-red);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.main-portal-content { padding: 10px; }
|
||||
.hero { padding: 40px; }
|
||||
.course-card img { height: 280px; }
|
||||
.semester-badge {
|
||||
background-color: var(--theme-navy);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="main-portal-content">
|
||||
<div class="main-portal-content p-3">
|
||||
<div class="container-fluid">
|
||||
|
||||
@if($course)
|
||||
<!-- Back Button -->
|
||||
<a href="{{ route('mycourse') }}" class="btn btn-outline-secondary btn-sm mb-3">
|
||||
<i class="fa fa-arrow-left me-1"></i> Back to My Courses
|
||||
</a>
|
||||
|
||||
{{-- Dynamic Image URL Handler --}}
|
||||
@php
|
||||
$imageSrc = Str::startsWith($course->image, ['http://', 'https://'])
|
||||
? $course->image
|
||||
: asset('storage/' . $course->image);
|
||||
@endphp
|
||||
<!-- Course Header -->
|
||||
<div class="module-header">
|
||||
<h2 class="fw-bold mb-1">{{ $course->title ?? $course->name ?? 'Course Modules' }}</h2>
|
||||
<p class="mb-0 opacity-75">{{ $course->course_code ?? '' }} {{ isset($course->desc) ? '| '.$course->desc : '' }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<div class="hero">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-9 col-md-8 text-start">
|
||||
<h1 class="fw-bold display-6 mb-2">{{ $course->title }}</h1>
|
||||
<p class="lead mb-4 small opacity-75">Welcome back! Continue your learning journey and complete all modules.</p>
|
||||
<a href="#" class="btn btn-continue px-4 py-2 fw-semibold shadow-sm">
|
||||
<i class="fa fa-play me-2"></i> Continue Learning
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-4 text-center d-none d-md-block">
|
||||
<i class="fa-solid fa-graduation-cap" style="font-size: 140px; opacity: 0.35; color: #8C080F;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="fw-bold mb-4" style="color: var(--theme-navy);">Modules List</h4>
|
||||
|
||||
<!-- Main Content Grid -->
|
||||
<div class="row g-4">
|
||||
|
||||
<!-- LEFT COLUMN: Course details & Modules -->
|
||||
<div class="col-lg-8 col-12">
|
||||
|
||||
<!-- Main Course Card -->
|
||||
<div class="card course-card">
|
||||
<img src="{{ $imageSrc }}" alt="{{ $course->title }}" onerror="this.onerror=null;this.src='https://images.unsplash.com/photo-1486262715619-67b85e0b08d3?auto=format&fit=crop&w=1200&q=80';">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-start gap-2 mb-3">
|
||||
@if(isset($modules) && count($modules) > 0)
|
||||
<div class="row g-3">
|
||||
@foreach($modules as $index => $module)
|
||||
<div class="col-12">
|
||||
<div class="card module-card p-4">
|
||||
<div class="d-flex justify-content-between align-items-start flex-wrap gap-2">
|
||||
<div>
|
||||
<h3 class="fw-bold mb-1" style="color: var(--theme-navy);">{{ $course->course_code ?? $course->title }}</h3>
|
||||
@if(!empty($module->semester))
|
||||
<span class="semester-badge mb-2 d-inline-block">
|
||||
Semester {{ $module->semester }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
<h5 class="fw-bold text-dark mb-2">
|
||||
Module {{ $index + 1 }}: {{ $module->title }}
|
||||
</h5>
|
||||
|
||||
<p class="text-muted small mb-0">
|
||||
<i class="fa-solid fa-user me-1" style="color: var(--theme-red);"></i> {{ $course->author ?? 'Instructor' }}
|
||||
{{ $module->description ?? 'No description provided.' }}
|
||||
</p>
|
||||
</div>
|
||||
<span class="badge px-3 py-2 rounded-pill" style="background-color: var(--theme-navy); color: var(--theme-yellow);">
|
||||
{{ $course->badge ?? 'Active Course' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="text-secondary small lh-base">
|
||||
{{ $course->desc ?? 'No description available for this course.' }}
|
||||
</p>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="d-flex justify-content-between mb-2 small">
|
||||
<span class="fw-semibold" style="color: var(--theme-navy);">Overall Progress</span>
|
||||
<span class="fw-bold" style="color: var(--theme-red);">0%</span>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" style="width:0%"></div>
|
||||
<div>
|
||||
<a href="#" class="btn btn-sm text-white px-3 py-2" style="background-color: var(--theme-red); border-radius: 6px;">
|
||||
View Content <i class="fa fa-chevron-right ms-1"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modules Header -->
|
||||
<div class="section-title-wrapper">
|
||||
<h4 class="fw-bold mb-0" style="color: var(--theme-navy);">
|
||||
Course Modules
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<!-- Modules Sub-Grid (Sample Modules Interface) -->
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6 col-12">
|
||||
<div class="card module-card h-100">
|
||||
<div class="card-body p-4 d-flex flex-column justify-content-between">
|
||||
<div>
|
||||
<div class="d-flex justify-content-between align-items-start gap-2 mb-2">
|
||||
<h6 class="fw-bold mb-0" style="color: var(--theme-navy);">Introduction & Fundamentals</h6>
|
||||
<span class="status progressing">In Progress</span>
|
||||
</div>
|
||||
<p class="text-muted small mb-0">Basic concepts and core theories.</p>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<button type="button" onclick="goToModule(1)" class="btn btn-theme-red w-100 btn-sm py-2">
|
||||
Continue Learning
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- RIGHT COLUMN: Sidebar Statistics -->
|
||||
<div class="col-lg-4 col-12">
|
||||
<div class="row g-3">
|
||||
<div class="col-12">
|
||||
<div class="info-box d-flex align-items-center">
|
||||
<div class="stat-icon"><i class="fa fa-layer-group"></i></div>
|
||||
<div class="ms-3">
|
||||
<h5 class="fw-bold mb-0" style="color: var(--theme-navy);">{{ $course->level ?? 'General' }}</h5>
|
||||
<span class="text-muted small">Course Level</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="info-box d-flex align-items-center">
|
||||
<div class="stat-icon"><i class="fa fa-clock"></i></div>
|
||||
<div class="ms-3">
|
||||
<h5 class="fw-bold mb-0" style="color: var(--theme-navy);">{{ $course->duration ?? 'N/A' }}</h5>
|
||||
<span class="text-muted small">Course Duration</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="info-box d-flex align-items-center">
|
||||
<div class="stat-icon"><i class="fa fa-award"></i></div>
|
||||
<div class="ms-3">
|
||||
<h5 class="fw-bold mb-0" style="color: var(--theme-navy);">{{ $course->status ?? 'Enrolled' }}</h5>
|
||||
<span class="text-muted small">Status</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- End Row -->
|
||||
|
||||
@else
|
||||
|
||||
<!-- Empty State: When no course is assigned -->
|
||||
<div class="row justify-content-center py-5">
|
||||
<div class="col-md-8 text-center">
|
||||
<div class="p-5 rounded-4 shadow-sm bg-white border">
|
||||
<i class="fas fa-graduation-cap fa-4x text-muted mb-3"></i>
|
||||
<h3 class="fw-bold text-dark mb-2">No Assigned Course Found</h3>
|
||||
<p class="text-muted mb-0">You do not have any course assigned to your profile yet. Please contact the administration for assistance.</p>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<!-- Empty State -->
|
||||
<div class="bg-white p-5 text-center rounded-3 border">
|
||||
<i class="fas fa-book-open fa-3x text-muted mb-3"></i>
|
||||
<h5 class="fw-bold">No Modules Found</h5>
|
||||
<p class="text-muted mb-0">There are no modules found for this course.</p>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function goToModule(moduleId) {
|
||||
|
||||
window.location.href = "{{ url('/module') }}/" + moduleId;
|
||||
}
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
|
|
@ -20,7 +20,7 @@ use App\Http\Controllers\AdminTimetableController;
|
|||
use App\Http\Controllers\AdminDashboardController;
|
||||
use App\Http\Controllers\welcomeController;
|
||||
use App\Http\Controllers\DocumentDownloadController;
|
||||
|
||||
use App\Http\Controllers\MyCoursesController;
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Public Routes & General Pages
|
||||
|
|
@ -117,6 +117,14 @@ Route::middleware(['web'])->group(function () {
|
|||
Route::get('/mycourse', [CoureseAssignController::class, 'showMyCourse'])->name('mycourse');
|
||||
Route::get('/module/{id}', [CoureseAssignController::class, 'showModule'])->name('module.show');
|
||||
|
||||
Route::get('/mycourse', [MyCoursesController::class, 'showMyCourses'])->name('mycourse');
|
||||
|
||||
|
||||
Route::get('/course/{course_id}/modules', [MyCoursesController::class, 'showModule'])->name('course.modules');
|
||||
|
||||
|
||||
Route::get('/mycourse', [MyCoursesController::class, 'showMyCourses'])->name('mycourse');
|
||||
// Route::get('/module/{course_id}', [MyCoursesController::class, 'showModule'])->name('course.modules');
|
||||
/* Document Downloads */
|
||||
Route::get('/student/download/calendar', [DocumentDownloadController::class, 'downloadAcademicCalendar'])->name('student.download.calendar');
|
||||
Route::get('/student/download/handbook', [DocumentDownloadController::class, 'downloadStudentHandbook'])->name('student.download.handbook');
|
||||
|
|
@ -165,6 +173,8 @@ Route::middleware(['web'])->prefix('admin')->group(function () {
|
|||
Route::post('/adminmycourses/store', [adminmycoursesController::class, 'store'])->name('admin.courses.store');
|
||||
Route::post('/adminmycourses/update/{id}', [adminmycoursesController::class, 'update'])->name('admin.courses.update');
|
||||
Route::delete('/courses/{id}', [adminmycoursesController::class, 'destroy'])->name('admin.courses.delete');
|
||||
Route::post('/admin/assign-course', [adminmycoursesController::class, 'assignCourse'])
|
||||
->name('assign.course');
|
||||
|
||||
// Admin Timetable Routes
|
||||
Route::get('/timetable', [AdminTimetableController::class, 'index'])->name('admin.timetable');
|
||||
|
|
|
|||
Loading…
Reference in New Issue