pembenaran player course
This commit is contained in:
parent
e30ac8a5c8
commit
e3458433f2
@ -213,32 +213,6 @@ function is_added_to_wishlist($user_id = 0, $course_id = "")
|
||||
}
|
||||
}
|
||||
|
||||
// function is_purchased($user_id = 0, $course_id = "")
|
||||
// {
|
||||
// // 0 represents Not purchased, 1 represents Purchased, 2 represents Pending
|
||||
// if ($user_id > 0) {
|
||||
// if (enroll_status($course_id, $user_id) == 'valid') {
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// function is_purchased($user_id = 0, $course_id = "")
|
||||
// {
|
||||
// // 0 represents not purchased, 1 represents purchased
|
||||
// if ($user_id > 0) {
|
||||
// $status = enroll_status($course_id, $user_id);
|
||||
// return $status === 'valid'; // Return true only if status is 'valid'
|
||||
// } else {
|
||||
// return false; // User ID is not valid
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
if (!function_exists('is_purchased')) {
|
||||
function is_purchased($user_id = 0, $course_id = "")
|
||||
{
|
||||
@ -271,7 +245,6 @@ if (!function_exists('enroll_status_api')) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_total_duration_of_lesson_by_course_id($course_id)
|
||||
{
|
||||
$total_duration = 0;
|
||||
@ -433,75 +406,6 @@ if (!function_exists('update_watch_history_manually')) {
|
||||
}
|
||||
}
|
||||
|
||||
// if (!function_exists('update_watch_history_manually')) {
|
||||
// // code of mark this lesson as completed
|
||||
// function update_watch_history_manually($lesson_id = "", $course_id = "", $user_id = "")
|
||||
// {
|
||||
// $is_completed = 0;
|
||||
|
||||
// $query = DB::table('watch_histories')->where('course_id', $course_id)->where('student_id', $user_id)->first();
|
||||
|
||||
// $course_progress = course_progress($course_id, $user_id);
|
||||
|
||||
// if (!empty($query)) {
|
||||
// $lesson_ids = json_decode($query->completed_lesson, true);
|
||||
// if (!is_array($lesson_ids))
|
||||
// $lesson_ids = array();
|
||||
// if (!in_array($lesson_id, $lesson_ids)) {
|
||||
// array_push($lesson_ids, $lesson_id);
|
||||
// $total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
|
||||
// $course_progress = (100 / count($total_lesson)) * count($lesson_ids);
|
||||
|
||||
// if ($course_progress >= 100 && $query->completed_date == null) {
|
||||
// $completed_date = time();
|
||||
// } else {
|
||||
// $completed_date = $query->completed_date;
|
||||
// }
|
||||
|
||||
// DB::table('watch_histories')->where('id', $query->id)->update([
|
||||
// 'completed_lesson' => json_encode($lesson_ids),
|
||||
// 'completed_date' => $completed_date,
|
||||
// ]);
|
||||
|
||||
// $is_completed = 1;
|
||||
|
||||
// } else {
|
||||
// if (($key = array_search($lesson_id, $lesson_ids)) !== false) {
|
||||
// unset($lesson_ids[$key]);
|
||||
// }
|
||||
|
||||
// $total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
|
||||
// $course_progress = (100 / count($total_lesson)) * count($lesson_ids);
|
||||
|
||||
// if ($course_progress >= 100 && $query->completed_date == null) {
|
||||
// $completed_date = time();
|
||||
// } else {
|
||||
// $completed_date = $query->completed_date;
|
||||
// }
|
||||
|
||||
// DB::table('watch_histories')->where('id', $query->id)->update([
|
||||
// 'completed_lesson' => json_encode($lesson_ids),
|
||||
// 'completed_date' => $completed_date,
|
||||
// ]);
|
||||
|
||||
// $is_completed = 0;
|
||||
// }
|
||||
|
||||
// } else {
|
||||
// $total_lesson = DB::table('lessons')->where('course_id', $course_id)->get();
|
||||
// $course_progress = (100 / count($total_lesson));
|
||||
|
||||
// $insert_data['course_id'] = $course_id;
|
||||
// $insert_data['student_id'] = $user_id;
|
||||
// $insert_data['completed_lesson'] = json_encode(array($lesson_id));
|
||||
// $insert_data['watching_lesson_id'] = $lesson_id;
|
||||
// DB::table('watch_histories')->create($insert_data);
|
||||
// }
|
||||
|
||||
// return json_encode(array('lesson_id' => $lesson_id, 'course_progress' => round($course_progress), 'is_completed' => $is_completed));
|
||||
// }
|
||||
// }
|
||||
|
||||
function course_completion_data($course_id = "", $user_id = "")
|
||||
{
|
||||
$response = array();
|
||||
|
||||
@ -7,7 +7,6 @@ use Illuminate\Http\Request;
|
||||
|
||||
class CommonController extends Controller
|
||||
{
|
||||
// Get video details new code
|
||||
function get_video_details(Request $request, $url = "")
|
||||
{
|
||||
if ($url == "") {
|
||||
@ -17,36 +16,9 @@ class CommonController extends Controller
|
||||
$host = explode('.', str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST))));
|
||||
$host = isset($host[0]) ? $host[0] : $host;
|
||||
|
||||
$vimeo_api_key = get_settings('vimeo_api_key');
|
||||
$youtube_api_key = get_settings('youtube_api_key');
|
||||
|
||||
if ($host == 'vimeo') {
|
||||
$video_id = substr(parse_url($url, PHP_URL_PATH), 1);
|
||||
$options = array('http' => array(
|
||||
'method' => 'GET',
|
||||
'header' => 'Authorization: Bearer ' . $vimeo_api_key
|
||||
));
|
||||
$context = stream_context_create($options);
|
||||
|
||||
try {
|
||||
$hash = json_decode(file_get_contents("https://api.vimeo.com/videos/{$video_id}", false, $context));
|
||||
} catch (\Throwable $th) {
|
||||
$hash = '';
|
||||
}
|
||||
|
||||
if ($hash == '') return;
|
||||
|
||||
|
||||
return array(
|
||||
'provider' => 'Vimeo',
|
||||
'video_id' => $video_id,
|
||||
'title' => $hash->name,
|
||||
'thumbnail' => $hash->pictures->sizes[0]->link,
|
||||
'video' => $hash->link,
|
||||
'embed_video' => "https://player.vimeo.com/video/" . $video_id,
|
||||
'duration' => gmdate("H:i:s", $hash->duration)
|
||||
);
|
||||
} elseif ($host == 'youtube' || $host == 'youtu') {
|
||||
if ($host == 'youtube' || $host == 'youtu') {
|
||||
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
|
||||
$video_id = $match[1];
|
||||
|
||||
@ -68,8 +40,7 @@ class CommonController extends Controller
|
||||
'embed_video' => "http://www.youtube.com/embed/" . $hash->items[0]->id,
|
||||
'duration' => $duration->format('%H:%I:%S'),
|
||||
);
|
||||
} elseif ($host == 'drive') {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function rendered_view(Request $request, $path = "")
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Course;
|
||||
use App\Models\Live_class;
|
||||
use App\Models\Setting;
|
||||
|
||||
@ -13,6 +13,17 @@ use Illuminate\Support\Facades\Session;
|
||||
|
||||
class PlayerController extends Controller
|
||||
{
|
||||
public function reload_sidebar($course_id, $lesson_id)
|
||||
{
|
||||
$course_details = Course::findOrFail($course_id);
|
||||
$lesson_details = Lesson::findOrFail($lesson_id);
|
||||
|
||||
return view('course_player.side_bar', compact(
|
||||
'course_details',
|
||||
'lesson_details'
|
||||
));
|
||||
}
|
||||
|
||||
public function course_player(Request $request, $slug, $id = '')
|
||||
{
|
||||
$course = Course::where('slug', $slug)->firstOrNew();
|
||||
@ -35,7 +46,7 @@ class PlayerController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//cek histori tontonan
|
||||
$check_lesson_history = Watch_history::where('course_id', $course->id)
|
||||
->where('student_id', auth()->user()->id)->first();
|
||||
$first_lesson_of_course = Lesson::where('course_id', $course->id)->orderBy('sort', 'asc')->value('id');
|
||||
|
||||
@ -134,8 +134,14 @@ class MessageController extends Controller
|
||||
|
||||
public function search_student(Request $request)
|
||||
{
|
||||
$page_data['user_details'] = User::where('email', $request->search_mail)->first();
|
||||
$view_path = 'frontend.' . get_frontend_settings('theme') . '.student.message.search_result';
|
||||
$search = $request->search_mail;
|
||||
|
||||
if (empty(trim($search))) {
|
||||
$page_data['user_details'] = null; // or collect() for no results
|
||||
} else {
|
||||
$page_data['user_details'] = User::where('email', 'LIKE', '%' . $search . '%') ->first();
|
||||
}
|
||||
$view_path = 'frontend.' . get_frontend_settings('theme') . '.student.message.search_result';
|
||||
return view($view_path, $page_data);
|
||||
}
|
||||
|
||||
|
||||
@ -14,9 +14,14 @@ class QuizController extends Controller
|
||||
{
|
||||
public function quiz_submit(Request $request)
|
||||
{
|
||||
$retake = Lesson::where('id', $request->quiz_id)->value('retake');
|
||||
$submit = QuizSubmission::where('quiz_id', $request->quiz_id)->where('user_id', auth()->user()->id)->count();
|
||||
if ($submit > $retake) {
|
||||
$quiz = Lesson::findOrFail($request->quiz_id);
|
||||
|
||||
$retake = $quiz->retake;
|
||||
$submit = QuizSubmission::where('quiz_id', $quiz->id)
|
||||
->where('user_id', auth()->user()->id)
|
||||
->count();
|
||||
|
||||
if ($submit >= $retake) {
|
||||
Session::flash('warning', get_phrase('Attempt has been over.'));
|
||||
return redirect()->back();
|
||||
}
|
||||
@ -37,41 +42,63 @@ class QuizController extends Controller
|
||||
$questions = Question::whereIn('id', $question_ids)->get();
|
||||
|
||||
$right_answers = $wrong_answers = [];
|
||||
|
||||
foreach ($questions as $key => $question) {
|
||||
|
||||
$correct_answer = json_decode($question->answer, true);
|
||||
$submitted = $submitted_answers[$key];
|
||||
|
||||
if ($question->type == 'mcq') {
|
||||
$isCorrect = empty(array_diff($correct_answer, $submitted)) && empty(array_diff($submitted, $correct_answer));
|
||||
$isCorrect = empty(array_diff($correct_answer, $submitted))
|
||||
&& empty(array_diff($submitted, $correct_answer));
|
||||
} elseif ($question->type == 'fill_blanks') {
|
||||
$isCorrect = count($correct_answer) === count($submitted);
|
||||
|
||||
if ($isCorrect) {
|
||||
for ($i = 0; $i < count($correct_answer); $i++) {
|
||||
if (strtolower($correct_answer[$i]) != strtolower($submitted[$i])) {
|
||||
foreach ($correct_answer as $i => $answer) {
|
||||
if (strtolower($answer) !== strtolower($submitted[$i])) {
|
||||
$isCorrect = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$isCorrect = false;
|
||||
}
|
||||
} elseif ($question->type == 'true_false') {
|
||||
$isCorrect = strtolower(json_encode($correct_answer)) == strtolower($submitted);
|
||||
$isCorrect = strtolower(json_encode($correct_answer)) === strtolower($submitted);
|
||||
}
|
||||
|
||||
$isCorrect ? $right_answers[] = $question->id : $wrong_answers[] = $question->id;
|
||||
$isCorrect
|
||||
? $right_answers[] = $question->id
|
||||
: $wrong_answers[] = $question->id;
|
||||
}
|
||||
|
||||
$data['quiz_id'] = $quiz_id;
|
||||
$data['user_id'] = auth()->user()->id;
|
||||
$data['correct_answer'] = $right_answers ? json_encode($right_answers) : null;
|
||||
$data['wrong_answer'] = $wrong_answers ? json_encode($wrong_answers) : null;
|
||||
$data['submits'] = $submits->count() > 0 ? json_encode($submits->toArray()) : null;
|
||||
QuizSubmission::create([
|
||||
'quiz_id' => $quiz->id,
|
||||
'user_id' => auth()->user()->id,
|
||||
'correct_answer' => $right_answers ? json_encode($right_answers) : null,
|
||||
'wrong_answer' => $wrong_answers ? json_encode($wrong_answers) : null,
|
||||
'submits' => $submits->count() ? json_encode($submits->toArray()) : null,
|
||||
]);
|
||||
|
||||
// ✅ HITUNG NILAI
|
||||
$total_questions = $questions->count();
|
||||
$mark_per_question = $total_questions > 0
|
||||
? ($quiz->total_mark / $total_questions)
|
||||
: 0;
|
||||
|
||||
$obtained_mark = count($right_answers) * $mark_per_question;
|
||||
|
||||
// ✅ JIKA LULUS → MARK LESSON COMPLETED
|
||||
if ($obtained_mark >= $quiz->pass_mark) {
|
||||
update_watch_history_manually(
|
||||
$quiz->id,
|
||||
$quiz->course_id,
|
||||
auth()->user()->id
|
||||
);
|
||||
|
||||
Session::flash('success', get_phrase('Congratulations, you passed the quiz.'));
|
||||
} else {
|
||||
Session::flash('warning', get_phrase('You did not reach the minimum score.'));
|
||||
}
|
||||
|
||||
QuizSubmission::insert($data);
|
||||
Session::flash('success', get_phrase('Your answers have been submitted.'));
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
||||
@ -14,37 +14,14 @@
|
||||
|
||||
<hr class="bg-secondary my-4">
|
||||
|
||||
<div class="row mb-3">
|
||||
@php
|
||||
$preview_video_type = str_contains($course_details->preview, 'youtu') ? 'youtube' : '';
|
||||
$preview_video_type = str_contains($course_details->preview, 'vimeo') && $preview_video_type == '' ? 'vimeo' : '';
|
||||
$preview_video_type = str_contains($course_details->preview, 'http') && $preview_video_type == '' ? 'html5' : '';
|
||||
@endphp
|
||||
<label for="preview_video_link" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Preview Video') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="radio" onchange="$('#preview_link_input').toggleClass('d-hidden'); $('#preview_file_input').toggleClass('d-hidden');" class="form-check-input" value="link" name="preview_video_provider" id="preview_video_link" @if($preview_video_type != '') checked @endif> <label for="preview_video_link">{{ get_phrase('Video Link') }}</label>
|
||||
|
||||
<input type="radio" onchange="$('#preview_link_input').toggleClass('d-hidden'); $('#preview_file_input').toggleClass('d-hidden');" class="form-check-input" value="file" name="preview_video_provider" id="preview_video_file" @if($preview_video_type == '') checked @endif> <label for="preview_video_file">{{ get_phrase('Video File') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 @if($preview_video_type == '') d-hidden @endif" id="preview_link_input">
|
||||
<div class="row mb-3" id="preview_link_input">
|
||||
<label for="preview_link" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Video link') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" name = "preview_link" id = "preview_link" class="form-control ol-form-control" value="{{ $course_details->preview }}">
|
||||
<small class="text-muted">{{get_phrase('Supported URL')}}: <b>{{get_phrase('Youtube')}}</b> {{get_phrase('or')}} <b>{{get_phrase('Vimeo')}}</b> {{get_phrase('or')}} <b>{{get_phrase('HTML5')}}</b></small>
|
||||
<small class="text-muted">{{get_phrase('Supported URL')}}: <b>{{get_phrase('Youtube')}}</b> {{get_phrase('or')}} <b>{{get_phrase('Google Drive')}}</b></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 @if($preview_video_type != '') d-hidden @endif" id="preview_file_input">
|
||||
<label for="preview" class="form-label ol-form-label col-sm-2 col-form-label">{{get_phrase('Preview Video File')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="file" name="preview" class="form-control ol-form-control" id="preview" accept="video/*" />
|
||||
<small class="text-muted">{{get_phrase('Supported Video file')}}: <b>.{{get_phrase('mp4')}}</b> {{get_phrase('or')}} <b>.{{get_phrase('webm')}}</b> {{get_phrase('or')}} <b>.{{get_phrase('ogg')}}</b></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
document.getElementById('thumbnail').addEventListener('change', function(event) {
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
{{ get_phrase('Video url') . ' [.mp4]' }}
|
||||
@elseif ($lesson_type == 'video')
|
||||
{{ get_phrase('Video file') }}
|
||||
@elseif ($lesson_type == 'youtube' || $lesson_type == 'academy cloud' || $lesson_type == 'vimeo')
|
||||
@elseif ($lesson_type == 'youtube')
|
||||
{{ ucfirst(get_phrase($lesson_type)) }} {{ get_phrase('Video') }}
|
||||
@elseif($lesson_type == 'google_drive_video')
|
||||
{{ get_phrase('Google drive video') }}
|
||||
@ -47,16 +47,6 @@
|
||||
|
||||
@if ($lesson_type == 'youtube')
|
||||
@include('admin.course.youtube_type_lesson_add')
|
||||
@elseif ($lesson_type == 'academy_cloud')
|
||||
@include('admin.course.academy_cloud_type_lesson_add')
|
||||
@elseif ($lesson_type == 'vimeo')
|
||||
@include('admin.course.vimeo_type_lesson_add')
|
||||
@elseif ($lesson_type == 'html5')
|
||||
@include('admin.course.html5_type_lesson_add')
|
||||
@elseif ($lesson_type == 'video')
|
||||
@include('admin.course.video_type_lesson_add')
|
||||
@elseif ($lesson_type == 'amazon-s3')
|
||||
@include('amazon_s3_type_lesson_add.php')
|
||||
@elseif ($lesson_type == 'google_drive_video')
|
||||
@include('admin.course.google_drive_type_lesson_add')
|
||||
@elseif ($lesson_type == 'document')
|
||||
@ -67,8 +57,6 @@
|
||||
@include('admin.course.image_file_type_lesson_add')
|
||||
@elseif ($lesson_type == 'iframe')
|
||||
@include('admin.course.iframe_type_lesson_add')
|
||||
@elseif ($lesson_type == 'scorm')
|
||||
@include('admin.course.scorm_type_lesson_add')
|
||||
@endif
|
||||
|
||||
<div class="form-group mb-3">
|
||||
@ -123,16 +111,9 @@
|
||||
}
|
||||
|
||||
function checkURLValidity(video_url) {
|
||||
var youtubePregMatch =
|
||||
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
||||
var vimeoPregMatch = /^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/;
|
||||
if (video_url.match(youtubePregMatch)) {
|
||||
return true;
|
||||
} else if (vimeoPregMatch.test(video_url)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
var youtube = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
||||
return youtube.test(video_url);
|
||||
}
|
||||
|
||||
</script>
|
||||
@include('admin.init')
|
||||
|
||||
@ -30,47 +30,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
||||
for="radio-vimeo">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/video-circle-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Vimeo Video') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
||||
id="radio-vimeo" value="vimeo" @if ($selected_lesson == 'vimeo') checked @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
||||
for="radio-videofile">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/video-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Video file') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
||||
id="radio-videofile" value="video" @if ($selected_lesson == 'video') checked @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
||||
for="radio-url">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/link-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Video url [ .mp4 ]') }}</p>
|
||||
</div>
|
||||
<input value="html5" class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
||||
id="radio-url">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<!-- <div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
||||
for="radio-drive">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
@ -81,8 +41,7 @@
|
||||
id="radio-drive" value="google_drive_video"
|
||||
@if ($selected_lesson == 'google_drive_video') {{ get_phrase('checked') }} @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div> -->
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
||||
@ -130,7 +89,7 @@
|
||||
for="radio-iframe">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Iframe embed') }}</p>
|
||||
<p class="title">{{ get_phrase('File embed(ppt, pdf)') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
||||
id="radio-iframe" value="iframe"
|
||||
@ -138,19 +97,6 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
||||
for="radio-scorm">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Scorm Content') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
||||
id="radio-scorm" value="scorm"
|
||||
@if ($selected_lesson == 'scorm') {{ get_phrase('checked') }} @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
|
||||
@ -31,14 +31,6 @@
|
||||
</div>
|
||||
</div>
|
||||
@include('frontend.course_player.player_config')
|
||||
@elseif($lesson_details->lesson_type == 'system-video')
|
||||
<div class="overflow-hidden bd-r-10 mb-16 h-314 h-md-428 position-relative bg-light">
|
||||
<video poster="" id="player" playsinline controls>
|
||||
<source src="{{ asset($lesson_details->lesson_src) }}"
|
||||
type="video/mp4">
|
||||
</video>
|
||||
</div>
|
||||
@include('frontend.course_player.player_config')
|
||||
@elseif($lesson_details->lesson_type == 'image')
|
||||
<div class="overflow-hidden bd-r-10 mb-16 position-relative bg-light">
|
||||
@php
|
||||
@ -47,47 +39,41 @@
|
||||
@endphp
|
||||
<img width="100%" class="max-w-auto" height="auto" src="{{ $img }}" />
|
||||
</div>
|
||||
@elseif($lesson_details->lesson_type == 'vimeo-url' && $lesson_details->video_type == 'vimeo')
|
||||
@php
|
||||
$video_url = $lesson_details->lesson_src;
|
||||
$video_id = explode('https://vimeo.com/', $video_url);
|
||||
$video_id = str_replace('https://vimeo.com/', '', $video_url);
|
||||
@endphp
|
||||
<div class="overflow-hidden bd-r-10 mb-16 h-314 h-md-428 position-relative bg-light">
|
||||
<div class="plyr__video-embed " id="player">
|
||||
|
||||
|
||||
<iframe height="500"
|
||||
src="https://player.vimeo.com/video/{{ $video_id }}?loop=false&byline=false&portrait=false&title=false&speed=true&transparent=0&gesture=media"
|
||||
allowfullscreen allowtransparency allow="autoplay"></iframe>
|
||||
|
||||
|
||||
<div class="position-absolute top-50 start-50 translate-middle">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('frontend.course_player.player_config')
|
||||
@elseif($lesson_details->lesson_type == 'google_drive')
|
||||
@php
|
||||
$video_url = $lesson_details->lesson_src;
|
||||
$url_array_1 = explode('/', $video_url . '/');
|
||||
$url_array_2 = explode('=', $video_url);
|
||||
$video_id = null;
|
||||
if ($url_array_1[4] == 'd'):
|
||||
$video_id = $url_array_1[5];
|
||||
else:
|
||||
$video_id = $url_array_2[1];
|
||||
endif;
|
||||
$video_url = trim($lesson_details->lesson_src);
|
||||
|
||||
// Extract Google Drive file ID reliably from standard share links
|
||||
preg_match('/\/d\/([a-zA-Z0-9_-]+)/', $video_url, $matches);
|
||||
$video_id = $matches[1] ?? null;
|
||||
@endphp
|
||||
|
||||
<div class="overflow-hidden bd-r-10 mb-16 h-314 h-md-428 position-relative bg-light">
|
||||
<video id="player" playsinline controls>
|
||||
<source class="remove_video_src"
|
||||
src="https://www.googleapis.com/drive/v3/files/{{ $video_id }}?alt=media&key={{get_settings('youtube_api_key')}}"
|
||||
type="video/mp4">
|
||||
</video>
|
||||
</div>
|
||||
@include('frontend.course_player.player_config')
|
||||
@if($video_id)
|
||||
<div class="overflow-hidden bd-r-10 mb-16 h-314 h-md-428 position-relative bg-light">
|
||||
<!-- Responsive 16:9 ratio wrapper -->
|
||||
<div class="ratio ratio-16x9 w-100 h-100">
|
||||
<iframe
|
||||
src="https://drive.google.com/file/d/{{ $video_id }}/preview"
|
||||
allowfullscreen
|
||||
allow="autoplay; fullscreen; picture-in-picture"
|
||||
class="border-0 rounded-10"
|
||||
frameborder="0"
|
||||
loading="lazy">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
@include('frontend.course_player.player_config')
|
||||
@else
|
||||
<div class="overflow-hidden bd-r-10 mb-16 h-314 h-md-428 position-relative bg-light d-flex align-items-center justify-content-center">
|
||||
<div class="text-center text-danger">
|
||||
<h5>Invalid Google Drive Link</h5>
|
||||
<p class="mb-2">Could not extract video ID.</p>
|
||||
<small class="text-muted">Use a link like:<br>
|
||||
https://drive.google.com/file/d/<strong>FILE_ID</strong>/view
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@elseif($lesson_details->lesson_type == 'html5')
|
||||
<div class="overflow-hidden bd-r-10 mb-16 h-314 h-md-428 position-relative bg-light">
|
||||
|
||||
|
||||
@ -1,3 +1,40 @@
|
||||
<script>
|
||||
$(document).on('click', '.lesson-link', function (e) {
|
||||
e.preventDefault(); // ⛔ stop redirect sementara
|
||||
|
||||
let url = $(this).attr('href');
|
||||
let lessonId = $(this).data('lesson-id');
|
||||
let courseId = $(this).data('course-id');
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('set.watch.history') }}",
|
||||
type: "POST",
|
||||
data: {
|
||||
lesson_id: lessonId,
|
||||
course_id: courseId
|
||||
},
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
success: function (response) {
|
||||
console.log('Watch history updated:', response);
|
||||
|
||||
// 🔥 optional: refresh sidebar sebelum pindah
|
||||
reloadSidebar();
|
||||
|
||||
// ⏩ lanjutkan navigasi
|
||||
setTimeout(function () {
|
||||
window.location.href = url;
|
||||
}, 200);
|
||||
},
|
||||
error: function () {
|
||||
// kalau gagal, tetap lanjutkan navigasi
|
||||
window.location.href = url;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
|
||||
@ -210,6 +210,7 @@
|
||||
if (lesson_id && course_id && (currentDuration % 5) == 0 && previousSavedDuration != currentDuration) {
|
||||
previousSavedDuration = currentDuration;
|
||||
let url = "{{ route('update_watch_history') }}";
|
||||
let sidebarReloaded = false;
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
@ -224,7 +225,11 @@
|
||||
},
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
console.log(response.course_progress);
|
||||
|
||||
if (response.is_completed === 1 && !sidebarReloaded) {
|
||||
sidebarReloaded = true;
|
||||
reloadSidebar();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -9,126 +9,97 @@
|
||||
<div class="course-video-area border-primary border">
|
||||
<!-- Video -->
|
||||
<div class="course-video-wrap">
|
||||
<div id="player">
|
||||
<div id="player" class="ratio ratio-16x9">
|
||||
<iframe src="{{ $lesson_details->lesson_src }}?origin=https://plyr.io&iv_load_policy=3&modestbranding=1&playsinline=1&showinfo=0&rel=0&enablejsapi=1" allowfullscreen allowtransparency allow="autoplay"></iframe>
|
||||
</div>
|
||||
@include('course_player.player_config')
|
||||
</div>
|
||||
</div>
|
||||
@elseif ($lesson_details->lesson_type == 'scorm')
|
||||
<div class="course-video-area">
|
||||
<div class="course-video-wrap">
|
||||
<div>
|
||||
@if ($lesson_details->attachment_type == 'iSpring')
|
||||
<iframe class="embed-responsive-item"
|
||||
src="{{ asset('uploads/lesson_file/scorm_content/' . $lesson_details->attachment . '/res/index.html') }}"
|
||||
allowfullscreen allowtransparency width="100%" height="100%" allow="autoplay"></iframe>
|
||||
@elseif ($lesson_details->attachment_type == 'articulate')
|
||||
<iframe class="embed-responsive-item"
|
||||
src="{{ asset('uploads/lesson_file/scorm_content/' . $lesson_details->attachment . '/index.html') }}"
|
||||
allowfullscreen allowtransparency width="100%" height="100%" allow="autoplay"></iframe>
|
||||
@elseif ($lesson_details->attachment_type == 'adobeCaptivate')
|
||||
<iframe class="embed-responsive-item"
|
||||
src="{{ asset('uploads/lesson_file/scorm_content/' . $lesson_details->attachment . '/index.html') }}"
|
||||
allowfullscreen allowtransparency width="100%" height="100%" allow="autoplay"></iframe>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@elseif($lesson_details->lesson_type == 'system-video')
|
||||
@elseif($lesson_details->lesson_type == 'google_drive')
|
||||
@php
|
||||
$watermark_type = get_player_settings('watermark_type');
|
||||
$lesson_video = $lesson_details->lesson_src;
|
||||
if ($watermark_type == 'ffmpeg') {
|
||||
$origin = dirname($lesson_details->lesson_src);
|
||||
$dir = $origin . '/watermark';
|
||||
$file = str_replace($origin, '', $lesson_details->lesson_src);
|
||||
$lesson_video = "{$dir}{$file}";
|
||||
}
|
||||
$video_url = trim($lesson_details->lesson_src);
|
||||
preg_match('/\/d\/([a-zA-Z0-9_-]+)/', $video_url, $matches);
|
||||
$video_id = $matches[1] ?? null;
|
||||
@endphp
|
||||
<div class="course-video-area border-primary border">
|
||||
<!-- Video -->
|
||||
<div class="course-video-wrap">
|
||||
<div class=" bd-r-10 mb-16 position-relative bg-light custom-system-video">
|
||||
<video id="player" playsinline controls oncontextmenu="return false;">
|
||||
{{-- <source src="{{ asset($lesson_details->lesson_src) }}" type="video/mp4"> --}}
|
||||
<source src="{{ route('course.get_file', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id]) }}" type="video/mp4">
|
||||
</video>
|
||||
@include('course_player.player_config')
|
||||
|
||||
@if($video_id)
|
||||
<div class="course-video-area border-primary border position-relative">
|
||||
<!-- Responsive wrapper with 16:9 aspect ratio -->
|
||||
<div class="ratio ratio-16x9 w-100">
|
||||
<iframe
|
||||
src="https://drive.google.com/file/d/{{ $video_id }}/preview"
|
||||
allowfullscreen
|
||||
allow="autoplay; fullscreen; picture-in-picture"
|
||||
class="border-0 rounded"
|
||||
frameborder="0"
|
||||
loading="lazy">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('course_player.player_config')
|
||||
@else
|
||||
<div class="alert alert-danger text-center py-5">
|
||||
<h5>Invalid Google Drive Link</h5>
|
||||
<p>Could not extract video ID from the provided URL.</p>
|
||||
</div>
|
||||
@endif
|
||||
@elseif($lesson_details->lesson_type == 'image')
|
||||
@php
|
||||
// $img = asset('uploads/lesson_file/attachment/' . $lesson_details->attachment);
|
||||
$img = route('course.get_file', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id])
|
||||
@endphp
|
||||
<img width="100%" class="max-w-auto" height="auto" src="{{ $img }}" />
|
||||
@elseif($lesson_details->lesson_type == 'vimeo-url' && $lesson_details->video_type == 'vimeo')
|
||||
@php
|
||||
$video_url = $lesson_details->lesson_src;
|
||||
$video_id = explode('https://vimeo.com/', $video_url);
|
||||
$video_id = str_replace('https://vimeo.com/', '', $video_url);
|
||||
@endphp
|
||||
|
||||
<div class="course-video-area border-primary border">
|
||||
<!-- Video -->
|
||||
<div class="course-video-wrap">
|
||||
<div id="player">
|
||||
<iframe height="500" src="https://player.vimeo.com/video/{{ $video_id }}?loop=false&byline=false&portrait=false&title=false&speed=true&transparent=0&gesture=media" allowfullscreen allowtransparency allow="autoplay"></iframe>
|
||||
@include('course_player.player_config')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@elseif($lesson_details->lesson_type == 'google_drive')
|
||||
@php
|
||||
$video_url = $lesson_details->lesson_src;
|
||||
$url_array_1 = explode('/', $video_url . '/');
|
||||
$url_array_2 = explode('=', $video_url);
|
||||
$video_id = null;
|
||||
if ($url_array_1[4] == 'd'):
|
||||
$video_id = $url_array_1[5];
|
||||
else:
|
||||
$video_id = $url_array_2[1];
|
||||
endif;
|
||||
@endphp
|
||||
<div class="course-video-area border-primary border">
|
||||
<!-- Video -->
|
||||
<div class="course-video-wrap">
|
||||
<video width="100%" height="680" id="player" playsinline controls>
|
||||
<source class="" src="https://www.googleapis.com/drive/v3/files/{{ $video_id }}?alt=media&key={{ get_settings('youtube_api_key') }}" type="video/mp4">
|
||||
</video>
|
||||
@include('course_player.player_config')
|
||||
</div>
|
||||
</div>
|
||||
@elseif($lesson_details->lesson_type == 'html5')
|
||||
<div class="course-video-area border-primary border">
|
||||
<!-- Video -->
|
||||
<div class="course-video-wrap">
|
||||
<video width="100%" height="680" id="player" playsinline controls>
|
||||
<source class="remove_video_src" src="{{ $lesson_details->lesson_src }}" type="video/mp4">
|
||||
</video>
|
||||
@include('course_player.player_config')
|
||||
</div>
|
||||
</div>
|
||||
@elseif($lesson_details->lesson_type == 'document_type')
|
||||
@php
|
||||
$src = route('course.get_file', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id])
|
||||
@endphp
|
||||
@if ($lesson_details->attachment_type == 'pdf')
|
||||
{{-- <iframe class="embed-responsive-item" width="100%" src="{{ $src }}" allowfullscreen></iframe> --}}
|
||||
@php
|
||||
$src = route('course.get_file', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id]);
|
||||
$pdf_src = route('pdf_canvas', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id]);
|
||||
$direct_pdf = $src; // URL langsung ke file PDF
|
||||
$fullscreen_id = 'lesson-content-' . $lesson_details->id;
|
||||
@endphp
|
||||
|
||||
<iframe class="embed-responsive-item" width="100%" height="600px" src="{{ route('pdf_canvas', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id]) }}" allowfullscreen></iframe>
|
||||
<div class="position-relative d-inline-block w-100">
|
||||
<div id="{{ $fullscreen_id }}" class="w-100 border rounded overflow-hidden bg-light">
|
||||
@if ($lesson_details->attachment_type == 'pdf')
|
||||
<a href="{{ $direct_pdf }}" target="_blank" class="btn btn-sm position-absolute top-0 end-0 mt-2 me-2 shadow" style="z-index: 1050; color: white; background: #001151;" title="Buka PDF di Tab Baru (tekan F11 untuk full screen)">
|
||||
<i class="bi bi-box-arrow-up-right"></i> Buka Full PDF
|
||||
</a>
|
||||
<iframe src="{{ $pdf_src }}#toolbar=1&navpanes=0&scrollbar=1&view=FitH"
|
||||
class="w-100 border-0"
|
||||
style="height: 80vh; min-height: 600px;"
|
||||
allowfullscreen
|
||||
allow="fullscreen">
|
||||
</iframe>
|
||||
@elseif($lesson_details->attachment_type == 'txt')
|
||||
<iframe src="{{ $src }}"
|
||||
class="w-100 border-0"
|
||||
style="height: 80vh; min-height: 600px;"
|
||||
frameborder="0">
|
||||
</iframe>
|
||||
@else
|
||||
<div class="d-flex flex-column justify-content-center align-items-center"
|
||||
style="height: 60vh; min-height: 300px;">
|
||||
|
||||
<div class="text-center mb-3">
|
||||
<p class="mt-3 mb-1 fw-bold">
|
||||
Dokumen tidak dapat ditampilkan secara langsung
|
||||
</p>
|
||||
<p class="text-muted small">
|
||||
Silakan unduh file untuk melihat isi dokumen
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@elseif($lesson_details->attachment_type == 'doc' || $lesson_details->attachment_type == 'ppt')
|
||||
<iframe class="embed-responsive-item" width='100%' src="https://view.officeapps.live.com/op/embed.aspx?src={{ $src }}" frameborder='0'></iframe>
|
||||
@elseif($lesson_details->attachment_type == 'txt')
|
||||
<iframe class="embed-responsive-item" width='100%' src="{{ $src }}" frameborder='0'></iframe>
|
||||
@endif
|
||||
<a href="{{ $src }}"
|
||||
class="btn btn-primary"
|
||||
target="_blank"
|
||||
download>
|
||||
<i class="fa fa-download me-1"></i>
|
||||
Download Dokumen
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@elseif($lesson_details->lesson_type == 'quiz')
|
||||
<div class="course-video-area border-primary pb-5">
|
||||
@include('course_player.quiz.index')
|
||||
@ -143,4 +114,19 @@
|
||||
document.getElementById('player').oncontextmenu = function() {
|
||||
return false; // Prevent right-click menu
|
||||
};
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function reloadSidebar() {
|
||||
let courseId = '{{ $course_details->id }}';
|
||||
let lessonId = '{{ $lesson_details->id }}';
|
||||
|
||||
let url = "{{ route('course.sidebar.reload', ['course_id' => '__COURSE__', 'lesson_id' => '__LESSON__']) }}";
|
||||
url = url.replace('__COURSE__', courseId)
|
||||
.replace('__LESSON__', lessonId);
|
||||
|
||||
$('#player_side_bar').load(url, function () {
|
||||
console.log('Sidebar updated');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -70,6 +70,28 @@
|
||||
->get();
|
||||
@endphp
|
||||
|
||||
@php
|
||||
$is_passed = false;
|
||||
|
||||
if ($submits->count() > 0 && $questions->count() > 0) {
|
||||
$mark_per_question = $quiz->total_mark / $questions->count();
|
||||
|
||||
foreach ($submits as $submit) {
|
||||
$correct_answers = $submit->correct_answer
|
||||
? json_decode($submit->correct_answer, true)
|
||||
: [];
|
||||
|
||||
$obtained_mark = count($correct_answers) * $mark_per_question;
|
||||
|
||||
if ($obtained_mark >= $quiz->pass_mark) {
|
||||
$is_passed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
|
||||
|
||||
<div class="row px-4">
|
||||
<div class="col-12">
|
||||
<h4 class="quiz-title text-center mt-4"><span>{{ $quiz->title }}</span></h4>
|
||||
@ -135,10 +157,13 @@
|
||||
id="{{ $submit->id }}">{{ get_phrase('View Result') }} {{ ++$key }}</button>
|
||||
@endforeach
|
||||
|
||||
@if ($submits->count() < $quiz->retake)
|
||||
<button type="button" class="eBtn gradient border-0"
|
||||
id="starterBtn">{{ get_phrase('Start Quiz') }}</button>
|
||||
@endif
|
||||
@if (!$is_passed && $submits->count() < $quiz->retake)
|
||||
<button type="button" class="eBtn gradient border-0"
|
||||
id="starterBtn">
|
||||
{{ get_phrase('Start Quiz') }}
|
||||
</button>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -138,29 +138,7 @@
|
||||
|
||||
// Submit quiz
|
||||
function submitQuiz() {
|
||||
|
||||
var quizId = "{{ $quiz->id }}";
|
||||
var completed_lesson_arr = @json($completed_lesson_arr); // Convert the PHP array to a JavaScript array
|
||||
|
||||
// Check if quizId is in the completed_lesson_arr array using JavaScript's `includes()` method
|
||||
if (!completed_lesson_arr.includes(quizId)) {
|
||||
$.ajax({
|
||||
url: "{{ route('set.watch.history') }}", // Your route
|
||||
type: "post",
|
||||
data: {
|
||||
lesson_id: "{{ $quiz->id }}",
|
||||
course_id: "{{ $course_details->id }}"
|
||||
},
|
||||
success: function(response) {
|
||||
submitForm.submit();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error updating watch history:", xhr.responseText);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
submitForm.submit();
|
||||
}
|
||||
submitForm.submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -63,23 +63,30 @@
|
||||
@php $type = $lesson->lesson_type; @endphp
|
||||
<li class="coourse-playlist-item @if (isset($history->watching_lesson_id) && $lesson->id == $history->watching_lesson_id || $lesson->id == $lesson_details->id) active @else lock @endif">
|
||||
<div class="check-title-area align-items-center">
|
||||
|
||||
@if($course_details->enable_drip_content)
|
||||
@if($is_locked)
|
||||
<i class="fas fa-lock" title="<?php echo get_phrase('Complete previous lesson to unlock it'); ?>"></i>
|
||||
@else
|
||||
@if(in_array($lesson->id, $completed_lesson_arr))
|
||||
<i class="fas fa-check-circle checkbox-icon" title="<?php echo get_phrase('Lesson completed'); ?>"></i>
|
||||
@elseif(in_array($type, ['video-url', 'system-video', 'vimeo-url', 'google_drive']))
|
||||
@elseif(in_array($type, ['video-url', 'google_drive']))
|
||||
<i class="form-check-input flexCheckChecked mt-0" title="<?php echo get_phrase('Play Now'); ?>"></i>
|
||||
@else
|
||||
<input class="form-check-input flexCheckChecked mt-0" @if (in_array($lesson->id, $completed_lesson)) checked @endif type="checkbox" id="{{ $lesson->id }}">
|
||||
<input
|
||||
class="form-check-input mt-0"
|
||||
type="checkbox"
|
||||
id="{{ $lesson->id }}"
|
||||
@if (in_array($lesson->id, $completed_lesson)) checked @endif
|
||||
disabled
|
||||
>
|
||||
@endif
|
||||
@endif
|
||||
<div class="play-lock-number">
|
||||
<span>
|
||||
@if (in_array($type, ['text', 'document_type', 'iframe']))
|
||||
<i class="fa-solid fa-file"></i>
|
||||
@elseif (in_array($type, ['video-url', 'system-video', 'vimeo-url']))
|
||||
@elseif (in_array($type, ['video-url']))
|
||||
<i class="fa-solid fa-video"></i>
|
||||
@elseif ($type == 'image')
|
||||
<i class="fa-solid fa-image"></i>
|
||||
@ -91,7 +98,19 @@
|
||||
</span>
|
||||
</div>
|
||||
<p class="d-none">{{ $lesson->lesson_type }}</p>
|
||||
<a href="{{ route('course.player', ['slug' => $course_details->slug, 'id' => $lesson->id]) }}" class="video-title">{{ $lesson->title }}</a>
|
||||
@if (in_array($type, ['google_drive', 'video-url', 'quiz']))
|
||||
<a href="{{ route('course.player', ['slug' => $course_details->slug, 'id' => $lesson->id]) }}"
|
||||
class="video-title">
|
||||
{{ $lesson->title }}
|
||||
</a>
|
||||
@else
|
||||
<a href="{{ route('course.player', ['slug' => $course_details->slug, 'id' => $lesson->id]) }}"
|
||||
class="video-title lesson-link"
|
||||
data-lesson-id="{{ $lesson->id }}"
|
||||
data-course-id="{{ $course_details->id }}">
|
||||
{{ $lesson->title }}
|
||||
</a>
|
||||
@endif
|
||||
@else
|
||||
<input class="form-check-input flexCheckChecked mt-0" @if (in_array($lesson->id, $completed_lesson)) checked @endif type="checkbox" id="{{ $lesson->id }}">
|
||||
<div class="play-lock-number">
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
$average_rating = $rating / $total;
|
||||
}
|
||||
@endphp
|
||||
<!------------------- Breadcum Area Start ------>
|
||||
<section class="breadcum-area page-content-pb-100 bg-white">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@ -34,14 +33,11 @@
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="course-details pe-auto pe-lg-5">
|
||||
|
||||
<h2 class="g-title ellipsis-line-4">{{ $course_details->title }}</h2>
|
||||
<p class="g-text text-dark ellipsis-line-2">
|
||||
{{ ellipsis($course_details->short_description, 160) }}
|
||||
</p>
|
||||
|
||||
<div class="row row-gap-4">
|
||||
<div class="col-6 col-sm-6 col-md-4">
|
||||
<a class="d-flex align-items-center text-dark" href="{{ route('instructor.details', ['name' => slugify($course_details->creator->name), 'id' => $course_details->creator->id]) }}">
|
||||
@ -80,20 +76,15 @@
|
||||
{{ total_durations($course_details->id) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 order-2 order-lg-1">
|
||||
|
||||
<div class="details-page-content">
|
||||
<div class="ps-box static-menu mt-5 w-100">
|
||||
<ul class="nav nav-bordered" id="pills-tab" role="tablist">
|
||||
@ -138,54 +129,83 @@
|
||||
@include('frontend.default.course.pricing_card')
|
||||
</div>
|
||||
</div>
|
||||
<!------------------- Player Feature Area End --------->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!------------------- Breadcum Area End --------->
|
||||
|
||||
|
||||
<!-- Vertically centered modal -->
|
||||
<div class="modal fade-in-effect" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body bg-dark">
|
||||
<div class="modal-content radius-22 overflow-hidden border-0">
|
||||
<div class="modal-header border-0 pb-0 position-relative">
|
||||
<button type="button" class="btn-close btn-close-white shadow-none position-absolute end-0 top-0 m-3" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body bg-dark p-0">
|
||||
<link rel="stylesheet" href="{{ asset('assets/global/plyr/plyr.css') }}">
|
||||
|
||||
@php
|
||||
$preview_video_type = str_contains($course_details->preview, 'youtu') ? 'youtube' : '';
|
||||
$preview_video_type = str_contains($course_details->preview, 'vimeo') && $preview_video_type == '' ? 'vimeo' : $preview_video_type;
|
||||
$preview_video_type = str_contains($course_details->preview, 'http') && $preview_video_type == '' ? 'html5' : $preview_video_type;
|
||||
$preview = $course_details->preview ?? '';
|
||||
|
||||
// Detect video type
|
||||
$video_type = 'html5'; // default fallback
|
||||
|
||||
if (str_contains($preview, 'youtu')) {
|
||||
$video_type = 'youtube';
|
||||
} elseif (preg_match('/drive\.google\.com\/file\/d\/([a-zA-Z0-9_-]+)/', $preview, $matches)) {
|
||||
$video_type = 'google_drive';
|
||||
$google_drive_id = $matches[1];
|
||||
} elseif (str_contains($preview, 'http') && (str_ends_with($preview, '.mp4') || str_contains($preview, '.mp4'))) {
|
||||
$video_type = 'html5';
|
||||
} elseif (!empty($preview)) {
|
||||
// Local asset (stored in storage or public folder)
|
||||
$video_type = 'html5_local';
|
||||
}
|
||||
@endphp
|
||||
|
||||
@if ($preview_video_type == 'youtube')
|
||||
@if ($video_type == 'youtube')
|
||||
<div class="plyr__video-embed" id="promoPlayer">
|
||||
<iframe height="500" src="{{ $course_details->preview }}?origin=https://plyr.io&iv_load_policy=3&modestbranding=1&playsinline=1&showinfo=0&rel=0&enablejsapi=1" allowfullscreen allowtransparency allow="autoplay"></iframe>
|
||||
<iframe
|
||||
src="{{ str_replace('watch?v=', 'embed/', $preview) }}?autoplay=1&rel=0&modestbranding=1&playsinline=1"
|
||||
allowfullscreen
|
||||
allow="autoplay">
|
||||
</iframe>
|
||||
</div>
|
||||
@elseif ($preview_video_type == 'vimeo')
|
||||
|
||||
@elseif ($video_type == 'google_drive')
|
||||
<div class="plyr__video-embed" id="promoPlayer">
|
||||
<iframe height="500" id="promoPlayer" src="https://player.vimeo.com/video/{{ $course_details->preview }}?loop=false&byline=false&portrait=false&title=false&speed=true&transparent=0&gesture=media" allowfullscreen allowtransparency allow="autoplay"></iframe>
|
||||
<iframe
|
||||
src="https://drive.google.com/file/d/{{ $google_drive_id }}/preview"
|
||||
width="100%"
|
||||
height="500"
|
||||
allowfullscreen
|
||||
allow="autoplay">
|
||||
</iframe>
|
||||
</div>
|
||||
@elseif($preview_video_type == 'html5')
|
||||
<video id="promoPlayer" playsinline controls>
|
||||
<source src="{{ $course_details->preview }}" type="video/mp4">
|
||||
|
||||
@elseif ($video_type == 'html5' || $video_type == 'html5_local')
|
||||
<video id="promoPlayer" playsinline controls crossorigin>
|
||||
<source src="{{ $video_type == 'html5_local' ? asset($preview) : $preview }}" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
@else
|
||||
<video id="promoPlayer" playsinline controls>
|
||||
<source src="{{ asset($course_details->preview) }}" type="video/mp4">
|
||||
</video>
|
||||
<div class="d-flex align-items-center justify-content-center text-white" style="height: 500px;">
|
||||
<p class="h4">{{ get_phrase('No preview video available') }}</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<script src="{{ asset('assets/global/plyr/plyr.js') }}"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
const promoPlayer = new Plyr('#promoPlayer');
|
||||
const promoPlayer = new Plyr('#promoPlayer', {
|
||||
controls: ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'fullscreen'],
|
||||
autoplay: true,
|
||||
clickToPlay: true,
|
||||
youtube: { noCookie: true, rel: 0, modestbranding: 1 },
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
const myModalElement = document.getElementById('exampleModal')
|
||||
|
||||
@ -80,33 +80,64 @@
|
||||
"use strict";
|
||||
$(document).ready(function() {
|
||||
|
||||
// Hide dropdown when clicking outside
|
||||
$(document).on('click', function(event) {
|
||||
if (!$(event.target).closest('.search-box').length) {
|
||||
$('#msg-search-list').removeClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Show dropdown when clicking/focusing the search input
|
||||
$('.Esearch_entry').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$('#msg-search-list').addClass('active');
|
||||
});
|
||||
|
||||
let debounceTimer;
|
||||
const debounceDelay = 800; // 0.8 seconds
|
||||
|
||||
$('#search_student').keyup(function(e) {
|
||||
let searchTerm = $(this).val();
|
||||
$('#search_student').on('keyup', function(e) {
|
||||
let searchTerm = $(this).val().trim();
|
||||
|
||||
if (searchTerm.indexOf('@') !== -1) {
|
||||
// Always clear previous timer
|
||||
clearTimeout(debounceTimer);
|
||||
|
||||
// If input is empty, clear results and hide dropdown
|
||||
if (searchTerm === '') {
|
||||
$('#msg-search-list').empty().removeClass('active');
|
||||
return;
|
||||
}
|
||||
|
||||
// Optional: Only search if at least 2-3 characters (better UX + performance)
|
||||
// Remove this block if you want to search even with 1 character
|
||||
if (searchTerm.length < 2) {
|
||||
$('#msg-search-list').empty().removeClass('active');
|
||||
return;
|
||||
}
|
||||
|
||||
// Show dropdown immediately while waiting
|
||||
$('#msg-search-list').addClass('active');
|
||||
|
||||
// Set new timer — API will be called after 800ms of no typing
|
||||
debounceTimer = setTimeout(function() {
|
||||
$.ajax({
|
||||
type: "post",
|
||||
type: "POST",
|
||||
url: "{{ route('search.student') }}",
|
||||
data: {
|
||||
search_mail: searchTerm
|
||||
search_mail: searchTerm,
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
$('#msg-search-list').empty().append(response);
|
||||
$('#msg-search-list')
|
||||
.empty()
|
||||
.append(response)
|
||||
.addClass('active');
|
||||
},
|
||||
error: function() {
|
||||
$('#msg-search-list').empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, debounceDelay);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -14,33 +14,11 @@
|
||||
|
||||
<hr class="bg-secondary my-4">
|
||||
|
||||
<div class="row mb-3">
|
||||
@php
|
||||
$preview_video_type = str_contains($course_details->preview, 'youtu') ? 'youtube' : '';
|
||||
$preview_video_type = str_contains($course_details->preview, 'vimeo') && $preview_video_type == '' ? 'vimeo' : '';
|
||||
$preview_video_type = str_contains($course_details->preview, 'http') && $preview_video_type == '' ? 'html5' : '';
|
||||
@endphp
|
||||
<label for="preview_video_link" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Preview Video') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="radio" onchange="$('#preview_link_input').toggleClass('d-hidden'); $('#preview_file_input').toggleClass('d-hidden');" class="form-check-input" value="link" name="preview_video_provider" id="preview_video_link" @if ($preview_video_type != '') checked @endif> <label for="preview_video_link">{{ get_phrase('Video Link') }}</label>
|
||||
|
||||
<input type="radio" onchange="$('#preview_link_input').toggleClass('d-hidden'); $('#preview_file_input').toggleClass('d-hidden');" class="form-check-input" value="file" name="preview_video_provider" id="preview_video_file" @if ($preview_video_type == '') checked @endif> <label for="preview_video_file">{{ get_phrase('Video File') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 @if ($preview_video_type == '') d-hidden @endif" id="preview_link_input">
|
||||
<div class="row mb-3" id="preview_link_input">
|
||||
<label for="preview_link" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Video link') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" name = "preview_link" id = "preview_link" class="form-control ol-form-control" value="{{ $course_details->preview }}">
|
||||
<small class="text-muted">{{ get_phrase('Supported URL') }}: <b>{{ get_phrase('Youtube') }}</b> {{ get_phrase('or') }} <b>{{ get_phrase('Vimeo') }}</b> {{ get_phrase('or') }} <b>{{ get_phrase('HTML5') }}</b></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 @if ($preview_video_type != '') d-hidden @endif" id="preview_file_input">
|
||||
<label for="preview" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Preview Video File') }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="file" name="preview" class="form-control ol-form-control" id="preview" accept="video/*" />
|
||||
<small class="text-muted">{{ get_phrase('Supported Video file') }}: <b>.{{ get_phrase('mp4') }}</b> {{ get_phrase('or') }} <b>.{{ get_phrase('webm') }}</b> {{ get_phrase('or') }} <b>.{{ get_phrase('ogg') }}</b></small>
|
||||
<small class="text-muted">{{ get_phrase('Supported URL') }}: <b>{{ get_phrase('Youtube') }}</b> {{ get_phrase('or') }}<b>{{ get_phrase('Google Drive') }}</b></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -28,41 +28,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-vimeo">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/video-circle-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Vimeo Video') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-vimeo" value="vimeo" @if ($selected_lesson == 'vimeo') checked @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-videofile">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/video-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Video file') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-videofile" value="video" @if ($selected_lesson == 'video') checked @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-url">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/link-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Video url [ .mp4 ]') }}</p>
|
||||
</div>
|
||||
<input value="html5" class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-url">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<!-- <div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-drive">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/document-black-18.svg" alt="">
|
||||
@ -70,7 +36,7 @@
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-drive" value="google_drive_video" @if ($selected_lesson == 'google_drive_video') {{ get_phrase('checked') }} @endif>
|
||||
</label>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
<div class="col">
|
||||
@ -110,24 +76,11 @@
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-iframe">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Iframe embed') }}</p>
|
||||
<p class="title">{{ get_phrase('File embed(ppt, pdf)') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-iframe" value="iframe" @if ($selected_lesson == 'iframe') {{ get_phrase('checked') }} @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
||||
for="radio-scorm">
|
||||
<div class="title-icon d-flex align-items-center">
|
||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
||||
<p class="title">{{ get_phrase('Scorm Content') }}</p>
|
||||
</div>
|
||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
||||
id="radio-scorm" value="scorm"
|
||||
@if ($selected_lesson == 'scorm') {{ get_phrase('checked') }} @endif>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
|
||||
@ -11,6 +11,7 @@ Route::middleware(['auth'])->group(function () {
|
||||
Route::get('play-course/{slug}/{id?}', 'course_player')->name('course.player');
|
||||
Route::post('set-watch-history/', 'set_watch_history')->name('set.watch.history');
|
||||
Route::get('player/prepend/watermark', 'prepend_watermark')->name('player.prepend.watermark');
|
||||
Route::get('course-player/sidebar/{course_id}/{lesson_id}', 'reload_sidebar')->name('course.sidebar.reload');
|
||||
});
|
||||
|
||||
Route::controller(ForumController::class)->group(function () {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user