diff --git a/app/Http/Controllers/Admin/ProjectController.php b/app/Http/Controllers/Admin/ProjectController.php
new file mode 100644
index 0000000..fa4dd0e
--- /dev/null
+++ b/app/Http/Controllers/Admin/ProjectController.php
@@ -0,0 +1,302 @@
+all(), [
+ 'title' => 'required',
+ 'section' => 'required|numeric',
+ 'course_id' => 'required'
+ ]);
+
+ if ($validator->fails()) {
+ return redirect()->back()->withErrors($validator)->withInput();
+ }
+
+ $data['title'] = $request->title;
+ $data['course_id'] = $request->course_id;
+ $data['section_id'] = $request->section;
+ $data['description'] = $request->description;
+ $data['attachment'] = $request->attachment;
+ $data['summary'] = $request->summary;
+
+
+ Lesson::where('id', $id)->update($data);
+
+ Session::flash('success', get_phrase('Project has been updated.'));
+ return redirect()->back();
+ }
+
+ public function store(Request $request)
+ {
+ $maxSort = Lesson::where('section_id', $request->section)
+ ->max('sort');
+
+ $data['user_id'] = auth()->user()->id;
+ $data['sort'] = $maxSort + 1;
+ $data['title'] = $request->title;
+ $data['course_id'] = $request->course_id;
+ $data['section_id'] = $request->section;
+ $data['attachment'] = $request->attachment;
+ $data['description'] = $request->description;
+ $data['summary'] = $request->summary;
+ $data['lesson_type'] = 'project';
+ $data['status'] = 1;
+
+ Lesson::insert($data);
+
+ Session::flash('success', get_phrase('Project has been created.'));
+ return redirect()->back();
+ }
+
+ public function getSubmissions($id)
+ {
+ $participants = ProjectSubmission::join('users', 'project_submissions.user_id', '=', 'users.id')
+ ->where('project_submissions.lesson_id', $id)
+ ->where('project_submissions.status', 0)
+ ->select('users.name', 'users.id')
+ ->distinct()
+ ->get();
+
+ return view('admin.project.grading.index', ['participants' => $participants, 'lesson_id' => $id]);
+ }
+
+ public function getPreview(Request $request)
+ {
+ // Validasi input
+ $request->validate([
+ 'lesson_id' => 'required|integer',
+ 'user_id' => 'required|integer'
+ ]);
+
+ // Cari submission terbaru
+ $submission = ProjectSubmission::where('lesson_id', $request->lesson_id)
+ ->where('user_id', $request->user_id)
+ ->latest()
+ ->first();
+ // dd($submission); // <-- INI HARUS DIHAPUS ATAU DI-KOMEN
+
+ // Tentukan label komentar
+ $commentLabel = (!empty($submission) && !empty($submission->comment))
+ ? "Revisi Sebelumnya"
+ : "Masukkan Revisi Anda";
+
+ // Return view preview
+ return view('admin.project.grading.preview', compact('submission', 'commentLabel'));
+ }
+
+ public function getParticipantSubmission(Request $request)
+ {
+ $submissions = ProjectSubmission::where('lesson_id', $request->quizId)
+ ->where('user_id', $request->participant)
+ ->orderBy('created_at', 'desc')
+ ->get();
+
+ $html = '';
+
+ if($submissions->count() > 0){
+ foreach ($submissions as $submission) {
+ $date = date('d M Y, H:i', strtotime($submission->created_at));
+
+ $statusLabel = '';
+ if($submission->status == 1) $statusLabel = ' (Lulus)';
+ elseif($submission->status == 2) $statusLabel = ' (Revisi)';
+ else $statusLabel = ' (Pending)';
+
+ $html .= '';
+ }
+ } else {
+ $html .= '';
+ }
+
+ return response()->json($html);
+ }
+
+ public function updateSubmission(Request $request, $id)
+ {
+ $request->validate([
+ 'status' => 'required|in:1,2',
+ 'comment' => 'required_if:status,2', // Wajib isi jika status 2 (Revisi)
+ ]);
+
+ // Menggunakan Model findOrFail
+ $submission = ProjectSubmission::findOrFail($id);
+
+ $submission->status = $request->status;
+ $submission->reviewed_by = auth()->id();
+ $submission->reviewed_at = now();
+
+ if ($request->status == 1) {
+ // Jika Diterima (1), Comment jadi NULL (sesuai request)
+ $submission->comment = null;
+ } else {
+ // Jika Perlu Perbaikan (2), Simpan Comment
+ $submission->comment = $request->comment;
+ }
+
+ $submission->save();
+
+ // **LOGIKA WATCH HISTORY - DIPERBAIKI berdasarkan referensi**
+
+ $lesson = Lesson::findOrFail($submission->lesson_id);
+
+ $student_id = $submission->user_id;
+ $course_id = $lesson->course_id;
+ $lesson_id = $submission->lesson_id;
+
+ // Ambil semua lesson ID untuk course ini
+ $total_lesson = Lesson::where('course_id', $course_id)
+ ->pluck('id')
+ ->map(function($id) {
+ return (int)$id;
+ })
+ ->toArray();
+
+ // Cari watch_history untuk student ini
+ $watch_history = Watch_history::where('course_id', $course_id)
+ ->where('student_id', $student_id)
+ ->first();
+
+ // **LOGIKA UTAMA berdasarkan referensi set_watch_history**
+ if ($watch_history) {
+ // Parse data lama dengan handling yang robust
+ $completed_lessons = [];
+
+ if (!empty($watch_history->completed_lesson)) {
+ $decoded = json_decode($watch_history->completed_lesson, true);
+
+ if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
+ // Konversi semua nilai ke integer
+ $completed_lessons = array_map('intval', $decoded);
+ } else {
+ // Fallback jika format tidak valid
+ $completed_lesson_data = trim($watch_history->completed_lesson, '[]"\' ');
+ if (!empty($completed_lesson_data)) {
+ $completed_lessons = array_map('intval', explode(',', $completed_lesson_data));
+ }
+ }
+ }
+
+ // Hapus duplikat dan sortir
+ $completed_lessons = array_unique($completed_lessons);
+ sort($completed_lessons);
+
+ // **HANYA tambahkan lesson jika project DITERIMA (status 1)**
+ if ($request->status == 1 && !in_array($lesson_id, $completed_lessons)) {
+ $completed_lessons[] = $lesson_id;
+ sort($completed_lessons);
+ }
+
+ // Hitung completion dengan benar (seperti referensi)
+ $completed_in_course = array_intersect($completed_lessons, $total_lesson);
+ $is_completed = count($total_lesson) > 0 &&
+ count($completed_in_course) >= count($total_lesson);
+
+ $data = [
+ 'course_id' => $course_id,
+ 'student_id' => $student_id,
+ 'watching_lesson_id' => $lesson_id,
+ 'completed_lesson' => json_encode($completed_lessons, JSON_NUMERIC_CHECK), // Gunakan JSON_NUMERIC_CHECK
+ 'completed_date' => $is_completed ? date('Y-m-d H:i:s') : null, // Format MySQL datetime
+ ];
+
+ // **FIX: Update dengan student_id yang benar (bukan auth user)**
+ Watch_history::where('course_id', $course_id)
+ ->where('student_id', $student_id)
+ ->update($data);
+
+ // Log untuk debugging
+ \Log::info('Project submission watch history updated:', [
+ 'project_submission_id' => $id,
+ 'student_id' => $student_id,
+ 'course_id' => $course_id,
+ 'lesson_id' => $lesson_id,
+ 'completed_lessons' => $completed_lessons,
+ 'is_completed' => $is_completed,
+ 'total_lessons_in_course' => count($total_lesson)
+ ]);
+
+ } else {
+ // **Jika tidak ada watch_history, buat baru**
+ // Hanya buat jika project DITERIMA (status 1)
+ if ($request->status == 1) {
+ $completed_lessons = [$lesson_id];
+
+ // Hitung completion untuk data baru
+ $is_completed = count($total_lesson) == 1 && in_array($lesson_id, $total_lesson);
+
+ $data = [
+ 'course_id' => $course_id,
+ 'student_id' => $student_id,
+ 'watching_lesson_id' => $lesson_id,
+ 'completed_lesson' => json_encode($completed_lessons, JSON_NUMERIC_CHECK),
+ 'completed_date' => $is_completed ? date('Y-m-d H:i:s') : null,
+ 'created_at' => now(),
+ 'updated_at' => now(),
+ ];
+
+ Watch_history::create($data);
+
+ \Log::info('New watch history created from project submission:', [
+ 'project_submission_id' => $id,
+ 'student_id' => $student_id,
+ 'course_id' => $course_id,
+ 'lesson_id' => $lesson_id
+ ]);
+ }
+ }
+
+ // **LOGIKA SERTIFIKAT - dengan progress yang benar**
+ $completed_lessons = $completed_lessons ?? [];
+ $completed_in_course = array_intersect($completed_lessons, $total_lesson);
+ $completed_count = count($completed_in_course);
+ $total_count = count($total_lesson);
+
+ $progress_percentage = 0;
+ if ($total_count > 0) {
+ $progress_percentage = ($completed_count / $total_count) * 100;
+ }
+
+ // Jika progress 100% dan status project diterima, buat sertifikat
+ if ($progress_percentage >= 100 && $request->status == 1) {
+ $certificateExists = Certificate::where('user_id', $student_id)
+ ->where('course_id', $course_id)
+ ->exists();
+
+ if (!$certificateExists) {
+ // Cek jika method generateIdentifier ada
+ if (method_exists($this, 'generateIdentifier')) {
+ $identifier = $this->generateIdentifier(12);
+ } else {
+ // Fallback ke random string
+ $identifier = \Illuminate\Support\Str::random(12);
+ }
+
+ Certificate::create([
+ 'user_id' => $student_id,
+ 'course_id' => $course_id,
+ 'identifier' => $identifier,
+ ]);
+
+ \Log::info('Certificate created after project submission:', [
+ 'student_id' => $student_id,
+ 'course_id' => $course_id,
+ 'project_submission_id' => $id
+ ]);
+ }
+ }
+
+ return redirect()->back()->with('success', get_phrase('Project graded successfully'));
+ }
+}
diff --git a/app/Http/Controllers/Admin/QuizController.php b/app/Http/Controllers/Admin/QuizController.php
index c34e379..bc5d50c 100644
--- a/app/Http/Controllers/Admin/QuizController.php
+++ b/app/Http/Controllers/Admin/QuizController.php
@@ -56,6 +56,10 @@ class QuizController extends Controller
return redirect()->back();
}
+ $maxSort = Lesson::where('section_id', $request->section)
+ ->max('sort');
+ $data['user_id'] = auth()->user()->id;
+ $data['sort'] = $maxSort + 1;
$data['title'] = $request->title;
$data['course_id'] = $request->course_id;
$data['section_id'] = $request->section;
diff --git a/app/Http/Controllers/SettingController.php b/app/Http/Controllers/SettingController.php
index 9131de7..3c821b7 100644
--- a/app/Http/Controllers/SettingController.php
+++ b/app/Http/Controllers/SettingController.php
@@ -657,11 +657,41 @@ class SettingController extends Controller
return redirect(route('admin.certificate.settings'))->with('success', get_phrase('Certificate template has been updated'));
}
+ function certificate_update_template_details(Request $request)
+ {
+ $request->validate(['certificate_template_details' => 'required|image']);
+
+ $row = Setting::where('type', 'certificate_template_details');
+
+ if ($row->count() > 0) {
+ remove_file(get_settings('certificate_template_details'));
+ $path = FileUploader::upload($request->certificate_template_details, 'uploads/certificate-template-details', 1000);
+ Setting::where('type', 'certificate_template_details')->update(['description' => $path]);
+ } else {
+ $path = FileUploader::upload($request->certificate_template_details, 'uploads/certificate-template-details', 1000);
+ Setting::insert(['type' => 'certificate_template_details', 'description' => $path]);
+ }
+
+ $certificate_builder_content = get_settings('certificate_builder_content');
+ if ($certificate_builder_content) {
+ // Use regular expression to replace the image source
+ $modifiedHtml = preg_replace('/(]+src=")([^"]+)(")/', '$1' . get_image($path) . '$3', $certificate_builder_content);
+ Setting::where('type', 'certificate_builder_content')->update(['description' => $modifiedHtml]);
+ }
+
+ return redirect(route('admin.certificate.settings'))->with('success', get_phrase('Certificate template has been updated'));
+ }
+
function certificate_builder()
{
return view('admin.certificate.builder');
}
+ function certificate_builder_details()
+ {
+ return view('admin.certificate.builder_details');
+ }
+
function certificate_builder_update(Request $request)
{
$request->validate(['certificate_builder_content' => 'required']);
@@ -677,6 +707,20 @@ class SettingController extends Controller
return route('admin.certificate.settings');
}
+ function certificate_builder_details_update(Request $request)
+ {
+ $request->validate(['certificate_builder_content_details' => 'required']);
+
+ $row = Setting::where('type', 'certificate_builder_content_details');
+ if ($row->count() > 0) {
+ Setting::where('type', 'certificate_builder_content_details')->update(['description' => $request->certificate_builder_content_details]);
+ } else {
+ Setting::insert(['type' => 'certificate_builder_content_details', 'description' => $request->certificate_builder_content_details]);
+ }
+ Session::flash('success', get_phrase('Certificate builder template has been updated'));
+ return route('admin.certificate.settings');
+ }
+
//User Review Add
public function user_review_add()
{
diff --git a/app/Http/Controllers/instructor/ProjectController.php b/app/Http/Controllers/instructor/ProjectController.php
index 42db41d..b841fe7 100644
--- a/app/Http/Controllers/instructor/ProjectController.php
+++ b/app/Http/Controllers/instructor/ProjectController.php
@@ -14,39 +14,32 @@ class ProjectController extends Controller
{
public function update(Request $request, $id)
{
- $request->validate([
- 'status' => 'required|in:1,2',
- 'comment' => 'required_if:status,2',
+ $validator = Validator::make($request->all(), [
+ 'title' => 'required',
+ 'section' => 'required|numeric',
+ 'course_id' => 'required'
]);
- $submission = ProjectSubmission::findOrFail($id);
-
- $submission->status = $request->status;
- $submission->reviewed_by = auth()->id();
- $submission->reviewed_at = now();
-
- if ($request->status == 1) {
- $submission->comment = null;
- } else {
- $submission->comment = $request->comment;
+ if ($validator->fails()) {
+ return redirect()->back()->withErrors($validator)->withInput();
}
- $submission->save();
+ $data['title'] = $request->title;
+ $data['course_id'] = $request->course_id;
+ $data['section_id'] = $request->section;
+ $data['description'] = $request->description;
+ $data['attachment'] = $request->attachment;
+ $data['summary'] = $request->summary;
- return redirect()->back()->with('success', get_phrase('Project graded successfully'));
+
+ Lesson::where('id', $id)->update($data);
+
+ Session::flash('success', get_phrase('Project has been updated.'));
+ return redirect()->back();
}
public function store(Request $request)
{
- $title = Lesson::join('sections', 'lessons.section_id', 'sections.id')
- ->join('courses', 'sections.course_id', 'courses.id')
- ->where('courses.user_id', auth()->user()->id)
- ->where('lessons.title', $request->title)
- ->first();
- if ($title) {
- Session::flash('error', get_phrase('Title has been taken.'));
- return redirect()->back();
- }
$maxSort = Lesson::where('section_id', $request->section)
->max('sort');
@@ -56,8 +49,8 @@ class ProjectController extends Controller
$data['title'] = $request->title;
$data['course_id'] = $request->course_id;
$data['section_id'] = $request->section;
- $data['description'] = $request->description;
$data['attachment'] = $request->attachment;
+ $data['description'] = $request->description;
$data['summary'] = $request->summary;
$data['lesson_type'] = 'project';
$data['status'] = 1;
@@ -68,10 +61,11 @@ class ProjectController extends Controller
return redirect()->back();
}
- public function getIndex($id)
+ public function getSubmissions($id)
{
$participants = ProjectSubmission::join('users', 'project_submissions.user_id', '=', 'users.id')
->where('project_submissions.lesson_id', $id)
+ ->where('project_submissions.status', 0)
->select('users.name', 'users.id')
->distinct()
->get();
diff --git a/resources/views/admin/certificate/builder_details.blade.php b/resources/views/admin/certificate/builder_details.blade.php
new file mode 100644
index 0000000..d6f9049
--- /dev/null
+++ b/resources/views/admin/certificate/builder_details.blade.php
@@ -0,0 +1,849 @@
+
+
+
+
{{ get_phrase('Certificate template') }}
+{{ get_phrase('Certificate Template Main') }}
{{ get_phrase('Certificate template') }}
+{{ get_phrase('Certificate Template Main') }}
{{ get_phrase('Certificate Template Details') }}
+{{ get_phrase('Certificate Template Details') }}
+