Skip to content

Commit

Permalink
Merge branch 'course-management-system' into release-2.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
NuwanJ committed Oct 16, 2024
1 parent 249c532 commit 69cb896
Show file tree
Hide file tree
Showing 27 changed files with 1,287 additions and 170 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/laravel_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"

- name: Remove existing composer.lock
run: rm ./composer.lock

- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/laravel_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,24 @@ jobs:
- uses: actions/checkout@v2
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"

- name: Remove existing composer.lock
run: rm ./composer.lock

- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

- name: Generate key
run: php artisan key:generate

- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache

- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
- name: Execute tests (Unit and Feature tests) via PHPUnit
env:
DB_CONNECTION: sqlite
Expand Down
25 changes: 21 additions & 4 deletions app/Domains/AcademicProgram/Course/Models/Course.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
namespace App\Domains\AcademicProgram\Course\Models;

use App\Domains\Auth\Models\User;
use App\Domains\AcademicProgram\AcademicProgram;
use App\Domains\AcademicProgram\Course\Models\Traits\Scope\CourseScope;
use App\Domains\AcademicProgram\Semester\Models\Semester;
use Database\Factories\CourseFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Spatie\Activitylog\Traits\LogsActivity;
use App\Domains\AcademicProgram\AcademicProgram;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use App\Domains\AcademicProgram\Semester\Models\Semester;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use App\Domains\AcademicProgram\Course\Models\Traits\Scope\CourseScope;

/**
* Class Course.
Expand Down Expand Up @@ -129,6 +130,22 @@ public function modules()
return $this->hasMany(CourseModule::class);
}

/**
* Get the prerequisites for the course.
*/
public function prerequisites(): BelongsToMany
{
return $this->belongsToMany(Course::class, 'course_prerequisites', 'course_id', 'prerequisite_id');
}

/**
* Get the courses where this course is a prerequisite.
*/
public function prerequisiteFor(): BelongsToMany
{
return $this->belongsToMany(Course::class, 'course_prerequisites', 'prerequisite_id', 'course_id');
}

