marking chapters as complete and toggling value from course list and chapter page.
This commit is contained in:
17
app/Http/Controllers/Chapter/CompleteToggle.php
Normal file
17
app/Http/Controllers/Chapter/CompleteToggle.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Chapter;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Chapter;
|
||||||
|
use App\Models\Course;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
|
||||||
|
class CompleteToggle extends Controller
|
||||||
|
{
|
||||||
|
public function __invoke(Course $course, Chapter $chapter): RedirectResponse
|
||||||
|
{
|
||||||
|
$chapter->update(['is_complete' => !$chapter->is_complete]);
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
* @property string $duration
|
* @property string $duration
|
||||||
* @property integer $course_id
|
* @property integer $course_id
|
||||||
* @property bool $sync_offline
|
* @property bool $sync_offline
|
||||||
|
* @property bool $is_complete
|
||||||
* @property string $video_path
|
* @property string $video_path
|
||||||
* @property string $directory_path
|
* @property string $directory_path
|
||||||
* @property Course $course
|
* @property Course $course
|
||||||
@@ -34,6 +35,7 @@ class Chapter extends Model
|
|||||||
'duration',
|
'duration',
|
||||||
'course_id',
|
'course_id',
|
||||||
'sync_offline',
|
'sync_offline',
|
||||||
|
'is_complete',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $appends = ['video_path', 'directory_path', 'video_url'];
|
protected $appends = ['video_path', 'directory_path', 'video_url'];
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('chapters', function (Blueprint $table) {
|
||||||
|
$table->boolean('is_complete')->default(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('chapters', function (Blueprint $table) {
|
||||||
|
$table->removeColumn('is_complete');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
<table class="table table-sm">
|
<table class="table table-sm">
|
||||||
@foreach($chapters as $courseChapter)
|
@foreach($chapters as $courseChapter)
|
||||||
<tr class="@if($courseChapter->id === $chapter->id)table-dark @endif">
|
<tr class="@if($courseChapter->id === $chapter->id)table-dark @endif">
|
||||||
|
<td><a href="{{ route('course.chapter.complete_toggle', ['course' => $courseChapter->course->id, 'chapter' => $courseChapter->id]) }}" class="text-decoration-none"><span class="icon-check {{ $courseChapter->is_complete?'text-info':'text-dark' }}"></span></a></td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ route('course.chapter', ['course' => $courseChapter->course_id, 'chapter' => $courseChapter->order ]) }}"
|
<a href="{{ route('course.chapter', ['course' => $courseChapter->course_id, 'chapter' => $courseChapter->order ]) }}"
|
||||||
class="text-decoration-none">{{ $courseChapter->title }}</a>
|
class="text-decoration-none">{{ $courseChapter->title }}</a>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
crossorigin="anonymous">
|
crossorigin="anonymous">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-dark-5@1.1.3/dist/css/bootstrap-nightfall.min.css"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-dark-5@1.1.3/dist/css/bootstrap-nightfall.min.css"
|
||||||
rel="stylesheet" media="(prefers-color-scheme: dark)">
|
rel="stylesheet" media="(prefers-color-scheme: dark)">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simple-line-icons/2.5.5/css/simple-line-icons.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ route('course.chapter', ['course' => $course->id, 'chapter' => $chapter->order]) }}"
|
<td><a href="{{ route('course.chapter', ['course' => $course->id, 'chapter' => $chapter->order]) }}"
|
||||||
class="text-decoration-none">{{ $chapter->title }}</a></td>
|
class="text-decoration-none">{{ $chapter->title }}</a></td>
|
||||||
|
<td><a href="{{ route('course.chapter.complete_toggle', ['course' => $course->id, 'chapter' => $chapter->id]) }}" class="text-decoration-none"><span class="icon-check {{ $chapter->is_complete?'text-info':'text-dark' }}"></span></a></td>
|
||||||
<td>{{ $chapter->duration }}</td>
|
<td>{{ $chapter->duration }}</td>
|
||||||
<td>{{ $chapter->sync_offline?'Yes':'no' }}</td>
|
<td>{{ $chapter->sync_offline?'Yes':'no' }}</td>
|
||||||
<td>{{ $chapter->is_video_file?'Yes':'-' }}</td>
|
<td>{{ $chapter->is_video_file?'Yes':'-' }}</td>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Route::prefix('course')->group(function () {
|
|||||||
Route::get('/{course}/update', Course\Update::class)->name('course.update');
|
Route::get('/{course}/update', Course\Update::class)->name('course.update');
|
||||||
Route::get('/{course}/chapter/{chapter}', ChapterController::class)->name('course.chapter');
|
Route::get('/{course}/chapter/{chapter}', ChapterController::class)->name('course.chapter');
|
||||||
Route::get('/{course}/chapter/{chapter}/sync', Chapter\Sync::class)->name('course.chapter.sync');
|
Route::get('/{course}/chapter/{chapter}/sync', Chapter\Sync::class)->name('course.chapter.sync');
|
||||||
|
Route::get('/{course}/chapter/{chapter}/completetoggle', Chapter\CompleteToggle::class)->name('course.chapter.complete_toggle');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user