WIP: halaman ujian (mayan progress)
This commit is contained in:
parent
fdda679141
commit
f18c470f14
|
|
@ -3,11 +3,72 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\DataSoalModel;
|
||||
use App\Models\DetailTestModel;
|
||||
use App\Models\TestSessionsModel;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HalamanUjianController extends Controller
|
||||
{
|
||||
|
||||
public function getCurrentAnswer(Request $request) {
|
||||
$data_answer = DetailTestModel::where('id_soal', $request->id_question)
|
||||
->where('id_test_sessions', $request->session_id)
|
||||
->first();
|
||||
|
||||
if($data_answer != null) {
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'jawaban' => $data_answer->jawaban
|
||||
]);
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Data jawaban tidak ditemukan.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getTimeLeft(Request $request) {
|
||||
$data_session = TestSessionsModel::where('id_test_sessions', $request->session_id)->first();
|
||||
if($data_session != null) {
|
||||
if($data_session->status_session != '1') {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Data sesi tes belum dimulai atau telah usai. Silahkan cek status dengan kode untuk informasi lebih lanjut.'
|
||||
]);
|
||||
} else if($data_session->status_session == '1') {
|
||||
if($data_session->is_active == '1') {
|
||||
$time_left = $data_session->unix_end_time - time();
|
||||
if($time_left <= 0) {
|
||||
$data_session->update([
|
||||
'status_session' => '2',
|
||||
'is_active' => '0'
|
||||
]);
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Waktu sesi tes telah habis. Silahkan cek status dengan kode untuk informasi lebih lanjut.'
|
||||
]);
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'time_left' => $data_session->unix_end_time
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Sesi tes belum aktif. Silahkan mulai tes terlebih dahulu.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Data sesi tes tidak ditemukan. Silakan mulai tes terlebih dahulu.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
|
|
@ -27,7 +88,23 @@ public function index(Request $request)
|
|||
if($data_session != null) {
|
||||
if($data_session->status_session != '1') {
|
||||
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes belum dimulai atau telah usai. Silahkan cek status dengan kode untuk informasi lebih lanjut.');
|
||||
}
|
||||
} else if($data_session->status_session == '1') {
|
||||
if($data_session->is_active == '0') {
|
||||
$data_session->update([
|
||||
'is_active' => '1',
|
||||
'unix_start_time' => time(),
|
||||
'unix_end_time' => time() + (20 * 60)
|
||||
]);
|
||||
} else if($data_session->is_active == '1') {
|
||||
if(time() > $data_session->unix_end_time) {
|
||||
$data_session->update([
|
||||
'status_session' => '2',
|
||||
'is_active' => '0'
|
||||
]);
|
||||
return redirect()->route('cek-status.index')->with('error', 'Waktu sesi tes telah habis. Silahkan cek status dengan kode untuk informasi lebih lanjut.');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes tidak ditemukan. Silakan mulai tes terlebih dahulu.');
|
||||
}
|
||||
|
|
@ -43,6 +120,30 @@ public function index(Request $request)
|
|||
}
|
||||
|
||||
$data_question = DataSoalModel::all();
|
||||
$answered_question = [];
|
||||
$index_question = 1;
|
||||
foreach($data_question as $detail) {
|
||||
$detail_answer = DetailTestModel::where('id_soal', $detail->id_soal)
|
||||
->where('id_test_sessions', $id_session)
|
||||
->first();
|
||||
if($detail_answer != null) {
|
||||
$answered_question[] = [
|
||||
'id_soal' => $detail->id_soal,
|
||||
'nomor_soal' => $index_question,
|
||||
'answered' => true,
|
||||
'jawaban' => $detail_answer->jawaban
|
||||
];
|
||||
} else {
|
||||
$answered_question[] = [
|
||||
'id_soal' => $detail->id_soal,
|
||||
'nomor_soal' => $index_question,
|
||||
'answered' => false,
|
||||
'jawaban' => null
|
||||
];
|
||||
}
|
||||
$index_question++;
|
||||
}
|
||||
|
||||
$total_question = null;
|
||||
$is_last_question = false;
|
||||
if($question_number <= 0 || $question_number > count($data_question)) {
|
||||
|
|
@ -54,7 +155,41 @@ public function index(Request $request)
|
|||
$total_question = count($data_question);
|
||||
$data_question = $data_question[$question_number - 1];
|
||||
|
||||
return view("user.pages.ujian.index", compact('data_session', 'data_question', 'total_question', 'is_last_question', 'question_number'));
|
||||
$answer = [];
|
||||
if($data_question->jawaban_a != null) {
|
||||
$answer[] = [
|
||||
'key' => 'a',
|
||||
'value' => $data_question->jawaban_a
|
||||
];
|
||||
}
|
||||
if($data_question->jawaban_b != null) {
|
||||
$answer[] = [
|
||||
'key' => 'b',
|
||||
'value' => $data_question->jawaban_b
|
||||
];
|
||||
}
|
||||
if($data_question->jawaban_c != null) {
|
||||
$answer[] = [
|
||||
'key' => 'c',
|
||||
'value' => $data_question->jawaban_c
|
||||
];
|
||||
}
|
||||
if($data_question->jawaban_d != null) {
|
||||
$answer[] = [
|
||||
'key' => 'd',
|
||||
'value' => $data_question->jawaban_d
|
||||
];
|
||||
}
|
||||
if($data_question->jawaban_e != null) {
|
||||
$answer[] = [
|
||||
'key' => 'e',
|
||||
'value' => $data_question->jawaban_e
|
||||
];
|
||||
}
|
||||
|
||||
// dd($answer);
|
||||
|
||||
return view("user.pages.ujian.index", compact('data_session', 'data_question', 'total_question', 'is_last_question', 'question_number', 'answer', 'answered_question'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,7 +205,30 @@ public function create()
|
|||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
$data_session = TestSessionsModel::where('id_test_sessions', $request->session_id)->first();
|
||||
if($data_session != null) {
|
||||
if($data_session->status_session != '1') {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Data sesi tes belum dimulai atau telah usai. Silahkan cek status dengan kode untuk informasi lebih lanjut.'
|
||||
]);
|
||||
}
|
||||
DetailTestModel::updateOrCreate(
|
||||
[
|
||||
'id_soal' => $request->id_question,
|
||||
'id_test_sessions' => $request->session_id
|
||||
],
|
||||
[
|
||||
'jawaban' => $request->jawaban_final
|
||||
]
|
||||
);
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Data sesi tes tidak ditemukan. Silakan mulai tes terlebih dahulu.'
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DetailTestModel extends Model
|
||||
{
|
||||
protected $table = 'detail_test';
|
||||
|
||||
protected $primaryKey = 'id_detail_test';
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $fillable = [
|
||||
'id_detail_test',
|
||||
'id_soal',
|
||||
'id_test_sessions',
|
||||
'jawaban'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'id_detail_test' => 'string',
|
||||
];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
static::creating(function ($model) {
|
||||
if (empty($model->id_detail_test)) {
|
||||
$model->id_detail_test = Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,9 @@ class TestSessionsModel extends Model
|
|||
'status_session',
|
||||
'token_session',
|
||||
'id_booking',
|
||||
'unix_start_time',
|
||||
'is_active',
|
||||
'unix_end_time',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('detail_test', function (Blueprint $table) {
|
||||
$table->dropForeign(['id_test']);
|
||||
$table->dropColumn('id_test');
|
||||
$table->char('id_test_sessions', 36)->after('id_soal');
|
||||
$table->foreign('id_test_sessions')->references('id_test_sessions')->on('test_sessions')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('detail_test', function (Blueprint $table) {
|
||||
$table->dropForeign(['id_test_sessions']);
|
||||
$table->dropColumn('id_test_sessions');
|
||||
$table->unsignedBigInteger('id_test')->after('id_soal');
|
||||
$table->foreign('id_test')->references('id_test')->on('test')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('detail_test', function (Blueprint $table) {
|
||||
$table->foreign('id_soal')->references('id_soal')->on('soal')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('detail_test', function (Blueprint $table) {
|
||||
$table->dropForeign(['id_soal']);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('test_sessions', function (Blueprint $table) {
|
||||
$table->char('unix_start_time', 20)->default(0)->after('token_session');
|
||||
$table->char('unix_end_time', 20)->default(0)->after('is_active');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('test_sessions', function (Blueprint $table) {
|
||||
$table->dropColumn('unix_start_time');
|
||||
$table->dropColumn('unix_end_time');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -7,9 +7,16 @@
|
|||
<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" id="navbarSupportedContent">
|
||||
<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 fw-bold">Time Left: <span id="time_left"></span></div>
|
||||
<div class="d-flex col-md-2">
|
||||
<div class="col-md-6 d-flex justify-content-center align-items-center">
|
||||
Time Left: <span id="time_left"></span>
|
||||
</div>
|
||||
<div class="col-md-6 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>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
@ -19,38 +26,25 @@
|
|||
<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 d-none" id="id_question" value="{{ $data_question->id_soal }}"></div>
|
||||
<div class="col-md-12 p-2" style="text-align: justify">{{ $data_question->pertanyaan }}</div>
|
||||
<div class="col-md-12">
|
||||
<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_a">
|
||||
<label class="form-check-label" for="jawaban_a">{{ $data_question->jawaban_a }}</label>
|
||||
</div>
|
||||
<div class="form-check m-2">
|
||||
<input class="form-check-input" type="radio" name="jawaban_final" id="jawaban_b">
|
||||
<label class="form-check-label" for="jawaban_b">{{ $data_question->jawaban_b }}</label>
|
||||
</div>
|
||||
<div class="form-check m-2">
|
||||
<input class="form-check-input" type="radio" name="jawaban_final" id="jawaban_c">
|
||||
<label class="form-check-label" for="jawaban_c">{{ $data_question->jawaban_c }}</label>
|
||||
</div>
|
||||
<div class="form-check m-2">
|
||||
<input class="form-check-input" type="radio" name="jawaban_final" id="jawaban_d">
|
||||
<label class="form-check-label" for="jawaban_d">{{ $data_question->jawaban_d }}</label>
|
||||
</div>
|
||||
<div class="form-check m-2">
|
||||
<input class="form-check-input" type="radio" name="jawaban_final" id="jawaban_e">
|
||||
<label class="form-check-label" for="jawaban_e">{{ $data_question->jawaban_e }}</label>
|
||||
</div>
|
||||
@foreach ($answer as $item)
|
||||
<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>
|
||||
@endforeach
|
||||
</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">Navigasi Soal</div>
|
||||
@for ($i = 0; $i < $total_question; $i++)
|
||||
<div onclick="changeQuestion({{ $i + 1 }})" class="col-md-1 btn d-flex justify-content-center align-items-center bg-light-subtle border rounded p-0 m-1" style="aspect-ratio: 1/1.5;">{{ $i + 1 }}</div>
|
||||
@endfor
|
||||
@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)
|
||||
|
|
@ -64,6 +58,28 @@
|
|||
@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>
|
||||
|
|
@ -75,10 +91,37 @@
|
|||
const ws = new WebSocket('{{ env("WEBSOCKET_URL") }}');
|
||||
let SESSION_ID = '{{ $data_session->id_test_sessions }}';
|
||||
let TOKEN_SESSION = '{{ $data_session->token_session }}';
|
||||
let UNIX_END_TIME = null;
|
||||
|
||||
function changeQuestion(num) {
|
||||
let url_temp = window.location.href;
|
||||
let current_num = new URLSearchParams(window.location.search).get('question');
|
||||
let xhttp = new XMLHttpRequest();
|
||||
let the_answer = null;
|
||||
let token = document.getElementById('_token').getAttribute('value');
|
||||
let formData = new FormData();
|
||||
|
||||
if(current_num == num) {
|
||||
console.log('same question');
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementsByName('jawaban_final').forEach(element => {
|
||||
if (element.checked) {
|
||||
the_answer = {
|
||||
key: element.id.split('_')[1],
|
||||
};
|
||||
}
|
||||
});
|
||||
if(the_answer) {
|
||||
formData.append('jawaban_final', the_answer.key);
|
||||
formData.append('_token', token);
|
||||
formData.append('question', num);
|
||||
formData.append('id_question', $('#id_question').attr('value'));
|
||||
formData.append('session_id', SESSION_ID);
|
||||
xhttp.open("POST", "{{ route('ujian.store') }}", false);
|
||||
xhttp.send(formData);
|
||||
}
|
||||
stopTobii();
|
||||
if(!url_temp.includes('question')) {
|
||||
window.location.href = url_temp + '&question=' + num;
|
||||
|
|
@ -87,6 +130,55 @@ function changeQuestion(num) {
|
|||
}
|
||||
}
|
||||
|
||||
function getCurrentAnswer() {
|
||||
let id_question = $('#id_question').attr('value');
|
||||
let xhttp = new XMLHttpRequest();
|
||||
let current_num = new URLSearchParams(window.location.search).get('question');
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
let response = JSON.parse(this.responseText);
|
||||
document.getElementById('nomor_' + current_num).classList.remove('bg-light-subtle');
|
||||
document.getElementById('nomor_' + current_num).classList.remove('bg-secondary-subtle');
|
||||
document.getElementById('nomor_' + current_num).classList.add('bg-info');
|
||||
document.getElementById('nomor_' + current_num).classList.add('text-white');
|
||||
if(response.status == 'success') {
|
||||
document.getElementsByName('jawaban_final').forEach(element => {
|
||||
if (element.id.split('_')[1] == response.jawaban) {
|
||||
element.checked = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", "{{ route('ujian.getCurrentAnswer') }}?id_question=" + id_question + "&session_id=" + SESSION_ID, 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);
|
||||
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 finishExam() {
|
||||
ws.send(JSON.stringify({
|
||||
type: "command",
|
||||
|
|
@ -139,7 +231,34 @@ function stopTobii() {
|
|||
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);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
Route::resource('tobii-receiver', TobiiReceiverController::class)->only(['store', 'show']);
|
||||
Route::get('tobii-receiver/fetch/data/{id_test_sessions}', [TobiiReceiverController::class, 'fetchDataTobii'])->name('tobii-receiver.fetchData');
|
||||
Route::resource('ujian', HalamanUjianController::class);
|
||||
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::middleware(['auth', 'role.auth'])->group(function() {
|
||||
Route::resource('dashboard', DashboardController::class);
|
||||
Route::resource('users', UsersController::class);
|
||||
|
|
|
|||
Loading…
Reference in New Issue