protected static function newFactory()
{
return CourseFactory::new();
Expand Down
13 changes: 13 additions & 0 deletions app/Domains/Event/Models/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Event extends Model
protected $fillable = [
'title',
'url',
'event_type',
'published_at',
'description',
'image',
Expand All @@ -46,8 +47,20 @@ class Event extends Model
*/
protected $casts = [
'enabled' => 'boolean',
'event_type' => 'array',
];

public static function eventTypeMap(): array
{
// TODO integrate with Taxonomies
return [
0 => 'Event',
1 => 'Seminar',
2 => 'ACES',

];
}

public function thumbURL()
{
if ($this->image != null) return '/img/events/' . $this->image;
Expand Down
71 changes: 2 additions & 69 deletions app/Http/Controllers/Backend/CourseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,39 +41,6 @@ public function create()
}
}

/**
* Store a newly created course in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$validatedData = $request->validate([
'code' => 'required|string|max:16|unique:courses,code',
'semester_id' => 'required|integer|exists:semesters,id',
'academic_program' => ['required', Rule::in(array_values(Course::getAcademicPrograms()))],
'version' => ['required', 'integer', Rule::in(array_keys(Course::getVersions()))],
'name' => 'required|string|max:255',
'credits' => 'required|integer',
'type' => ['required', Rule::in(array_keys(Course::getTypes()))],
'content' => 'nullable|string',
'objectives' => 'nullable|json',
'time_allocation' => 'nullable|json',
'marks_allocation' => 'nullable|json',
'ilos' => 'nullable|json',
'urls' => 'nullable|json',
'references' => 'nullable|json',
]);

try {
$course = Course::create($validatedData);
return redirect()->route('dashboard.courses.index')->with('success', 'Course created successfully.');
} catch (\Exception $e) {
Log::error('Error creating course: ' . $e->getMessage());
return abort(500);
}
}

/**
* Show the form for editing the specified course.
Expand All @@ -90,40 +57,6 @@ public function edit(Course $course)
return abort(500);
}
}
/**
* Update the specified course in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Course $course
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Course $course)
{
$validatedData = $request->validate([
'code' => 'required|string|max:16|unique:courses,code,' . $course->id,
'semester_id' => 'required|integer|exists:semesters,id',
'academic_program' => ['required', Rule::in(array_values(Course::getAcademicPrograms()))],
'version' => ['required', 'integer', Rule::in(array_keys(Course::getVersions()))],
'name' => 'required|string|max:255',
'credits' => 'required|integer',
'type' => ['required', Rule::in(array_values(Course::getTypes()))],
'type' => ['required', Rule::in(array_values(Course::getTypes()))],
'content' => 'nullable|string',
'objectives' => 'nullable|json',
'time_allocation' => 'nullable|json',
'marks_allocation' => 'nullable|json',
'ilos' => 'nullable|json',
'urls' => 'nullable|json',
'references' => 'nullable|json',
]);
try {
$course->update($validatedData);
return redirect()->route('dashboard.courses.index')->with('success', 'Course updated successfully.');
} catch (\Exception $e) {
Log::error('Error updating course: ' . $e->getMessage());
return abort(500);
}
}

/**
* Remove the specified course from storage.
Expand All @@ -140,10 +73,10 @@ public function destroy(Course $course)
{
try {
$course->delete();
return redirect()->route('dashboard.courses.index')->with('success', 'Course deleted successfully.');
return redirect()->route('dashboard.courses.index')->with('Success', 'Course deleted successfully.');
} catch (\Exception $e) {
Log::error('Error in deleting course: ' . $e->getMessage());
return abort(500);
}
}
}
}
14 changes: 6 additions & 8 deletions app/Http/Controllers/Backend/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public function store(Request $request)
$data = request()->validate([
'title' => 'string|required',
'url' => ['required', 'unique:events'],
'event_type' => 'required|array',
'published_at' => 'required|date_format:Y-m-d',
'description' => 'string|required',
'enabled' => 'nullable',
Expand All @@ -55,6 +56,7 @@ public function store(Request $request)
}

try {

$event = new Event($data);
$event->enabled = ($request->enabled != null);
$event->url = urlencode(str_replace(" ", "-", $request->url));
Expand All @@ -75,12 +77,7 @@ public function store(Request $request)
*/
public function edit(Event $event)
{
try {
return view('backend.event.edit', compact('event'));
} catch (\Exception $ex) {
Log::error('Failed to edit event', ['error' => $ex->getMessage()]);
return abort(500);
};
return view('backend.event.edit', compact('event'));
}

/**
Expand All @@ -95,8 +92,8 @@ public function update(Request $request, Event $event)

$data = request()->validate([
'title' => ['required'],
'url' =>
['required', Rule::unique('events')->ignore($event->id)],
'url' => ['required', Rule::unique('events')->ignore($event->id)],
'event_type' => 'required|array',
'published_at' => 'required|date_format:Y-m-d',
'description' => 'string|required',
'enabled' => 'nullable',
Expand All @@ -116,6 +113,7 @@ public function update(Request $request, Event $event)

try {
$event->update($data);

$event->enabled = ($request->enabled != null);
$event->url = urlencode(str_replace(" ", "-", $request->url));
$event->created_by = Auth::user()->id;
Expand Down
15 changes: 14 additions & 1 deletion app/Http/Livewire/Backend/CreateCourses.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class CreateCourses extends Component

//2nd form step
public $objectives;
public $prerequisites = [];
public $ilos = [];

//3rd form step
Expand Down Expand Up @@ -158,7 +159,7 @@ public function updated($propertyName)
$this->validateOnly($propertyName);
}

protected $listeners = ['itemsUpdated' => 'updateItems'];
protected $listeners = ['itemsUpdated' => 'updateItems', 'prerequisitesUpdated' => 'updatePrerequisites'];

public function mount()
{
Expand All @@ -169,6 +170,11 @@ public function mount()
$this->ilos = Course::getILOTemplate();
}

public function updatePrerequisites($selectedCourses)
{
$this->prerequisites = $selectedCourses;
}

public function updateItems($type, $newItems)
{
if ($type == 'references') {
Expand Down Expand Up @@ -263,6 +269,13 @@ protected function storeCourse()
]);
}
}
// Sync prerequisites
if (!empty($this->prerequisites)) {
$course->prerequisites()->sync(collect($this->prerequisites)->pluck('id')->toArray());
} else {
// If no prerequisites, detach all
$course->prerequisites()->detach();
}

\DB::commit();
} catch (\Exception $e) {
Expand Down
18 changes: 16 additions & 2 deletions app/Http/Livewire/Backend/EditCourses.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class EditCourses extends Component

// 2nd form step
public $objectives;
public $prerequisites = [];
public $ilos = [
'knowledge' => [],
'skills' => [],
Expand Down Expand Up @@ -144,7 +145,7 @@ public function updated($propertyName)
$this->canUpdate = true;
}

protected $listeners = ['itemsUpdated' => 'updateItems'];
protected $listeners = ['itemsUpdated' => 'updateItems', 'prerequisitesUpdated' => 'updatePrerequisites'];

public function mount(Course $course)
{
Expand Down Expand Up @@ -179,10 +180,16 @@ public function mount(Course $course)
'time_allocation' => array_merge(Course::getTimeAllocation(), json_decode($module->time_allocation, true))
];
})->toArray();
$this->prerequisites = $course->prerequisites->pluck('id')->toArray();
// Update semesters list based on academic program and version
$this->updateSemestersList();
}

public function updatePrerequisites($selectedCourses)
{
$this->prerequisites = $selectedCourses;
}

public function updateItems($type, $newItems)
{
if ($type == 'references') {
Expand Down Expand Up @@ -286,7 +293,13 @@ protected function updateCourse()
]);
}
}

// Sync prerequisites
if (!empty($this->prerequisites)) {
$course->prerequisites()->sync(collect($this->prerequisites)->pluck('id')->toArray());
} else {
// If no prerequisites, detach all
$course->prerequisites()->detach();
}
\DB::commit();
} catch (\Exception $e) {
\DB::rollBack();
Expand Down Expand Up @@ -314,6 +327,7 @@ protected function resetForm()
$this->ilos = Course::getILOTemplate();
$this->references = [];
$this->modules = [];
$this->prerequisites = [];
}

public function render()
Expand Down
Loading

0 comments on commit 69cb896

Please sign in to comment.