Compare commits
No commits in common. "fbb03ba9fe92ac327f95f778da9274d09fa1dc58" and "731e95a8643780d785ca10ce5baa6fc708f6a070" have entirely different histories.
fbb03ba9fe
...
731e95a864
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\BookingModel;
|
|
||||||
use App\Models\DataSoalModel;
|
use App\Models\DataSoalModel;
|
||||||
use App\Models\DetailTestModel;
|
use App\Models\DetailTestModel;
|
||||||
use App\Models\TestSessionsModel;
|
use App\Models\TestSessionsModel;
|
||||||
|
|
@ -11,77 +10,20 @@
|
||||||
class HalamanUjianController extends Controller
|
class HalamanUjianController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
function fetchQuestion(Request $request) {
|
|
||||||
$data_question = DataSoalModel::all();
|
|
||||||
if($data_question != null) {
|
|
||||||
$number_question = $request->question_number;
|
|
||||||
if($number_question <= 0 || $number_question > count($data_question)) {
|
|
||||||
$number_question = 1;
|
|
||||||
}
|
|
||||||
return response()->json([
|
|
||||||
'status' => true,
|
|
||||||
'data' => $data_question[$number_question - 1]
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
return response()->json([
|
|
||||||
'status' => false,
|
|
||||||
'message' => 'Data soal tidak ditemukan.'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCurrentAnswer(Request $request) {
|
public function getCurrentAnswer(Request $request) {
|
||||||
$data_choice = DataSoalModel::where('id_soal', $request->id_question)->get();
|
|
||||||
$choices = [];
|
|
||||||
if($data_choice != null) {
|
|
||||||
foreach($data_choice as $choice) {
|
|
||||||
if($choice->jawaban_a != null) {
|
|
||||||
$choices[] = [
|
|
||||||
'key' => 'a',
|
|
||||||
'value' => $choice->jawaban_a
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if($choice->jawaban_b != null) {
|
|
||||||
$choices[] = [
|
|
||||||
'key' => 'b',
|
|
||||||
'value' => $choice->jawaban_b
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if($choice->jawaban_c != null) {
|
|
||||||
$choices[] = [
|
|
||||||
'key' => 'c',
|
|
||||||
'value' => $choice->jawaban_c
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if($choice->jawaban_d != null) {
|
|
||||||
$choices[] = [
|
|
||||||
'key' => 'd',
|
|
||||||
'value' => $choice->jawaban_d
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if($choice->jawaban_e != null) {
|
|
||||||
$choices[] = [
|
|
||||||
'key' => 'e',
|
|
||||||
'value' => $choice->jawaban_e
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data_answer = DetailTestModel::where('id_soal', $request->id_question)
|
$data_answer = DetailTestModel::where('id_soal', $request->id_question)
|
||||||
->where('id_test_sessions', $request->session_id)
|
->where('id_test_sessions', $request->session_id)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if($data_answer != null) {
|
if($data_answer != null) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => true,
|
'status' => 'success',
|
||||||
'jawaban' => $data_answer->jawaban,
|
'jawaban' => $data_answer->jawaban
|
||||||
'choices' => $choices
|
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => true,
|
'status' => 'error',
|
||||||
'jawaban' => null,
|
'message' => 'Data jawaban tidak ditemukan.'
|
||||||
'choices' => $choices
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -155,14 +97,10 @@ public function index(Request $request)
|
||||||
]);
|
]);
|
||||||
} else if($data_session->is_active == '1') {
|
} else if($data_session->is_active == '1') {
|
||||||
if(time() > $data_session->unix_end_time) {
|
if(time() > $data_session->unix_end_time) {
|
||||||
$data_booking = BookingModel::where('id_booking', $data_session->id_booking)->first();
|
|
||||||
$data_session->update([
|
$data_session->update([
|
||||||
'status_session' => '2',
|
'status_session' => '2',
|
||||||
'is_active' => '0'
|
'is_active' => '0'
|
||||||
]);
|
]);
|
||||||
$data_booking->update([
|
|
||||||
'status_tes' => '2'
|
|
||||||
]);
|
|
||||||
return redirect()->route('cek-status.index')->with('error', 'Waktu sesi tes telah habis. Silahkan cek status dengan kode untuk informasi lebih lanjut.');
|
return redirect()->route('cek-status.index')->with('error', 'Waktu sesi tes telah habis. Silahkan cek status dengan kode untuk informasi lebih lanjut.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -171,87 +109,87 @@ public function index(Request $request)
|
||||||
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes tidak ditemukan. Silakan mulai tes terlebih dahulu.');
|
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes tidak ditemukan. Silakan mulai tes terlebih dahulu.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// $question_number = null;
|
$question_number = null;
|
||||||
// $data_question = null;
|
$data_question = null;
|
||||||
// if(session('question') != null) {
|
if(session('question') != null) {
|
||||||
// $question_number = session('question');
|
$question_number = session('question');
|
||||||
// } else if($request->question != null) {
|
} else if($request->question != null) {
|
||||||
// $question_number = $request->question;
|
$question_number = $request->question;
|
||||||
// } else {
|
} else {
|
||||||
// $question_number = 1;
|
$question_number = 1;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// $data_question = DataSoalModel::all();
|
$data_question = DataSoalModel::all();
|
||||||
// $answered_question = [];
|
$answered_question = [];
|
||||||
// $index_question = 1;
|
$index_question = 1;
|
||||||
// foreach($data_question as $detail) {
|
foreach($data_question as $detail) {
|
||||||
// $detail_answer = DetailTestModel::where('id_soal', $detail->id_soal)
|
$detail_answer = DetailTestModel::where('id_soal', $detail->id_soal)
|
||||||
// ->where('id_test_sessions', $id_session)
|
->where('id_test_sessions', $id_session)
|
||||||
// ->first();
|
->first();
|
||||||
// if($detail_answer != null) {
|
if($detail_answer != null) {
|
||||||
// $answered_question[] = [
|
$answered_question[] = [
|
||||||
// 'id_soal' => $detail->id_soal,
|
'id_soal' => $detail->id_soal,
|
||||||
// 'nomor_soal' => $index_question,
|
'nomor_soal' => $index_question,
|
||||||
// 'answered' => true,
|
'answered' => true,
|
||||||
// 'jawaban' => $detail_answer->jawaban
|
'jawaban' => $detail_answer->jawaban
|
||||||
// ];
|
];
|
||||||
// } else {
|
} else {
|
||||||
// $answered_question[] = [
|
$answered_question[] = [
|
||||||
// 'id_soal' => $detail->id_soal,
|
'id_soal' => $detail->id_soal,
|
||||||
// 'nomor_soal' => $index_question,
|
'nomor_soal' => $index_question,
|
||||||
// 'answered' => false,
|
'answered' => false,
|
||||||
// 'jawaban' => null
|
'jawaban' => null
|
||||||
// ];
|
];
|
||||||
// }
|
}
|
||||||
// $index_question++;
|
$index_question++;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// $total_question = null;
|
$total_question = null;
|
||||||
// $is_last_question = false;
|
$is_last_question = false;
|
||||||
// if($question_number <= 0 || $question_number > count($data_question)) {
|
if($question_number <= 0 || $question_number > count($data_question)) {
|
||||||
// $question_number = 1;
|
$question_number = 1;
|
||||||
// }
|
}
|
||||||
// if(count($data_question) == $question_number) {
|
if(count($data_question) == $question_number) {
|
||||||
// $is_last_question = true;
|
$is_last_question = true;
|
||||||
// }
|
}
|
||||||
// $total_question = count($data_question);
|
$total_question = count($data_question);
|
||||||
// $data_question = $data_question[$question_number - 1];
|
$data_question = $data_question[$question_number - 1];
|
||||||
|
|
||||||
// $answer = [];
|
$answer = [];
|
||||||
// if($data_question->jawaban_a != null) {
|
if($data_question->jawaban_a != null) {
|
||||||
// $answer[] = [
|
$answer[] = [
|
||||||
// 'key' => 'a',
|
'key' => 'a',
|
||||||
// 'value' => $data_question->jawaban_a
|
'value' => $data_question->jawaban_a
|
||||||
// ];
|
];
|
||||||
// }
|
}
|
||||||
// if($data_question->jawaban_b != null) {
|
if($data_question->jawaban_b != null) {
|
||||||
// $answer[] = [
|
$answer[] = [
|
||||||
// 'key' => 'b',
|
'key' => 'b',
|
||||||
// 'value' => $data_question->jawaban_b
|
'value' => $data_question->jawaban_b
|
||||||
// ];
|
];
|
||||||
// }
|
}
|
||||||
// if($data_question->jawaban_c != null) {
|
if($data_question->jawaban_c != null) {
|
||||||
// $answer[] = [
|
$answer[] = [
|
||||||
// 'key' => 'c',
|
'key' => 'c',
|
||||||
// 'value' => $data_question->jawaban_c
|
'value' => $data_question->jawaban_c
|
||||||
// ];
|
];
|
||||||
// }
|
}
|
||||||
// if($data_question->jawaban_d != null) {
|
if($data_question->jawaban_d != null) {
|
||||||
// $answer[] = [
|
$answer[] = [
|
||||||
// 'key' => 'd',
|
'key' => 'd',
|
||||||
// 'value' => $data_question->jawaban_d
|
'value' => $data_question->jawaban_d
|
||||||
// ];
|
];
|
||||||
// }
|
}
|
||||||
// if($data_question->jawaban_e != null) {
|
if($data_question->jawaban_e != null) {
|
||||||
// $answer[] = [
|
$answer[] = [
|
||||||
// 'key' => 'e',
|
'key' => 'e',
|
||||||
// 'value' => $data_question->jawaban_e
|
'value' => $data_question->jawaban_e
|
||||||
// ];
|
];
|
||||||
// }
|
}
|
||||||
|
|
||||||
// dd($answer);
|
// dd($answer);
|
||||||
|
|
||||||
return view("user.pages.ujian.temp_index", compact('data_session'));
|
return view("user.pages.ujian.index", compact('data_session', 'data_question', 'total_question', 'is_last_question', 'question_number', 'answer', 'answered_question'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
8448
composer.lock_1
8448
composer.lock_1
File diff suppressed because it is too large
Load Diff
|
|
@ -84,42 +84,55 @@
|
||||||
<!-- btn show -->
|
<!-- btn show -->
|
||||||
<button type="button" class="btn btn-secondary position-absolute" onclick="showCalibrationPoints()" id="show_calibration" style="z-index: 999">Show</button>
|
<button type="button" class="btn btn-secondary position-absolute" onclick="showCalibrationPoints()" id="show_calibration" style="z-index: 999">Show</button>
|
||||||
<div class="position-absolute bg-white" style="width: 100vw; height: 100vh; z-index: -1;" id="calibration_point">
|
<div class="position-absolute bg-white" style="width: 100vw; height: 100vh; z-index: -1;" id="calibration_point">
|
||||||
<table class="w-100 h-100">
|
<!-- row 1 -->
|
||||||
<tr>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 2%; left: 2%"></div>
|
||||||
<td align="center">
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 2%; left: 19.2%"></div>
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 2%; left: 38.4%"></div>
|
||||||
</td>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 2%; left: 57.6%"></div>
|
||||||
<td align="center">
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 2%; left: 76.8%"></div>
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 2%; left: 96%"></div>
|
||||||
</td>
|
|
||||||
<td align="center">
|
<!-- row 2 -->
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 19.2%; left: 2%"></div>
|
||||||
</td>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 19.2%; left: 19.2%"></div>
|
||||||
</tr>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 19.2%; left: 38.4%"></div>
|
||||||
<tr>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 19.2%; left: 57.6%"></div>
|
||||||
<td align="center">
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 19.2%; left: 76.8%"></div>
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 19.2%; left: 96%"></div>
|
||||||
</td>
|
|
||||||
<td align="center">
|
<!-- row 3 -->
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 38.4%; left: 2%"></div>
|
||||||
</td>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 38.4%; left: 19.2%"></div>
|
||||||
<td align="center">
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 38.4%; left: 38.4%"></div>
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 38.4%; left: 57.6%"></div>
|
||||||
</td>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 38.4%; left: 76.8%"></div>
|
||||||
</tr>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 38.4%; left: 96%"></div>
|
||||||
<tr>
|
|
||||||
<td align="center">
|
<!-- row 4 -->
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 57.6%; left: 2%"></div>
|
||||||
</td>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 57.6%; left: 19.2%"></div>
|
||||||
<td align="center">
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 57.6%; left: 38.4%"></div>
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 57.6%; left: 57.6%"></div>
|
||||||
</td>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 57.6%; left: 76.8%"></div>
|
||||||
<td align="center">
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 57.6%; left: 96%"></div>
|
||||||
<div class="rounded-circle bg-primary" style="width: 3%; aspect-ratio: 1/1;"></div>
|
|
||||||
</td>
|
<!-- row 5 -->
|
||||||
</tr>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 76.8%; left: 2%"></div>
|
||||||
</table>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 76.8%; left: 19.2%"></div>
|
||||||
<div id="the_eye" class="rounded-circle bg-danger position-absolute" style="width: 1%; aspect-ratio: 1/1;"></div>
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 76.8%; left: 38.4%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 76.8%; left: 57.6%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 76.8%; left: 76.8%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 76.8%; left: 96%"></div>
|
||||||
|
|
||||||
|
<!-- row 6 -->
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 96%; left: 2%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 96%; left: 19.2%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 96%; left: 38.4%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 96%; left: 57.6%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 96%; left: 76.8%"></div>
|
||||||
|
<div class="rounded-circle bg-primary position-absolute" style="width: 0.5%; aspect-ratio: 1/1; top: 96%; left: 96%"></div>
|
||||||
|
|
||||||
|
<div id="the_eye" class="rounded-circle bg-danger position-absolute" style="width: 0.5%; aspect-ratio: 1/1;"></div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,291 +0,0 @@
|
||||||
@section('title', 'Ujian Kecemasan')
|
|
||||||
{{-- @section('body_status_overflow', 'overflow: hidden;') --}}
|
|
||||||
@section('main_style', 'min-height: 100vh;')
|
|
||||||
@extends('user.layouts.test_layout.index')
|
|
||||||
@section('content')
|
|
||||||
<div class="container-fluid p-0 d-flex flex-column" style="min-height: 100vh">
|
|
||||||
<nav class="navbar navbar-expand-lg bg-body-tertiary px-2">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<a class="navbar-brand" href="#">Smart Anxiety</a>
|
|
||||||
<div class="collapse navbar-collapse justify-content-between" id="navbarSupportedContent">
|
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul>
|
|
||||||
<div class="d-flex col-md-4">
|
|
||||||
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
|
||||||
Time Left: <span id="time_left"></span>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
|
||||||
<span id="bg_status_tobii" class="rounded bg-warning d-block mx-2" style="width: 10px; aspect-ratio: 1/1;"></span>Status Tobii
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4 d-flex justify-content-center align-items-center">
|
|
||||||
<button id="fullscreen_btn" data-status="fullscreen" class="btn btn-sm btn-outline-secondary" onclick="openFullscreen()">Fullscreen</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="d-flex flex-grow-1 container-fluid">
|
|
||||||
<div class="row flex-grow-1">
|
|
||||||
<div class="col-md-9 border-end">
|
|
||||||
<div class="row justify-content-center flex-column p-4">
|
|
||||||
<div class="col-md-12 border-bottom fs-4 fw-bold p-2">Soal</div>
|
|
||||||
<div class="col-md-12 p-2" id="text_question" style="text-align: justify"></div>
|
|
||||||
<div class="col-md-12" id="answer_field">
|
|
||||||
<div class="fs-4 fw-bold p-2">Jawaban:</div>
|
|
||||||
{{-- <div class="form-check m-2">
|
|
||||||
<input class="form-check-input" type="radio" name="jawaban_final" id="jawaban_{{ $item['key'] }}">
|
|
||||||
<label class="form-check-label" for="jawaban_{{ $item['key'] }}">{{ $item['value'] }}</label>
|
|
||||||
</div> --}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="row p-3">
|
|
||||||
<div class="col-md-12 border-bottom fs-4 fw-bold p-2 mb-3" id="navigation_field">Navigasi Soal</div>
|
|
||||||
{{-- @foreach ($answered_question as $question)
|
|
||||||
<div onclick="changeQuestion({{ $question['nomor_soal'] }})" id="nomor_{{ $question['nomor_soal'] }}" class="col-md-1 btn d-flex justify-content-center align-items-center {{ $question['answered'] ? 'bg-secondary-subtle' : 'bg-light-subtle' }} border rounded p-0 m-1" style="aspect-ratio: 1/1.5;">{{ $question['nomor_soal'] }}</div>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
<div class="col-md-12 p-0 mt-3">
|
|
||||||
@if ($question_number > 1)
|
|
||||||
<div class="btn btn-secondary" onclick="changeQuestion({{ $question_number - 1 }})">Previous</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($is_last_question)
|
|
||||||
<div class="btn btn-success" onclick="finishExam()">Finish</div>
|
|
||||||
@else
|
|
||||||
<div class="btn btn-primary" onclick="changeQuestion({{ $question_number + 1 }})">Next</div>
|
|
||||||
@endif
|
|
||||||
</div> --}}
|
|
||||||
</div>
|
|
||||||
<div class="row p-3">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Instruksi</h5>
|
|
||||||
<p class="card-text">Silahkan baca soal dengan teliti dan pilih jawaban yang paling tepat.</p>
|
|
||||||
<div class="card-text d-flex align-items-center">
|
|
||||||
<span class="col-md-1 bg-light-subtle border rounded p-0 m-1" style="aspect-ratio: 1/1.5;"></span>
|
|
||||||
<span>adalah tanda bahwa jawaban BELUM diisi.</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-text d-flex align-items-center">
|
|
||||||
<span class="col-md-1 bg-secondary-subtle border rounded p-0 m-1" style="aspect-ratio: 1/1.5;"></span>
|
|
||||||
<span>adalah tanda bahwa jawaban SUDAH diisi.</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-text d-flex align-items-center">
|
|
||||||
<span class="col-md-1 bg-info border rounded p-0 m-1 text-white" style="aspect-ratio: 1/1.5;"></span>
|
|
||||||
<span>adalah tanda bahwa anda sedang membaca/menjawab soal ini.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('script')
|
|
||||||
<script>
|
|
||||||
const ws = new WebSocket('{{ env("WEBSOCKET_URL") }}');
|
|
||||||
const SESSION_ID = '{{ $data_session->id_test_sessions }}';
|
|
||||||
const TOKEN_SESSION = '{{ $data_session->token_session }}';
|
|
||||||
let UNIX_END_TIME = null;
|
|
||||||
let QUESTION_INDEX = 1;
|
|
||||||
|
|
||||||
function fetchQuestion(question_index) {
|
|
||||||
let xhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhttp.onreadystatechange = function() {
|
|
||||||
if(this.readyState == 4 && this.status == 200) {
|
|
||||||
let response = JSON.parse(this.responseText);
|
|
||||||
if(response.status) {
|
|
||||||
$('#text_question').html(response.data.pertanyaan);
|
|
||||||
getCurrentAnswer(response.data.id_soal);
|
|
||||||
} else {
|
|
||||||
Swal.fire({
|
|
||||||
title: 'Error',
|
|
||||||
icon: 'error',
|
|
||||||
text: 'Terjadi kesalahan saat mengambil soal. Silahkan refresh halaman ini.',
|
|
||||||
confirmButtonText: 'OK'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xhttp.open("GET", "{{ route('ujian.fetchQuestion') }}?session_id=" + SESSION_ID + "&question_index=" + question_index, false);
|
|
||||||
xhttp.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentAnswer(id_question) {
|
|
||||||
let xhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhttp.onreadystatechange = function() {
|
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
|
||||||
let response = JSON.parse(this.responseText);
|
|
||||||
if (response.status) {
|
|
||||||
let choices_html = '';
|
|
||||||
$('#answer_field').html('<div class="fs-4 fw-bold p-2">Jawaban:</div>');
|
|
||||||
response.choices.forEach((choice) => {
|
|
||||||
choices_html += `
|
|
||||||
<div class="form-check m-2">
|
|
||||||
<input class="form-check-input" type="radio" name="jawaban_final" id="jawaban_${choice.key}">
|
|
||||||
<label class="form-check-label" for="jawaban_${choice.key}">${choice.value}</label>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
});
|
|
||||||
$('#answer_field').append(choices_html);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhttp.open("GET", "{{ route('ujian.getCurrentAnswer') }}?session_id=" + SESSION_ID + "&id_question=" + id_question, false);
|
|
||||||
xhttp.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTimeLeft() {
|
|
||||||
let xhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhttp.onreadystatechange = function() {
|
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
|
||||||
let response = JSON.parse(this.responseText);
|
|
||||||
console.log('Time left:', response.time_left);
|
|
||||||
UNIX_END_TIME = response.time_left;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhttp.open("GET", "{{ route('ujian.getTimeLeft') }}?session_id=" + SESSION_ID, false);
|
|
||||||
xhttp.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTimeLeft() {
|
|
||||||
let time_left = UNIX_END_TIME - Math.floor(Date.now() / 1000);
|
|
||||||
if(time_left < 0) {
|
|
||||||
time_left = 0;
|
|
||||||
finishExam();
|
|
||||||
}
|
|
||||||
let minutes = Math.floor(time_left / 60);
|
|
||||||
let seconds = time_left % 60;
|
|
||||||
document.getElementById('time_left').innerText = ' ' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startTobii() {
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: "command",
|
|
||||||
action: "start",
|
|
||||||
session_id: SESSION_ID
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopTobii() {
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: "command",
|
|
||||||
action: "stop",
|
|
||||||
session_id: SESSION_ID
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function openFullscreen() {
|
|
||||||
const status = $('#fullscreen_btn').attr('data-status');
|
|
||||||
const elem = document.documentElement;
|
|
||||||
if (status === 'fullscreen') {
|
|
||||||
if (elem.requestFullscreen) {
|
|
||||||
elem.requestFullscreen();
|
|
||||||
} else if (elem.webkitRequestFullscreen) {
|
|
||||||
elem.webkitRequestFullscreen(); // Safari
|
|
||||||
} else if (elem.msRequestFullscreen) {
|
|
||||||
elem.msRequestFullscreen(); // IE
|
|
||||||
}
|
|
||||||
$('#fullscreen_btn').attr('data-status', 'exit-fullscreen');
|
|
||||||
$('#fullscreen_btn').text('Exit Fullscreen');
|
|
||||||
startTobii();
|
|
||||||
} else if (status === 'exit-fullscreen') {
|
|
||||||
if (document.exitFullscreen) {
|
|
||||||
document.exitFullscreen();
|
|
||||||
} else if (document.webkitExitFullscreen) {
|
|
||||||
document.webkitExitFullscreen(); // Safari
|
|
||||||
} else if (document.msExitFullscreen) {
|
|
||||||
document.msExitFullscreen(); // IE
|
|
||||||
}
|
|
||||||
$('#fullscreen_btn').attr('data-status', 'fullscreen');
|
|
||||||
$('#fullscreen_btn').text('Enter Fullscreen');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkFullscreen() {
|
|
||||||
if (!document.fullscreenElement) {
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: "command",
|
|
||||||
action: "stop",
|
|
||||||
session_id: SESSION_ID
|
|
||||||
}));
|
|
||||||
|
|
||||||
Swal.fire({
|
|
||||||
title: 'Alert',
|
|
||||||
icon: 'warning',
|
|
||||||
text: 'Anda keluar dari mode fullscreen, harap masuk ke mode fullscreen untuk melanjutkan ujian.',
|
|
||||||
confirmButtonText: 'Ya',
|
|
||||||
showCancelButton: false,
|
|
||||||
showCloseButton: false,
|
|
||||||
allowOutsideClick: false,
|
|
||||||
allowEscapeKey: false,
|
|
||||||
backdrop: `rgba(0, 0, 0, 0.4)`
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
openFullscreen();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
ws.onopen = () => {
|
|
||||||
console.log("Connected to WebSocket");
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: "register",
|
|
||||||
session_id: SESSION_ID,
|
|
||||||
token_session: TOKEN_SESSION,
|
|
||||||
role: "web"
|
|
||||||
}));
|
|
||||||
|
|
||||||
document.addEventListener('fullscreenchange', checkFullscreen);
|
|
||||||
// checkFullscreen();
|
|
||||||
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: "update_status",
|
|
||||||
status_sessions: true,
|
|
||||||
session_id: SESSION_ID
|
|
||||||
}));
|
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
|
||||||
const data = JSON.parse(event.data);
|
|
||||||
|
|
||||||
if(data.type === 'reset_start_tobii') {
|
|
||||||
startTobii();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data.type === 'status_tobii_device') {
|
|
||||||
if(data.status) {
|
|
||||||
console.log('Tobii device is connected');
|
|
||||||
// document.getElementById('status_tobii_device').innerText = 'Connected';
|
|
||||||
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
|
|
||||||
document.getElementById('bg_status_tobii').classList.remove('bg-danger');
|
|
||||||
document.getElementById('bg_status_tobii').classList.add('bg-success');
|
|
||||||
} else {
|
|
||||||
console.log('Tobii device is not connected');
|
|
||||||
// document.getElementById('status_tobii_device').innerText = 'Not Connected';
|
|
||||||
document.getElementById('bg_status_tobii').classList.remove('bg-success');
|
|
||||||
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
|
|
||||||
document.getElementById('bg_status_tobii').classList.add('bg-danger');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
startTobii();
|
|
||||||
// getCurrentAnswer();
|
|
||||||
getTimeLeft();
|
|
||||||
setInterval(updateTimeLeft, 1000);
|
|
||||||
fetchQuestion(QUESTION_INDEX);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endsection
|
|
||||||
|
|
@ -41,7 +41,6 @@
|
||||||
Route::resource('ujian', HalamanUjianController::class);
|
Route::resource('ujian', HalamanUjianController::class);
|
||||||
Route::get('ujian/get/current-answer', [HalamanUjianController::class, 'getCurrentAnswer'])->name('ujian.getCurrentAnswer');
|
Route::get('ujian/get/current-answer', [HalamanUjianController::class, 'getCurrentAnswer'])->name('ujian.getCurrentAnswer');
|
||||||
Route::get('ujian/get/time-left', [HalamanUjianController::class, 'getTimeLeft'])->name('ujian.getTimeLeft');
|
Route::get('ujian/get/time-left', [HalamanUjianController::class, 'getTimeLeft'])->name('ujian.getTimeLeft');
|
||||||
Route::get('ujian/fetch/question', [HalamanUjianController::class, 'fetchQuestion'])->name('ujian.fetchQuestion');
|
|
||||||
Route::resource('hasil-tes', FinishUjianController::class)->only(['index', 'show']);
|
Route::resource('hasil-tes', FinishUjianController::class)->only(['index', 'show']);
|
||||||
Route::get('hasil-tes/get/all-answer', [FinishUjianController::class, 'getAllAnswer'])->name('hasil-tes.getAllAnswer');
|
Route::get('hasil-tes/get/all-answer', [FinishUjianController::class, 'getAllAnswer'])->name('hasil-tes.getAllAnswer');
|
||||||
Route::middleware(['auth', 'role.auth'])->group(function() {
|
Route::middleware(['auth', 'role.auth'])->group(function() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue