Compare commits
16 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
8e032dd1fb | |
|
|
1d8ade06f1 | |
|
|
043e2a81c0 | |
|
|
a475b0a740 | |
|
|
7f6cf7dcd6 | |
|
|
d0bcdd2949 | |
|
|
22f532cdd6 | |
|
|
1357d96c78 | |
|
|
aebcdbb844 | |
|
|
48c822c558 | |
|
|
e2954898e9 | |
|
|
cc783674b6 | |
|
|
f11c3a879d | |
|
|
d07e24e39b | |
|
|
6c41ac4cf3 | |
|
|
01258eb92d |
|
|
@ -28,7 +28,7 @@ public function create(Request $request): View
|
||||||
*
|
*
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
*/
|
*/
|
||||||
public function store(Request $request): RedirectResponse
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'token' => ['required'],
|
'token' => ['required'],
|
||||||
|
|
@ -51,12 +51,17 @@ function (User $user) use ($request) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'status' => $status == Password::PASSWORD_RESET,
|
||||||
|
'msg' => $status == Password::PASSWORD_RESET ? 'Password reset successful' : 'Password reset failed'
|
||||||
|
]);
|
||||||
|
|
||||||
// If the password was successfully reset, we will redirect the user back to
|
// If the password was successfully reset, we will redirect the user back to
|
||||||
// the application's home authenticated view. If there is an error we can
|
// the application's home authenticated view. If there is an error we can
|
||||||
// redirect them back to where they came from with their error message.
|
// redirect them back to where they came from with their error message.
|
||||||
return $status == Password::PASSWORD_RESET
|
// return $status == Password::PASSWORD_RESET
|
||||||
? redirect()->route('login')->with('status', __($status))
|
// ? redirect()->route('login')->with('status', __($status))
|
||||||
: back()->withInput($request->only('email'))
|
// : back()->withInput($request->only('email'))
|
||||||
->withErrors(['email' => __($status)]);
|
// ->withErrors(['email' => __($status)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public function create(): View
|
||||||
*
|
*
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
*/
|
*/
|
||||||
public function store(Request $request): RedirectResponse
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'email' => ['required', 'email'],
|
'email' => ['required', 'email'],
|
||||||
|
|
@ -36,9 +36,14 @@ public function store(Request $request): RedirectResponse
|
||||||
$request->only('email')
|
$request->only('email')
|
||||||
);
|
);
|
||||||
|
|
||||||
return $status == Password::RESET_LINK_SENT
|
return response()->json([
|
||||||
? back()->with('status', __($status))
|
'status' => $status == Password::RESET_LINK_SENT,
|
||||||
: back()->withInput($request->only('email'))
|
'msg' => __($status)
|
||||||
->withErrors(['email' => __($status)]);
|
]);
|
||||||
|
|
||||||
|
// return $status == Password::RESET_LINK_SENT
|
||||||
|
// ? back()->with('status', __($status))
|
||||||
|
// : back()->withInput($request->only('email'))
|
||||||
|
// ->withErrors(['email' => __($status)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use App\Mail\SendUniqueCode;
|
use App\Mail\SendUniqueCode;
|
||||||
use App\Models\BookingModel;
|
use App\Models\BookingModel;
|
||||||
|
use App\Models\TestSessionsModel;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Generator;
|
use Generator;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
@ -16,6 +17,28 @@ class BookingController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getchData() {
|
public function getchData() {
|
||||||
$data = BookingModel::get();
|
$data = BookingModel::get();
|
||||||
|
$data_ = $data->toArray();
|
||||||
|
foreach($data_ as $key => $value) {
|
||||||
|
if(time() > $value['unix_expired_time'] && $value['status_tes'] != '2') {
|
||||||
|
$data_session = TestSessionsModel::where('id_booking', $value['id_booking'])->first();
|
||||||
|
$data_booking = BookingModel::where('id_booking', $value['id_booking'])->first();
|
||||||
|
if($data_session != null) {
|
||||||
|
$data_session->update([
|
||||||
|
'status_session' => '2',
|
||||||
|
'is_active' => '0'
|
||||||
|
]);
|
||||||
|
$data_booking->update([
|
||||||
|
'status_tes' => '2'
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$data_booking->update([
|
||||||
|
'status_tes' => '0'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = BookingModel::orderBy('updated_at', 'desc')->get();
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => true,
|
'status' => true,
|
||||||
|
|
@ -143,8 +166,10 @@ public function update(Request $request, string $id)
|
||||||
'status_tes' => ['required']
|
'status_tes' => ['required']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
BookingModel::where('id_booking', $id)->update([
|
$data = BookingModel::where('id_booking', $id)->first();
|
||||||
'status_tes' => $request->status_tes
|
|
||||||
|
$data->update([
|
||||||
|
'status_tes' => str($request->status_tes)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,90 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\BookingModel;
|
||||||
|
use App\Models\LogKecemasanModel;
|
||||||
|
use App\Models\TestSessionsModel;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class DashboardController extends Controller
|
class DashboardController extends Controller
|
||||||
{
|
{
|
||||||
|
public function getDataForDashboardTable()
|
||||||
|
{
|
||||||
|
$data_booking = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m-d') . '%')->get();
|
||||||
|
$result = [];
|
||||||
|
foreach ($data_booking as $booking) {
|
||||||
|
$status_session = '0';
|
||||||
|
$data_sessions = TestSessionsModel::where('id_booking', $booking->id_booking)->first();
|
||||||
|
if($data_sessions != null) {
|
||||||
|
$status_session = $data_sessions->status_session;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[] = [
|
||||||
|
'nama_lengkap' => $booking->nama_lengkap,
|
||||||
|
'email' => $booking->email,
|
||||||
|
'no_telp' => $booking->no_telp,
|
||||||
|
'tanggal_booking' => $booking->created_at->format('Y-m-d'),
|
||||||
|
'status_session' => $status_session,
|
||||||
|
'status_tes' => $booking->status_tes,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return response()->json([
|
||||||
|
'status' => true,
|
||||||
|
'data' => $result
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
public function getDataDashboard()
|
||||||
|
{
|
||||||
|
$data_booking_today = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m-d') . '%')->count();
|
||||||
|
$data_booking_yesterday = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m-d', strtotime('-1 day')) . '%')->count();
|
||||||
|
$data_booking_month = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m') . '%')->count();
|
||||||
|
$booking_diff = $data_booking_month - $data_booking_today;
|
||||||
|
$booking_percent = $data_booking_month > 0 ? ($booking_diff / $data_booking_month) * 100 : 0;
|
||||||
|
|
||||||
|
$data_tes_today = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m-d') . '%')->where('status_tes', '2')->count();
|
||||||
|
$data_tes_yesterday = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m-d', strtotime('-1 day')) . '%')->where('status_tes', '2')->count();
|
||||||
|
$data_tes_month = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m') . '%')->where('status_tes', '2')->count();
|
||||||
|
$tes_diff = $data_tes_month - $data_tes_today;
|
||||||
|
$tes_percent = $data_tes_month > 0 ? ($tes_diff / $data_tes_month) * 100 : 0;
|
||||||
|
|
||||||
|
$data_tes_berlangsung_today = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m-d') . '%')->where('status_tes', '1')->count();
|
||||||
|
$data_tes_berlangsung_yesterday = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m-d', strtotime('-1 day')) . '%')->where('status_tes', '1')->count();
|
||||||
|
$data_tes_berlangsung_month = BookingModel::where('created_at', 'LIKE', '%' . date('Y-m') . '%')->where('status_tes', '1')->count();
|
||||||
|
$tes_berlangsung_diff = $data_tes_berlangsung_month - $data_tes_berlangsung_today;
|
||||||
|
$tes_berlangsung_percent = $data_tes_berlangsung_month > 0 ? ($tes_berlangsung_diff / $data_tes_berlangsung_month) * 100 : 0;
|
||||||
|
|
||||||
|
$data_rata_rata_kecemasan_today = LogKecemasanModel::where('created_at', 'LIKE', '%' . date('Y-m-d') . '%')->avg('skor_kecemasan');
|
||||||
|
$data_rata_rata_kecemasan_yesterday = LogKecemasanModel::where('created_at', 'LIKE', '%' . date('Y-m-d', strtotime('-1 day')) . '%')->avg('skor_kecemasan');
|
||||||
|
$data_rata_rata_kecemasan_month = LogKecemasanModel::where('created_at', 'LIKE', '%' . date('Y-m') . '%')->avg('skor_kecemasan');
|
||||||
|
$rata_rata_kecemasan_diff = $data_rata_rata_kecemasan_month - $data_rata_rata_kecemasan_today;
|
||||||
|
$rata_rata_kecemasan_percent = $data_rata_rata_kecemasan_month > 0 ? ($rata_rata_kecemasan_diff / $data_rata_rata_kecemasan_month) * 100 : 0;
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'total_booking' => $data_booking_today,
|
||||||
|
'booking_percent' => number_format($booking_percent, 1),
|
||||||
|
'booking_diff' => $booking_diff,
|
||||||
|
'booking_trend' => $booking_diff >= 0 ? 'bertambah' : 'berkurang',
|
||||||
|
'from_month_booking_count' => $data_booking_month,
|
||||||
|
|
||||||
|
'total_tes' => $data_tes_today,
|
||||||
|
'tes_percent' => number_format($tes_percent, 1),
|
||||||
|
'tes_diff' => $tes_diff,
|
||||||
|
'tes_trend' => $tes_diff >= 0 ? 'bertambah' : 'berkurang',
|
||||||
|
'from_month_tes_count' => $data_tes_month,
|
||||||
|
|
||||||
|
'total_tes_berlangsung' => $data_tes_berlangsung_today,
|
||||||
|
'tes_berlangsung_percent' => number_format($tes_berlangsung_percent, 1),
|
||||||
|
'tes_berlangsung_diff' => $tes_berlangsung_diff,
|
||||||
|
'tes_berlangsung_trend' => $tes_berlangsung_diff >= 0 ? 'bertambah' : 'berkurang',
|
||||||
|
'from_month_tes_berlangsung_count' => $data_tes_berlangsung_month,
|
||||||
|
|
||||||
|
'rata_rata_kecemasan' => number_format($data_rata_rata_kecemasan_today, 1),
|
||||||
|
'rata_rata_kecemasan_percent' => number_format($rata_rata_kecemasan_percent, 1),
|
||||||
|
'rata_rata_kecemasan_diff' => number_format($rata_rata_kecemasan_diff, 1),
|
||||||
|
'rata_rata_kecemasan_trend' => $rata_rata_kecemasan_diff >= 0 ? 'bertambah' : 'berkurang',
|
||||||
|
'from_month_rata_rata_kecemasan' => number_format($data_rata_rata_kecemasan_month, 1),
|
||||||
|
]);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public function store(Request $request)
|
||||||
'jawaban_c' => $request->jawaban_c,
|
'jawaban_c' => $request->jawaban_c,
|
||||||
'jawaban_d' => $request->jawaban_d,
|
'jawaban_d' => $request->jawaban_d,
|
||||||
'jawaban_e' => $request->jawaban_e,
|
'jawaban_e' => $request->jawaban_e,
|
||||||
'jawaban_benar' => $request->jawaban_benar,
|
'is_reverse' => $request->is_reverse,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|
@ -91,7 +91,7 @@ public function update(Request $request, string $id)
|
||||||
'jawaban_c' => $request->jawaban_c,
|
'jawaban_c' => $request->jawaban_c,
|
||||||
'jawaban_d' => $request->jawaban_d,
|
'jawaban_d' => $request->jawaban_d,
|
||||||
'jawaban_e' => $request->jawaban_e,
|
'jawaban_e' => $request->jawaban_e,
|
||||||
'jawaban_benar' => $request->jawaban_benar,
|
'is_reverse' => $request->is_reverse,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,50 @@
|
||||||
|
|
||||||
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\LogKecemasanModel;
|
||||||
use App\Models\TestSessionsModel;
|
use App\Models\TestSessionsModel;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class FinishUjianController extends Controller
|
class FinishUjianController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public function getNotAnswered(Request $request) {
|
||||||
|
$data_session = TestSessionsModel::where('id_test_sessions', $request->id_test_sessions)->first();
|
||||||
|
if($data_session != null) {
|
||||||
|
if($data_session->status_session == '0') {
|
||||||
|
return response()->json([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Data sesi tes dinonaktifkan. Silahkan cek status dengan kode untuk informasi lebih lanjut.'
|
||||||
|
]);
|
||||||
|
} else if($data_session->status_session == '2') {
|
||||||
|
$soal = DataSoalModel::all();
|
||||||
|
$data_ujian = [];
|
||||||
|
foreach($soal as $detail) {
|
||||||
|
$data_soal = DetailTestModel::where('id_soal', $detail->id_soal)->where('id_test_sessions', $request->id_test_sessions)->first();
|
||||||
|
if($data_soal == null) {
|
||||||
|
$data_ujian[] = [
|
||||||
|
'id_soal' => $detail->id_soal,
|
||||||
|
'soal' => $detail->pertanyaan,
|
||||||
|
'skor' => 0
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response()->json([
|
||||||
|
'status' => true,
|
||||||
|
'data' => $data_ujian
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response()->json([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Data sesi tes tidak ditemukan.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getAllAnswer(Request $request) {
|
public function getAllAnswer(Request $request) {
|
||||||
$data_session = TestSessionsModel::where('id_test_sessions', $request->id_test_sessions)->first();
|
$data_session = TestSessionsModel::where('id_test_sessions', $request->id_test_sessions)->first();
|
||||||
if($data_session != null) {
|
if($data_session != null) {
|
||||||
|
|
@ -24,22 +60,40 @@ public function getAllAnswer(Request $request) {
|
||||||
foreach($detail_test as $detail) {
|
foreach($detail_test as $detail) {
|
||||||
$data_soal = DataSoalModel::where('id_soal', $detail->id_soal)->first();
|
$data_soal = DataSoalModel::where('id_soal', $detail->id_soal)->first();
|
||||||
$data_jawaban = $detail->jawaban;
|
$data_jawaban = $detail->jawaban;
|
||||||
|
$skor = null;
|
||||||
if($data_jawaban == 'a') {
|
if($data_jawaban == 'a') {
|
||||||
$data_jawaban = $data_soal->jawaban_a;
|
$data_jawaban = $data_soal->jawaban_a;
|
||||||
|
$skor = 1;
|
||||||
} else if($data_jawaban == 'b') {
|
} else if($data_jawaban == 'b') {
|
||||||
$data_jawaban = $data_soal->jawaban_b;
|
$data_jawaban = $data_soal->jawaban_b;
|
||||||
|
$skor = 2;
|
||||||
} else if($data_jawaban == 'c') {
|
} else if($data_jawaban == 'c') {
|
||||||
$data_jawaban = $data_soal->jawaban_c;
|
$data_jawaban = $data_soal->jawaban_c;
|
||||||
|
$skor = 3;
|
||||||
} else if($data_jawaban == 'd') {
|
} else if($data_jawaban == 'd') {
|
||||||
$data_jawaban = $data_soal->jawaban_d;
|
$data_jawaban = $data_soal->jawaban_d;
|
||||||
|
$skor = 4;
|
||||||
} else if($data_jawaban == 'e') {
|
} else if($data_jawaban == 'e') {
|
||||||
$data_jawaban = $data_soal->jawaban_e;
|
$data_jawaban = $data_soal->jawaban_e;
|
||||||
} else {
|
} else {
|
||||||
$data_jawaban = 'Tidak menjawab';
|
$data_jawaban = 'Tidak menjawab';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($detail->jawaban == 'a' && $data_soal->is_reverse == 1) {
|
||||||
|
$skor = 4;
|
||||||
|
} else if($detail->jawaban == 'b' && $data_soal->is_reverse == 1) {
|
||||||
|
$skor = 3;
|
||||||
|
} else if($detail->jawaban == 'c' && $data_soal->is_reverse == 1) {
|
||||||
|
$skor = 2;
|
||||||
|
} else if($detail->jawaban == 'd' && $data_soal->is_reverse == 1) {
|
||||||
|
$skor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
$data_ujian[] = [
|
$data_ujian[] = [
|
||||||
'id_soal' => $detail->id_soal,
|
'id_soal' => $detail->id_soal,
|
||||||
'jawaban' => $data_jawaban,
|
'jawaban' => $data_jawaban,
|
||||||
|
'is_reverse' => $data_soal->is_reverse,
|
||||||
|
'skor' => $skor,
|
||||||
'jawaban_key' => $detail->jawaban,
|
'jawaban_key' => $detail->jawaban,
|
||||||
'soal' => $data_soal->pertanyaan
|
'soal' => $data_soal->pertanyaan
|
||||||
];
|
];
|
||||||
|
|
@ -73,6 +127,90 @@ public function index(Request $request)
|
||||||
|
|
||||||
$data_session = TestSessionsModel::where('id_test_sessions', $id_session)->first();
|
$data_session = TestSessionsModel::where('id_test_sessions', $id_session)->first();
|
||||||
if($data_session != null) {
|
if($data_session != null) {
|
||||||
|
$start = strtotime($data_session->created_at);
|
||||||
|
$end = strtotime($data_session->updated_at);
|
||||||
|
$difference = gmdate("i:s", $end - $start);
|
||||||
|
|
||||||
|
$data_booking = BookingModel::where('id_booking', $data_session->id_booking)->first();
|
||||||
|
if($data_booking != null) {
|
||||||
|
if($data_booking->status_tes == '0') {
|
||||||
|
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes tidak ditemukan atau telah dinonaktifkan.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$data_information = [
|
||||||
|
'kode' => $data_booking->kode_unik,
|
||||||
|
'nama' => $data_booking->nama_lengkap,
|
||||||
|
'email' => $data_booking->email,
|
||||||
|
'no_hp' => $data_booking->no_telp,
|
||||||
|
];
|
||||||
|
|
||||||
|
$screen_dim = [
|
||||||
|
'width' => $data_session->screen_w,
|
||||||
|
'height' => $data_session->screen_h
|
||||||
|
];
|
||||||
|
|
||||||
|
$answered = DetailTestModel::where('id_test_sessions', $id_session)->where('jawaban', '!=', null)->count();
|
||||||
|
$question_count = DataSoalModel::all()->count();
|
||||||
|
$soalTerjawab = $answered;
|
||||||
|
$soalTidakTerjawab = $question_count - $answered;
|
||||||
|
|
||||||
|
$totalScore = 0;
|
||||||
|
$detail_test = DetailTestModel::where('id_test_sessions', $request->id_test_sessions)->get();
|
||||||
|
foreach($detail_test as $detail) {
|
||||||
|
$data_soal = DataSoalModel::where('id_soal', $detail->id_soal)->first();
|
||||||
|
$data_jawaban = $detail->jawaban;
|
||||||
|
if($data_soal->is_reverse == 1) {
|
||||||
|
if($data_jawaban == 'a') {
|
||||||
|
$totalScore += 4;
|
||||||
|
} else if($data_jawaban == 'b') {
|
||||||
|
$totalScore += 3;
|
||||||
|
} else if($data_jawaban == 'c') {
|
||||||
|
$totalScore += 2;
|
||||||
|
} else if($data_jawaban == 'd') {
|
||||||
|
$totalScore += 1;
|
||||||
|
} else if($data_jawaban == 'e') {
|
||||||
|
$totalScore += 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if($data_jawaban == 'a') {
|
||||||
|
$totalScore += 1;
|
||||||
|
} else if($data_jawaban == 'b') {
|
||||||
|
$totalScore += 2;
|
||||||
|
} else if($data_jawaban == 'c') {
|
||||||
|
$totalScore += 3;
|
||||||
|
} else if($data_jawaban == 'd') {
|
||||||
|
$totalScore += 4;
|
||||||
|
} else if($data_jawaban == 'e') {
|
||||||
|
$totalScore += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
$data_aswered = [
|
||||||
|
'total_question' => $question_count,
|
||||||
|
'answered' => $answered,
|
||||||
|
'unanswered' => $soalTidakTerjawab,
|
||||||
|
'totalScore' => $totalScore
|
||||||
|
];
|
||||||
|
|
||||||
|
$log_kecemasan = LogKecemasanModel::where('id_test_sessions', $id_session)->first();
|
||||||
|
if($log_kecemasan == null) {
|
||||||
|
LogKecemasanModel::create([
|
||||||
|
'id_booking' => $data_session->id_booking,
|
||||||
|
'id_test_sessions' => $id_session,
|
||||||
|
'start_timestamp' => $start,
|
||||||
|
'end_timestamp' => $end,
|
||||||
|
'difference_timestamp' => $end - $start,
|
||||||
|
'screen_width' => $data_session->screen_w,
|
||||||
|
'screen_height' => $data_session->screen_h,
|
||||||
|
'answered_count' => $answered,
|
||||||
|
'not_answered_count' => $soalTidakTerjawab,
|
||||||
|
'total_question' => $question_count,
|
||||||
|
'skor_kecemasan' => $totalScore
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data_booking = BookingModel::where('id_booking', $data_session->id_booking)->first();
|
||||||
if($data_session->status_session == '0') {
|
if($data_session->status_session == '0') {
|
||||||
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes dinonaktifkan. Silahkan cek status dengan kode untuk informasi lebih lanjut.');
|
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes dinonaktifkan. Silahkan cek status dengan kode untuk informasi lebih lanjut.');
|
||||||
} else if($data_session->status_session == '1') {
|
} else if($data_session->status_session == '1') {
|
||||||
|
|
@ -80,9 +218,15 @@ public function index(Request $request)
|
||||||
'status_session' => '2',
|
'status_session' => '2',
|
||||||
'is_active' => '0'
|
'is_active' => '0'
|
||||||
]);
|
]);
|
||||||
return view('user.pages.finish_ujian.index', compact('id_session'));
|
$data_booking->update([
|
||||||
|
'status_tes' => '2'
|
||||||
|
]);
|
||||||
|
return view('user.pages.finish_ujian.index', compact('id_session', 'difference', 'data_information', 'screen_dim', 'data_aswered'));
|
||||||
} else if($data_session->status_session == '2') {
|
} else if($data_session->status_session == '2') {
|
||||||
return view('user.pages.finish_ujian.index', compact('id_session'));
|
$data_booking->update([
|
||||||
|
'status_tes' => '2'
|
||||||
|
]);
|
||||||
|
return view('user.pages.finish_ujian.index', compact('id_session', 'difference', 'data_information', 'screen_dim', 'data_aswered'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes tidak ditemukan.');
|
return redirect()->route('cek-status.index')->with('error', 'Data sesi tes tidak ditemukan.');
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,34 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\BookingModel;
|
||||||
|
use App\Models\TestSessionsModel;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class HasilTesController extends Controller
|
class HasilTesController extends Controller
|
||||||
{
|
{
|
||||||
|
public function fetchData() {
|
||||||
|
$data_booking = BookingModel::orderBy('updated_at', 'desc')->get();
|
||||||
|
$result = [];
|
||||||
|
foreach($data_booking as $booking) {
|
||||||
|
$data_test = TestSessionsModel::where('id_booking', $booking->id_booking)->first();
|
||||||
|
if($data_test != null) {
|
||||||
|
$result[] = [
|
||||||
|
'id_test_session' => $data_test->id_test_sessions,
|
||||||
|
'nama_lengkap' => $booking->nama_lengkap,
|
||||||
|
'tgl_tes' => $data_test->created_at->format('d-m-Y'),
|
||||||
|
'jam_tes' => $data_test->created_at->format('H:i'),
|
||||||
|
'kode_booking' => $booking->kode_unik,
|
||||||
|
'status_tes' => $booking->status_tes
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'status' => true,
|
||||||
|
'data' => $result
|
||||||
|
]);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
|
|
@ -35,7 +59,20 @@ public function store(Request $request)
|
||||||
*/
|
*/
|
||||||
public function show(string $id)
|
public function show(string $id)
|
||||||
{
|
{
|
||||||
//
|
$data = TestSessionsModel::where('id_test_sessions', $id)->first();
|
||||||
|
|
||||||
|
if($data != null) {
|
||||||
|
$data_booking = BookingModel::where('id_booking', $data->id_booking)->first();
|
||||||
|
return response()->json([
|
||||||
|
'status' => true,
|
||||||
|
'nama' => $data_booking->nama_lengkap
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'status' => false,
|
||||||
|
'msg' => 'Data tidak ditemukan!'
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,6 +96,21 @@ public function update(Request $request, string $id)
|
||||||
*/
|
*/
|
||||||
public function destroy(string $id)
|
public function destroy(string $id)
|
||||||
{
|
{
|
||||||
//
|
$data = TestSessionsModel::where('id_test_sessions', $id)->first();
|
||||||
|
if($data != null) {
|
||||||
|
$data_booking = BookingModel::where('id_booking', $data->id_booking)->first();
|
||||||
|
$data_booking->update([
|
||||||
|
'status_tes' => '0'
|
||||||
|
]);
|
||||||
|
return response()->json([
|
||||||
|
'status' => true,
|
||||||
|
'msg' => 'Data berhasil dinonaktifkan'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'status' => false,
|
||||||
|
'msg' => 'Data tidak ditemukan!'
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class UsersController extends Controller
|
class UsersController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -11,7 +12,7 @@ class UsersController extends Controller
|
||||||
* Display data for javascript ajax
|
* Display data for javascript ajax
|
||||||
*/
|
*/
|
||||||
public function getData() {
|
public function getData() {
|
||||||
$data = User::get();
|
$data = User::where('id', '!=', Auth::user()->id)->get();
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => true,
|
'status' => true,
|
||||||
'data' => $data->toArray()
|
'data' => $data->toArray()
|
||||||
|
|
@ -39,7 +40,18 @@ public function create()
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
$data = User::create([
|
||||||
|
'name' => $request->name,
|
||||||
|
'email' => $request->email,
|
||||||
|
'role' => $request->role,
|
||||||
|
'alamat' => $request->alamat,
|
||||||
|
'password' => bcrypt('password', ['rounds' => 12])
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'status' => true,
|
||||||
|
'msg' => 'Data berhasil di tambahkan'
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -74,7 +86,8 @@ public function update(Request $request, string $id)
|
||||||
$data = User::where('id', $id)->update([
|
$data = User::where('id', $id)->update([
|
||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'email' => $request->email,
|
'email' => $request->email,
|
||||||
'role' => $request->role
|
'role' => $request->role,
|
||||||
|
'alamat' => $request->alamat
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class LogKecemasanModel extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'log_hasil_kecemasan';
|
||||||
|
|
||||||
|
protected $primaryKey = 'id_log_kecemasan';
|
||||||
|
|
||||||
|
protected $keyType = 'string';
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'id_log_kecemasan',
|
||||||
|
'id_booking',
|
||||||
|
'id_test_sessions',
|
||||||
|
'start_timestamp',
|
||||||
|
'end_timestamp',
|
||||||
|
'difference_timestamp',
|
||||||
|
'screen_width',
|
||||||
|
'screen_height',
|
||||||
|
'answered_count',
|
||||||
|
'not_answered_count',
|
||||||
|
'total_question',
|
||||||
|
'skor_kecemasan'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'id_log_kecemasan' => 'string',
|
||||||
|
'id_booking' => 'string',
|
||||||
|
'id_test_sessions' => 'string',
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
static::creating(function ($model) {
|
||||||
|
if (empty($model->id_log_kecemasan)) {
|
||||||
|
$model->id_log_kecemasan = (string) \Illuminate\Support\Str::uuid();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,7 +21,8 @@ class User extends Authenticatable
|
||||||
'name',
|
'name',
|
||||||
'email',
|
'email',
|
||||||
'password',
|
'password',
|
||||||
'role'
|
'role',
|
||||||
|
'alamat'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,4 +47,14 @@ protected function casts(): array
|
||||||
'password' => 'hashed',
|
'password' => 'hashed',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
static::creating(function ($model) {
|
||||||
|
if (empty($model->id_user)) {
|
||||||
|
$model->id_user = (string) \Illuminate\Support\Str::uuid();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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('soal', function (Blueprint $table) {
|
||||||
|
$table->enum('jawaban_benar', [0, 1])->default(0)->change();
|
||||||
|
$table->renameColumn('jawaban_benar', 'is_reverse');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('soal', function (Blueprint $table) {
|
||||||
|
$table->renameColumn('is_reverse', 'jawaban_benar');
|
||||||
|
$table->enum('jawaban_benar', ['a', 'b', 'c', 'd', 'e'])->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?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::create('log_hasil_kecemasan', function (Blueprint $table) {
|
||||||
|
$table->uuid('id_log_kecemasan')->primary();
|
||||||
|
$table->uuid('id_booking');
|
||||||
|
$table->uuid('id_test_sessions');
|
||||||
|
$table->char('start_timestamp', 20);
|
||||||
|
$table->char('end_timestamp', 20);
|
||||||
|
$table->char('difference_timestamp', 20);
|
||||||
|
$table->char('screen_width', 10);
|
||||||
|
$table->char('screen_height', 10);
|
||||||
|
$table->integer('answered_count');
|
||||||
|
$table->integer('not_answered_count');
|
||||||
|
$table->integer('total_question');
|
||||||
|
$table->integer('skor_kecemasan');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('log_hasil_kecemasan');
|
||||||
|
}
|
||||||
|
};
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 76 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
|
|
@ -1,9 +1,9 @@
|
||||||
<nav class="pc-sidebar">
|
<nav class="pc-sidebar">
|
||||||
<div class="navbar-wrapper">
|
<div class="navbar-wrapper">
|
||||||
<div class="m-header">
|
<div class="m-header">
|
||||||
<a href="{{ route('dashboard.index') }}" class="b-brand text-primary">
|
<a href="{{ route('dashboard.index') }}" class="b-brand text-primary fs-3 fw-bold text-dark">
|
||||||
<!-- ======== Change your logo from here ============ -->
|
<!-- ======== Change your logo from here ============ -->
|
||||||
<img src="{{ asset('assets/admin/assets/images/logo-dark.svg') }}" class="img-fluid logo-lg" alt="logo" id="logo-admin">
|
{{ env('APP_NAME') }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-content">
|
<div class="navbar-content">
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,15 @@
|
||||||
<div class="col-md-6 col-xl-3">
|
<div class="col-md-6 col-xl-3">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="mb-2 f-w-400 text-muted">Total Page Views</h6>
|
<h6 class="mb-2 f-w-400 text-muted">Total Booking hari ini</h6>
|
||||||
<h4 class="mb-3">4,42,236 <span class="badge bg-light-primary border border-primary"><i
|
<h4 class="mb-3">
|
||||||
class="ti ti-trending-up"></i> 59.3%</span></h4>
|
<span id="total_booking"></span>
|
||||||
<p class="mb-0 text-muted text-sm">You made an extra <span class="text-primary">35,000</span> this year
|
<span class="badge bg-light-primary border border-primary">
|
||||||
|
<i class="ti" id="trending-icon-booking"></i>
|
||||||
|
<span id="booking_percent">%</span>
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<p class="mb-0 text-muted text-sm">Booking <span id="booking_trend">bertambah</span> <span class="text-primary" id="from_month_booking_count"></span> dari bulan lalu
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -35,271 +40,146 @@ class="ti ti-trending-up"></i> 59.3%</span></h4>
|
||||||
<div class="col-md-6 col-xl-3">
|
<div class="col-md-6 col-xl-3">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="mb-2 f-w-400 text-muted">Total Users</h6>
|
<h6 class="mb-2 f-w-400 text-muted">Total tes selesai hari ini</h6>
|
||||||
<h4 class="mb-3">78,250 <span class="badge bg-light-success border border-success"><i
|
<h4 class="mb-3">
|
||||||
class="ti ti-trending-up"></i> 70.5%</span></h4>
|
<span id="total_tes"></span>
|
||||||
<p class="mb-0 text-muted text-sm">You made an extra <span class="text-success">8,900</span> this year</p>
|
<span class="badge bg-light-primary border border-primary">
|
||||||
|
<i class="ti" id="trending-icon-tes"></i>
|
||||||
|
<span id="tes_percent">%</span>
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<p class="mb-0 text-muted text-sm">Tes <span id="tes_trend">bertambah</span> <span class="text-primary" id="from_month_tes_count"></span> dari bulan lalu
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-xl-3">
|
<div class="col-md-6 col-xl-3">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="mb-2 f-w-400 text-muted">Total Order</h6>
|
<h6 class="mb-2 f-w-400 text-muted">Total tes masih berlangsung hari ini</h6>
|
||||||
<h4 class="mb-3">18,800 <span class="badge bg-light-warning border border-warning"><i
|
<h4 class="mb-3">
|
||||||
class="ti ti-trending-down"></i> 27.4%</span></h4>
|
<span id="total_tes_berlangsung"></span>
|
||||||
<p class="mb-0 text-muted text-sm">You made an extra <span class="text-warning">1,943</span> this year</p>
|
<span class="badge bg-light-primary border border-primary">
|
||||||
|
<i class="ti" id="trending-icon-tes-berlangsung"></i>
|
||||||
|
<span id="tes_berlangsung_percent">%</span>
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<p class="mb-0 text-muted text-sm">Tes yang sedang berlangsung <span id="tes_berlangsung_trend">bertambah</span> <span class="text-primary" id="from_month_tes_berlangsung_count"></span> dari bulan lalu
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-xl-3">
|
<div class="col-md-6 col-xl-3">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="mb-2 f-w-400 text-muted">Total Sales</h6>
|
<h6 class="mb-2 f-w-400 text-muted">Rata rata skor kecemasan hari ini</h6>
|
||||||
<h4 class="mb-3">$35,078 <span class="badge bg-light-danger border border-danger"><i
|
<h4 class="mb-3">
|
||||||
class="ti ti-trending-down"></i> 27.4%</span></h4>
|
<span id="rata_rata_kecemasan"></span>
|
||||||
<p class="mb-0 text-muted text-sm">You made an extra <span class="text-danger">$20,395</span> this year
|
<span class="badge bg-light-primary border border-primary">
|
||||||
|
<i class="ti" id="trending-icon-rata-rata"></i>
|
||||||
|
<span id="rata_rata_kecemasan_percent">%</span>
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
<p class="mb-0 text-muted text-sm">Rata rata skor kecemasan <span id="rata_rata_kecemasan_trend">bertambah</span> <span class="text-primary" id="from_month_rata_rata_kecemasan_count"></span> dari bulan lalu
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-12 col-xl-8">
|
<div class="col-md-12 col-xl-8">
|
||||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
<h5 class="mb-3">Tabel Monitoring Tes</h5>
|
||||||
<h5 class="mb-0">Unique Visitor</h5>
|
<table id="table-data-booking" class="table table-bordered">
|
||||||
<ul class="nav nav-pills justify-content-end mb-0" id="chart-tab-tab" role="tablist">
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="chart-tab-home-tab" data-bs-toggle="pill" data-bs-target="#chart-tab-home"
|
|
||||||
type="button" role="tab" aria-controls="chart-tab-home" aria-selected="true">Month</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link active" id="chart-tab-profile-tab" data-bs-toggle="pill"
|
|
||||||
data-bs-target="#chart-tab-profile" type="button" role="tab" aria-controls="chart-tab-profile"
|
|
||||||
aria-selected="false">Week</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="tab-content" id="chart-tab-tabContent">
|
|
||||||
<div class="tab-pane" id="chart-tab-home" role="tabpanel" aria-labelledby="chart-tab-home-tab"
|
|
||||||
tabindex="0">
|
|
||||||
<div id="visitor-chart-1"></div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane show active" id="chart-tab-profile" role="tabpanel"
|
|
||||||
aria-labelledby="chart-tab-profile-tab" tabindex="0">
|
|
||||||
<div id="visitor-chart"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-12 col-xl-4">
|
|
||||||
<h5 class="mb-3">Income Overview</h5>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h6 class="mb-2 f-w-400 text-muted">This Week Statistics</h6>
|
|
||||||
<h3 class="mb-3">$7,650</h3>
|
|
||||||
<div id="income-overview-chart"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-12 col-xl-8">
|
|
||||||
<h5 class="mb-3">Recent Orders</h5>
|
|
||||||
<div class="card tbl-card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-hover table-borderless mb-0">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>TRACKING NO.</th>
|
<th>No</th>
|
||||||
<th>PRODUCT NAME</th>
|
<th>Nama</th>
|
||||||
<th>TOTAL ORDER</th>
|
<th>Email</th>
|
||||||
<th>STATUS</th>
|
<th>Telepon</th>
|
||||||
<th class="text-end">TOTAL AMOUNT</th>
|
<th>Tanggal Booking</th>
|
||||||
|
<th>Status Tes</th>
|
||||||
|
<th>Status Sesi</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Camera Lens</td>
|
|
||||||
<td>40</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-danger f-10 m-r-5"></i>Rejected</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-end">$40,570</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Laptop</td>
|
|
||||||
<td>300</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-warning f-10 m-r-5"></i>Pending</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-end">$180,139</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Mobile</td>
|
|
||||||
<td>355</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-success f-10 m-r-5"></i>Approved</span></td>
|
|
||||||
<td class="text-end">$180,139</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Camera Lens</td>
|
|
||||||
<td>40</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-danger f-10 m-r-5"></i>Rejected</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-end">$40,570</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Laptop</td>
|
|
||||||
<td>300</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-warning f-10 m-r-5"></i>Pending</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-end">$180,139</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Mobile</td>
|
|
||||||
<td>355</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-success f-10 m-r-5"></i>Approved</span></td>
|
|
||||||
<td class="text-end">$180,139</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Camera Lens</td>
|
|
||||||
<td>40</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-danger f-10 m-r-5"></i>Rejected</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-end">$40,570</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Laptop</td>
|
|
||||||
<td>300</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-warning f-10 m-r-5"></i>Pending</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-end">$180,139</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Mobile</td>
|
|
||||||
<td>355</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-success f-10 m-r-5"></i>Approved</span></td>
|
|
||||||
<td class="text-end">$180,139</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="#" class="text-muted">84564564</a></td>
|
|
||||||
<td>Mobile</td>
|
|
||||||
<td>355</td>
|
|
||||||
<td><span class="d-flex align-items-center gap-2"><i
|
|
||||||
class="fas fa-circle text-success f-10 m-r-5"></i>Approved</span></td>
|
|
||||||
<td class="text-end">$180,139</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endsection
|
||||||
</div>
|
|
||||||
<div class="col-md-12 col-xl-4">
|
@section('script')
|
||||||
<h5 class="mb-3">Analytics Report</h5>
|
<script>
|
||||||
<div class="card">
|
let table = null;
|
||||||
<div class="list-group list-group-flush">
|
$(document).ready(function() {
|
||||||
<a href="#"
|
$.get('{{ route("dashboard.fetchData") }}', function(data) {
|
||||||
class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">Company
|
$('#total_booking').text(data.total_booking);
|
||||||
Finance Growth<span class="h5 mb-0">+45.14%</span></a>
|
$('#booking_percent').text(data.booking_percent + '%');
|
||||||
<a href="#"
|
$('#from_month_booking_count').text(data.from_month_booking_count);
|
||||||
class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">Company
|
$('#booking_trend').text(data.booking_trend);
|
||||||
Expenses Ratio<span class="h5 mb-0">0.58%</span></a>
|
if (data.booking_diff >= 0) {
|
||||||
<a href="#"
|
$('#trending-icon-booking').addClass('ti-trending-up');
|
||||||
class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">Business
|
$('#booking_percent').addClass('text-primary');
|
||||||
Risk Cases<span class="h5 mb-0">Low</span></a>
|
} else {
|
||||||
</div>
|
$('#trending-icon-booking').addClass('ti-trending-down');
|
||||||
<div class="card-body px-2">
|
$('#booking_percent').addClass('text-danger');
|
||||||
<div id="analytics-report-chart"></div>
|
}
|
||||||
</div>
|
|
||||||
</div>
|
$('#total_tes').text(data.total_tes);
|
||||||
</div>
|
$('#tes_percent').text(data.tes_percent + '%');
|
||||||
|
$('#from_month_tes_count').text(data.from_month_tes_count);
|
||||||
<div class="col-md-12 col-xl-8">
|
$('#tes_trend').text(data.tes_trend);
|
||||||
<h5 class="mb-3">Sales Report</h5>
|
if (data.tes_diff >= 0) {
|
||||||
<div class="card">
|
$('#trending-icon-tes').addClass('ti-trending-up');
|
||||||
<div class="card-body">
|
$('#tes_percent').addClass('text-primary');
|
||||||
<h6 class="mb-2 f-w-400 text-muted">This Week Statistics</h6>
|
} else {
|
||||||
<h3 class="mb-0">$7,650</h3>
|
$('#trending-icon-tes').addClass('ti-trending-down');
|
||||||
<div id="sales-report-chart"></div>
|
$('#tes_percent').addClass('text-danger');
|
||||||
</div>
|
}
|
||||||
</div>
|
|
||||||
</div>
|
$('#total_tes_berlangsung').text(data.total_tes_berlangsung);
|
||||||
<div class="col-md-12 col-xl-4">
|
$('#tes_berlangsung_percent').text(data.tes_berlangsung_percent + '%');
|
||||||
<h5 class="mb-3">Transaction History</h5>
|
$('#from_month_tes_berlangsung_count').text(data.from_month_tes_berlangsung_count);
|
||||||
<div class="card">
|
$('#tes_berlangsung_trend').text(data.tes_berlangsung_trend);
|
||||||
<div class="list-group list-group-flush">
|
if (data.tes_berlangsung_diff >= 0) {
|
||||||
<a href="#" class="list-group-item list-group-item-action">
|
$('#trending-icon-tes-berlangsung').addClass('ti-trending-up');
|
||||||
<div class="d-flex">
|
$('#tes_berlangsung_percent').addClass('text-primary');
|
||||||
<div class="flex-shrink-0">
|
} else {
|
||||||
<div class="avtar avtar-s rounded-circle text-success bg-light-success">
|
$('#trending-icon-tes-berlangsung').addClass('ti-trending-down');
|
||||||
<i class="ti ti-gift f-18"></i>
|
$('#tes_berlangsung_percent').addClass('text-danger');
|
||||||
</div>
|
}
|
||||||
</div>
|
|
||||||
<div class="flex-grow-1 ms-3">
|
$('#rata_rata_kecemasan').text(data.rata_rata_kecemasan);
|
||||||
<h6 class="mb-1">Order #002434</h6>
|
$('#rata_rata_kecemasan_percent').text(data.rata_rata_kecemasan_percent + '%');
|
||||||
<p class="mb-0 text-muted">Today, 2:00 AM</P>
|
$('#from_month_rata_rata_kecemasan_count').text(data.from_month_rata_rata_kecemasan);
|
||||||
</div>
|
$('#rata_rata_kecemasan_trend').text(data.rata_rata_kecemasan_trend);
|
||||||
<div class="flex-shrink-0 text-end">
|
if (data.rata_rata_kecemasan_diff >= 0) {
|
||||||
<h6 class="mb-1">+ $1,430</h6>
|
$('#trending-icon-rata-rata').addClass('ti-trending-up');
|
||||||
<p class="mb-0 text-muted">78%</P>
|
$('#rata_rata_kecemasan_percent').addClass('text-primary');
|
||||||
</div>
|
} else {
|
||||||
</div>
|
$('#trending-icon-rata-rata').addClass('ti-trending-down');
|
||||||
</a>
|
$('#rata_rata_kecemasan_percent').addClass('text-danger');
|
||||||
<a href="#" class="list-group-item list-group-item-action">
|
}
|
||||||
<div class="d-flex">
|
|
||||||
<div class="flex-shrink-0">
|
table = new DataTable('#table-data-booking', {
|
||||||
<div class="avtar avtar-s rounded-circle text-primary bg-light-primary">
|
searching: false,
|
||||||
<i class="ti ti-message-circle f-18"></i>
|
paging: false,
|
||||||
</div>
|
ajax: {
|
||||||
</div>
|
url: '{{ route("dashboard.fetchDataTable") }}',
|
||||||
<div class="flex-grow-1 ms-3">
|
},
|
||||||
<h6 class="mb-1">Order #984947</h6>
|
columns: [
|
||||||
<p class="mb-0 text-muted">5 August, 1:45 PM</P>
|
{
|
||||||
</div>
|
data: null,
|
||||||
<div class="flex-shrink-0 text-end">
|
render: function(data, type, row, meta) {
|
||||||
<h6 class="mb-1">- $302</h6>
|
return meta.row + 1;
|
||||||
<p class="mb-0 text-muted">8%</P>
|
}
|
||||||
</div>
|
},
|
||||||
</div>
|
{ data: 'nama_lengkap' },
|
||||||
</a>
|
{ data: 'email', name: 'email' },
|
||||||
<a href="#" class="list-group-item list-group-item-action">
|
{ data: 'no_telp' },
|
||||||
<div class="d-flex">
|
{ data: 'tanggal_booking' },
|
||||||
<div class="flex-shrink-0">
|
{ data: 'status_tes' },
|
||||||
<div class="avtar avtar-s rounded-circle text-danger bg-light-danger">
|
{ data: 'status_session' },
|
||||||
<i class="ti ti-settings f-18"></i>
|
]
|
||||||
</div>
|
});
|
||||||
</div>
|
});
|
||||||
<div class="flex-grow-1 ms-3">
|
});
|
||||||
<h6 class="mb-1">Order #988784</h6>
|
</script>
|
||||||
<p class="mb-0 text-muted">7 hours ago</P>
|
|
||||||
</div>
|
|
||||||
<div class="flex-shrink-0 text-end">
|
|
||||||
<h6 class="mb-1">- $682</h6>
|
|
||||||
<p class="mb-0 text-muted">16%</P>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -139,7 +139,7 @@
|
||||||
<div class="col-md-12 my-1">
|
<div class="col-md-12 my-1">
|
||||||
<label for="edit_status_tes" class="form-label">Status</label>
|
<label for="edit_status_tes" class="form-label">Status</label>
|
||||||
<select class="form-select" name="edit_status_tes" id="edit_status_tes">
|
<select class="form-select" name="edit_status_tes" id="edit_status_tes">
|
||||||
<option value="0">Menunggu Konfirmasi</option>
|
<option value="0">Nonaktif</option>
|
||||||
<option value="1">Siap/Sedang Tes</option>
|
<option value="1">Siap/Sedang Tes</option>
|
||||||
<option value="2">Selesai</option>
|
<option value="2">Selesai</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
@ -183,8 +183,8 @@
|
||||||
let table = null;
|
let table = null;
|
||||||
let idEdit = null;
|
let idEdit = null;
|
||||||
let idHapus = null;
|
let idHapus = null;
|
||||||
let status_dict = ['warning', 'info', 'success'];
|
let status_dict = ['secondary', 'info', 'success'];
|
||||||
let status_dict_text = ['Menunggu Konfirmasi', 'Siap/Sedang Tes', 'Selesai'];
|
let status_dict_text = ['Nonaktif', 'Siap/Sedang Tes', 'Selesai'];
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
table = new DataTable("#table-data", {
|
table = new DataTable("#table-data", {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
|
||||||
|
|
@ -41,30 +41,13 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>No</th>
|
<th>No</th>
|
||||||
<th>Dummy</th>
|
<th>Nama</th>
|
||||||
<th>Dummy</th>
|
<th>Kode Unik</th>
|
||||||
<th>Dummy</th>
|
<th>Tgl dan Jam Ujian</th>
|
||||||
|
<th>Status Data</th>
|
||||||
<th>Aksi</th>
|
<th>Aksi</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>1</td>
|
|
||||||
<td>lorem</td>
|
|
||||||
<td>lorem</td>
|
|
||||||
<td>lorem</td>
|
|
||||||
<td>
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-info btn-sm rounded-circle mx-1" data-bs-toggle="modal" data-bs-target="#editModal" onclick="getDataEdit(this)" data-id="${data.id}">
|
|
||||||
<i class="ti ti-edit"></i>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-sm btn-danger delete-btn rounded-circle mx-1" data-bs-toggle="modal" data-bs-target="#deleteModal" onclick="getDataHapus(this)" data-id="${data.id}">
|
|
||||||
<i class="ti ti-trash"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -72,10 +55,229 @@
|
||||||
<!-- [ sample-page ] end -->
|
<!-- [ sample-page ] end -->
|
||||||
</div>
|
</div>
|
||||||
<!-- [ Main Content ] end -->
|
<!-- [ Main Content ] end -->
|
||||||
|
|
||||||
|
<!-- Modal Delete -->
|
||||||
|
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="exampleModalLabel">Hapus Data</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Apakah anda akan menghapus data dengan nama "<span id="delete_test" class="fw-bold"></span>" ini? (data hanya akan dinonaktikan)
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Batal</button>
|
||||||
|
<button type="button" class="btn btn-danger" onclick="hapusData()">Hapus</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- <!-- Modal Restore -->
|
||||||
|
<div class="modal fade" id="restoreModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="exampleModalLabel">Restore Data</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Apakah anda akan memulihkan data dengan nama "<span id="restore_test" class="fw-bold"></span>" ini? (data akan diperiksa dengan status terakhirnya)
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Batal</button>
|
||||||
|
<button type="button" class="btn btn-danger" onclick="restoreData()">Hapus</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> --}}
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('script')
|
@section('script')
|
||||||
<script>
|
<script>
|
||||||
new DataTable("#table-data", {});
|
let idHapus = null;
|
||||||
|
let tableData = null;
|
||||||
|
let ws = null;
|
||||||
|
|
||||||
|
function fetchRowData() {
|
||||||
|
if(tableData != null) {
|
||||||
|
tableData.ajax.reload(null, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDataInfo(btn) {
|
||||||
|
let idShow = btn.getAttribute('data-id');
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Alert',
|
||||||
|
icon: 'question',
|
||||||
|
text: 'Apakah Anda ingin melihat hasil dari data ini?',
|
||||||
|
confirmButtonText: 'Ya',
|
||||||
|
cancelButtonText: 'Tidak',
|
||||||
|
showCancelButton: true,
|
||||||
|
showCloseButton: true,
|
||||||
|
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
window.open("{{ route('hasil-tes.index') }}?id_test_sessions=" + idShow, "_blank");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDataDownload(btn) {
|
||||||
|
let idShow = btn.getAttribute('data-id');
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Alert',
|
||||||
|
icon: 'question',
|
||||||
|
text: 'Apakah Anda ingin mendownload hasil dari data ini?',
|
||||||
|
confirmButtonText: 'Ya',
|
||||||
|
cancelButtonText: 'Tidak',
|
||||||
|
showCancelButton: true,
|
||||||
|
showCloseButton: true,
|
||||||
|
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
'type': 'download_hasil_tes',
|
||||||
|
'id_test_sessions': idShow
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDataHapus(btn) {
|
||||||
|
idHapus = btn.getAttribute('data-id');
|
||||||
|
let urlShow = '{{ route('hasil_tes.show', ['__ID__']) }}';
|
||||||
|
|
||||||
|
$.get(urlShow.replace('__ID__', idHapus), function(data, status) {
|
||||||
|
if(data.status) {
|
||||||
|
$('#delete_test').html(data.nama);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hapusData() {
|
||||||
|
if(idHapus != null) {
|
||||||
|
let urlDestroy = '{{ route('hasil_tes.destroy', ['__ID__']) }}';
|
||||||
|
|
||||||
|
$.post(urlDestroy.replace('__ID__', idHapus), {
|
||||||
|
'_token': document.getElementById('_token').getAttribute('value'),
|
||||||
|
'_method': 'DELETE'
|
||||||
|
}, function(data, status) {
|
||||||
|
if(data.status) {
|
||||||
|
$('#deleteModal').modal('hide');
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Data berhasil dinonakstifkan!",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
fetchRowData();
|
||||||
|
idHapus = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
tableData = new DataTable("#table-data", {
|
||||||
|
'ajax': {
|
||||||
|
'url': '{{ route('hasil-tes.fetchData') }}'
|
||||||
|
},
|
||||||
|
'columns': [
|
||||||
|
{
|
||||||
|
data: null,
|
||||||
|
render: function(data, type, row, meta) {
|
||||||
|
return meta.row + 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'nama_lengkap'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'kode_booking'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: null,
|
||||||
|
render: function(data, type, row, meta) {
|
||||||
|
return `${data.tgl_tes} ${data.jam_tes}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: null,
|
||||||
|
render: function(data, type, row, meta) {
|
||||||
|
let bgClass = ['secondary', 'warning', 'success'];
|
||||||
|
let text = ['Nonaktif', 'Dalam Ujian', 'Selesai'];
|
||||||
|
return `
|
||||||
|
<span class="badge rounded-pill text-bg-${bgClass[data.status_tes]}">${text[data.status_tes]}</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: null,
|
||||||
|
render: function(data, type, row, meta) {
|
||||||
|
if(data.status_tes == 0) {
|
||||||
|
return `
|
||||||
|
<div class="btn-group">
|
||||||
|
<a class="btn btn-info btn-sm rounded-circle mx-1 text-light" onclick="getDataInfo(this)" data-id="${data.id_test_session}">
|
||||||
|
<i class="ti ti-file-info"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
return `
|
||||||
|
<div class="btn-group">
|
||||||
|
<a class="btn btn-info btn-sm rounded-circle mx-1 text-light" onclick="getDataInfo(this)" data-id="${data.id_test_session}">
|
||||||
|
<i class="ti ti-file-info"></i>
|
||||||
|
</a>
|
||||||
|
<button class="btn btn-sm btn-success rounded-circle mx-1" data-bs-toggle="modal" data-bs-target="#downloadModal" onclick="getDataDownload(this)" data-id="${data.id_test_session}">
|
||||||
|
<i class="ti ti-download"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-danger delete-btn rounded-circle mx-1" data-bs-toggle="modal" data-bs-target="#deleteModal" onclick="getDataHapus(this)" data-id="${data.id_test_session}">
|
||||||
|
<i class="ti ti-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Connecting to WebSocket...");
|
||||||
|
ws = new WebSocket("{{ env('WEBSOCKET_URL') }}");
|
||||||
|
ws.onopen = function() {
|
||||||
|
console.log("WebSocket connection established.");
|
||||||
|
};
|
||||||
|
ws.onmessage = function(event) {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
if(data.type === 'download_hasil_tes_response') {
|
||||||
|
if(data.data != null) {
|
||||||
|
console.log(data)
|
||||||
|
const blob = new Blob([JSON.stringify(data.data)], { type: 'text/plain;charset=utf-8' });
|
||||||
|
const link = document.createElement('a');
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
link.href = url;
|
||||||
|
link.download = `hasil_tes_${data.id_test_sessions}.json`;
|
||||||
|
link.style.display = 'none';
|
||||||
|
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Sukses',
|
||||||
|
text: 'Hasil tes berhasil didownload!',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'Gagal mendownload hasil tes.',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -93,13 +93,10 @@
|
||||||
<input disabled type="text" class="form-control" id="info_jawaban_e" name="info_jawaban_e">
|
<input disabled type="text" class="form-control" id="info_jawaban_e" name="info_jawaban_e">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 my-1">
|
<div class="col-md-6 my-1">
|
||||||
<label for="info_jawaban_benar" class="form-label">Jawaban Benar</label>
|
<label for="info_is_reverse" class="form-label">Apakah jawaban positif?</label>
|
||||||
<select disabled class="form-select" name="info_jawaban_benar" id="info_jawaban_benar">
|
<select disabled class="form-select" name="info_is_reverse" id="info_is_reverse">
|
||||||
<option value="a">A</option>
|
<option value="0">Tidak</option>
|
||||||
<option value="b">B</option>
|
<option value="1">Ya</option>
|
||||||
<option value="c">C</option>
|
|
||||||
<option value="d">D</option>
|
|
||||||
<option value="e">E</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -146,13 +143,10 @@
|
||||||
<input type="text" class="form-control" id="jawaban_e" name="jawaban_e">
|
<input type="text" class="form-control" id="jawaban_e" name="jawaban_e">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 my-1">
|
<div class="col-md-6 my-1">
|
||||||
<label for="jawaban_benar" class="form-label">Jawaban Benar</label>
|
<label for="is_reverse" class="form-label">Apakah jawaban positif?</label>
|
||||||
<select class="form-select" name="jawaban_benar" id="jawaban_benar">
|
<select class="form-select" name="is_reverse" id="is_reverse">
|
||||||
<option value="a">A</option>
|
<option value="0">Tidak</option>
|
||||||
<option value="b">B</option>
|
<option value="1">Ya</option>
|
||||||
<option value="c">C</option>
|
|
||||||
<option value="d">D</option>
|
|
||||||
<option value="e">E</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -200,13 +194,10 @@
|
||||||
<input type="text" class="form-control" id="edit_jawaban_e" name="edit_jawaban_e">
|
<input type="text" class="form-control" id="edit_jawaban_e" name="edit_jawaban_e">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 my-1">
|
<div class="col-md-6 my-1">
|
||||||
<label for="edit_jawaban_benar" class="form-label">Jawaban Benar</label>
|
<label for="is_reverse" class="form-label">Apakah jawaban positif?</label>
|
||||||
<select class="form-select" name="edit_jawaban_benar" id="edit_jawaban_benar">
|
<select class="form-select" name="edit_is_reverse" id="edit_is_reverse">
|
||||||
<option value="a">A</option>
|
<option value="0">Tidak</option>
|
||||||
<option value="b">B</option>
|
<option value="1">Ya</option>
|
||||||
<option value="c">C</option>
|
|
||||||
<option value="d">D</option>
|
|
||||||
<option value="e">E</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -296,7 +287,7 @@ function simpanAddData() {
|
||||||
'jawaban_c': $('#jawaban_c').val(),
|
'jawaban_c': $('#jawaban_c').val(),
|
||||||
'jawaban_d': $('#jawaban_d').val(),
|
'jawaban_d': $('#jawaban_d').val(),
|
||||||
'jawaban_e': $('#jawaban_e').val(),
|
'jawaban_e': $('#jawaban_e').val(),
|
||||||
'jawaban_benar': $('#jawaban_benar').val(),
|
'is_reverse': $('#is_reverse').val(),
|
||||||
}, function(data, status) {
|
}, function(data, status) {
|
||||||
$('#addModal').modal('hide');
|
$('#addModal').modal('hide');
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
|
|
@ -319,7 +310,7 @@ function getDataInfo(btn) {
|
||||||
$('#info_jawaban_c').attr('disabled', '');
|
$('#info_jawaban_c').attr('disabled', '');
|
||||||
$('#info_jawaban_d').attr('disabled', '');
|
$('#info_jawaban_d').attr('disabled', '');
|
||||||
$('#info_jawaban_e').attr('disabled', '');
|
$('#info_jawaban_e').attr('disabled', '');
|
||||||
$('#info_jawaban_benar').attr('disabled', '');
|
$('#info_is_reverse').attr('disabled', '');
|
||||||
|
|
||||||
$('#info_pertanyaan').val(data.data.pertanyaan);
|
$('#info_pertanyaan').val(data.data.pertanyaan);
|
||||||
$('#info_jawaban_a').val(data.data.jawaban_a);
|
$('#info_jawaban_a').val(data.data.jawaban_a);
|
||||||
|
|
@ -327,7 +318,7 @@ function getDataInfo(btn) {
|
||||||
$('#info_jawaban_c').val(data.data.jawaban_c);
|
$('#info_jawaban_c').val(data.data.jawaban_c);
|
||||||
$('#info_jawaban_d').val(data.data.jawaban_d);
|
$('#info_jawaban_d').val(data.data.jawaban_d);
|
||||||
$('#info_jawaban_e').val(data.data.jawaban_e);
|
$('#info_jawaban_e').val(data.data.jawaban_e);
|
||||||
$('#info_jawaban_benar').val(data.data.jawaban_benar);
|
$('#info_is_reverse').val(data.data.is_reverse);
|
||||||
|
|
||||||
$('#info_pertanyaan').attr('disabled', 'disabled');
|
$('#info_pertanyaan').attr('disabled', 'disabled');
|
||||||
$('#info_jawaban_a').attr('disabled', 'disabled');
|
$('#info_jawaban_a').attr('disabled', 'disabled');
|
||||||
|
|
@ -335,7 +326,7 @@ function getDataInfo(btn) {
|
||||||
$('#info_jawaban_c').attr('disabled', 'disabled');
|
$('#info_jawaban_c').attr('disabled', 'disabled');
|
||||||
$('#info_jawaban_d').attr('disabled', 'disabled');
|
$('#info_jawaban_d').attr('disabled', 'disabled');
|
||||||
$('#info_jawaban_e').attr('disabled', 'disabled');
|
$('#info_jawaban_e').attr('disabled', 'disabled');
|
||||||
$('#info_jawaban_benar').attr('disabled', 'disabled');
|
$('#info_is_reverse').attr('disabled', 'disabled');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +343,7 @@ function getDataEdit(btn) {
|
||||||
$('#edit_jawaban_c').val(data.data.jawaban_c);
|
$('#edit_jawaban_c').val(data.data.jawaban_c);
|
||||||
$('#edit_jawaban_d').val(data.data.jawaban_d);
|
$('#edit_jawaban_d').val(data.data.jawaban_d);
|
||||||
$('#edit_jawaban_e').val(data.data.jawaban_e);
|
$('#edit_jawaban_e').val(data.data.jawaban_e);
|
||||||
$('#edit_jawaban_benar').val(data.data.jawaban_benar);
|
$('#edit_is_reverse').val(data.data.is_reverse);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -370,7 +361,7 @@ function simpanEditData() {
|
||||||
'jawaban_c': $('#edit_jawaban_c').val(),
|
'jawaban_c': $('#edit_jawaban_c').val(),
|
||||||
'jawaban_d': $('#edit_jawaban_d').val(),
|
'jawaban_d': $('#edit_jawaban_d').val(),
|
||||||
'jawaban_e': $('#edit_jawaban_e').val(),
|
'jawaban_e': $('#edit_jawaban_e').val(),
|
||||||
'jawaban_benar': $('#edit_jawaban_benar').val(),
|
'is_reverse': $('#edit_is_reverse').val(),
|
||||||
}, function(data, status) {
|
}, function(data, status) {
|
||||||
if(data.status) {
|
if(data.status) {
|
||||||
$('#editModal').modal('hide');
|
$('#editModal').modal('hide');
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,16 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h5>Tabel Data</h5>
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h5>Data Users</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 d-flex justify-content-end">
|
||||||
|
<button class="btn btn-sm btn-info delete-btn rounded-circle mx-1" data-bs-toggle="modal" data-bs-target="#addModal">
|
||||||
|
<i class="ti ti-database-import"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table" id="table-data">
|
<table class="table" id="table-data">
|
||||||
|
|
@ -48,6 +57,45 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- [ Main Content ] end -->
|
<!-- [ Main Content ] end -->
|
||||||
|
|
||||||
|
<!-- Modal Add -->
|
||||||
|
<div class="modal fade" id="addModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="exampleModalLabel">Add Data</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 my-1">
|
||||||
|
<label for="add_nama_user" class="form-label">Nama User</label>
|
||||||
|
<input type="text" class="form-control" id="add_nama_user" name="add_nama_user">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 my-1">
|
||||||
|
<label for="add_email" class="form-label">Email</label>
|
||||||
|
<input type="text" class="form-control" id="add_email" name="add_email">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 my-1">
|
||||||
|
<label for="add_alamat" class="form-label">Alamat</label>
|
||||||
|
<input type="text" class="form-control" id="add_alamat" name="add_alamat">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 my-1">
|
||||||
|
<label for="add_role" class="form-label">Role</label>
|
||||||
|
<select class="form-select" name="add_role" id="add_role">
|
||||||
|
<option value="admin">Admin</option>
|
||||||
|
<option value="psikolog">Psikolog</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Batal</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="simpanAddData()">Simpan</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Modal Edit -->
|
<!-- Modal Edit -->
|
||||||
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
|
|
@ -66,12 +114,15 @@
|
||||||
<label for="edit_email" class="form-label">Email</label>
|
<label for="edit_email" class="form-label">Email</label>
|
||||||
<input type="text" class="form-control" id="edit_email" name="edit_email">
|
<input type="text" class="form-control" id="edit_email" name="edit_email">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-6 my-1">
|
||||||
|
<label for="edit_alamat" class="form-label">Alamat</label>
|
||||||
|
<input type="text" class="form-control" id="edit_alamat" name="edit_alamat">
|
||||||
|
</div>
|
||||||
<div class="col-md-6 my-1">
|
<div class="col-md-6 my-1">
|
||||||
<label for="edit_role" class="form-label">Role</label>
|
<label for="edit_role" class="form-label">Role</label>
|
||||||
<select class="form-select" name="edit_role" id="edit_role">
|
<select class="form-select" name="edit_role" id="edit_role">
|
||||||
<option value="admin">Admin</option>
|
<option value="admin">Admin</option>
|
||||||
<option value="psikolog">Psikolog</option>
|
<option value="psikolog">Psikolog</option>
|
||||||
<option value="user">User</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -167,6 +218,7 @@ function getDataEdit(btn) {
|
||||||
$('#edit_nama_user').val(data.data.name);
|
$('#edit_nama_user').val(data.data.name);
|
||||||
$('#edit_email').val(data.data.email);
|
$('#edit_email').val(data.data.email);
|
||||||
$('#edit_role').val(data.data.role);
|
$('#edit_role').val(data.data.role);
|
||||||
|
$('#edit_alamat').val(data.data.alamat);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -181,6 +233,30 @@ function getDataHapus(btn) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function simpanAddData() {
|
||||||
|
$.post('{{ route('users.store') }}', {
|
||||||
|
'_token': document.getElementById('_token').getAttribute('value'),
|
||||||
|
'name': $('#add_nama_user').val(),
|
||||||
|
'email': $('#add_email').val(),
|
||||||
|
'role': $('#add_role').val(),
|
||||||
|
'alamat': $('#add_alamat').val()
|
||||||
|
}, function(data, status) {
|
||||||
|
if(data.status) {
|
||||||
|
$('#addModal').modal('hide');
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Data berhasil ditambahkan!",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
fetchRowData();
|
||||||
|
$('#add_nama_user').val('');
|
||||||
|
$('#add_email').val('');
|
||||||
|
$('#add_role').val('admin');
|
||||||
|
$('#add_alamat').val('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function simpanEditData() {
|
function simpanEditData() {
|
||||||
if(idEdit != null) {
|
if(idEdit != null) {
|
||||||
let urlUpdate = '{{ route('users.update', ['__ID__']) }}';
|
let urlUpdate = '{{ route('users.update', ['__ID__']) }}';
|
||||||
|
|
@ -189,13 +265,14 @@ function simpanEditData() {
|
||||||
'_method': 'PUT',
|
'_method': 'PUT',
|
||||||
'name': $('#edit_nama_user').val(),
|
'name': $('#edit_nama_user').val(),
|
||||||
'email': $('#edit_email').val(),
|
'email': $('#edit_email').val(),
|
||||||
'role': $('#edit_role').val()
|
'role': $('#edit_role').val(),
|
||||||
|
'alamat': $('#edit_alamat').val()
|
||||||
}, function(data, status) {
|
}, function(data, status) {
|
||||||
if(data.status) {
|
if(data.status) {
|
||||||
$('#editModal').modal('hide');
|
$('#editModal').modal('hide');
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: "Info",
|
title: "Info",
|
||||||
text: "Data berhasil ditambahkan!",
|
text: "Data berhasil diubah!",
|
||||||
icon: "success"
|
icon: "success"
|
||||||
});
|
});
|
||||||
fetchRowData();
|
fetchRowData();
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,169 @@
|
||||||
<x-guest-layout>
|
<!DOCTYPE html>
|
||||||
<div class="mb-4 text-sm text-gray-600 dark:text-gray-400">
|
<html lang="en">
|
||||||
{{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
|
<!-- [Head] start -->
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Lupa Password | {{ env('APP_NAME') }}</title>
|
||||||
|
<!-- [Meta] -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="description"
|
||||||
|
content="Mantis is made using Bootstrap 5 design framework. Download the free admin template & use it for your project.">
|
||||||
|
<meta name="keywords"
|
||||||
|
content="Mantis, Dashboard UI Kit, Bootstrap 5, Admin Template, Admin Dashboard, CRM, CMS, Bootstrap Admin Template">
|
||||||
|
<meta name="author" content="CodedThemes">
|
||||||
|
|
||||||
|
<!-- [Favicon] icon -->
|
||||||
|
<link rel="icon" href="{{ asset('assets/admin/assets/images/favicon.svg') }}" type="image/x-icon"> <!-- [Google Font] Family -->
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@300;400;500;600;700&display=swap"
|
||||||
|
id="main-font-link">
|
||||||
|
<!-- [Tabler Icons] https://tablericons.com -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/tabler-icons.min.css') }}">
|
||||||
|
<!-- [Feather Icons] https://feathericons.com -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/feather.css') }}">
|
||||||
|
<!-- [Font Awesome Icons] https://fontawesome.com/icons -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/fontawesome.css') }}">
|
||||||
|
<!-- [Material Icons] https://fonts.google.com/icons -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/material.css') }}">
|
||||||
|
<!-- [Template CSS Files] -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/css/style.css') }}" id="main-style-link">
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/css/style-preset.css') }}">
|
||||||
|
|
||||||
|
<meta id="_token" value="{{ csrf_token() }}">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<!-- [Head] end -->
|
||||||
|
<!-- [Body] Start -->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- [ Pre-loader ] start -->
|
||||||
|
<div class="loader-bg">
|
||||||
|
<div class="loader-track">
|
||||||
|
<div class="loader-fill"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Session Status -->
|
|
||||||
<x-auth-session-status class="mb-4" :status="session('status')" />
|
|
||||||
|
|
||||||
<form method="POST" action="{{ route('password.email') }}">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<!-- Email Address -->
|
|
||||||
<div>
|
|
||||||
<x-input-label for="email" :value="__('Email')" />
|
|
||||||
<x-text-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus />
|
|
||||||
<x-input-error :messages="$errors->get('email')" class="mt-2" />
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- [ Pre-loader ] End -->
|
||||||
|
|
||||||
<div class="flex items-center justify-end mt-4">
|
<div class="auth-main">
|
||||||
<x-primary-button>
|
<div class="auth-wrapper v3">
|
||||||
{{ __('Email Password Reset Link') }}
|
<div class="auth-form">
|
||||||
</x-primary-button>
|
<div class="auth-header">
|
||||||
|
<a href="{{ route('beranda.index') }}" class="fs-1 text-dark">{{ env('APP_NAME') }}</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<div class="card my-5">
|
||||||
</x-guest-layout>
|
<div class="card-body">
|
||||||
|
<div class="d-flex justify-content-between align-items-end mb-4">
|
||||||
|
<h3 class="mb-0"><b>Lupa Password</b></h3>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-3">
|
||||||
|
<p class="text-muted">Lupa password Anda? Masukkan email Anda dan kami akan mengirimkan link untuk mereset password.</p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-3">
|
||||||
|
<label class="form-label">Email Address</label>
|
||||||
|
<input type="email" id="email" class="form-control" placeholder="Email Address">
|
||||||
|
</div>
|
||||||
|
<div class="d-grid mt-4">
|
||||||
|
<button type="button" class="btn btn-primary" onclick="doForgotPassword()">Kirim Link Reset Password</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="auth-footer row">
|
||||||
|
<!-- <div class=""> -->
|
||||||
|
<div class="col my-1">
|
||||||
|
<p class="m-0">Copyright {{ date('Y') }} © <a href="https://polije.ac.id" target="_blank"> Politeknik Negeri Jember</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto my-1">
|
||||||
|
<ul class="list-inline footer-link mb-0">
|
||||||
|
<li class="list-inline-item"><a href="{{ route('beranda.index') }}">Beranda</a></li>
|
||||||
|
<li class="list-inline-item"><a href="{{ route('beranda.index') }}#footer">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- </div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- [ Main Content ] end -->
|
||||||
|
<!-- Required Js -->
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/popper.min.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/simplebar.min.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/bootstrap.min.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/fonts/custom-font.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/pcoded.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/feather.min.js') }}"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
<script>layout_change('light');</script>
|
||||||
|
<script>change_box_container('false');</script>
|
||||||
|
<script>layout_rtl_change('false');</script>
|
||||||
|
<script>preset_change("preset-1");</script>
|
||||||
|
<script>font_change("Public-Sans");</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function doForgotPassword() {
|
||||||
|
try {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Loading",
|
||||||
|
text: "Sedang memproses, tunggu sebentar yaa!",
|
||||||
|
icon: "info",
|
||||||
|
showConfirmButton: false,
|
||||||
|
allowOutsideClick: false
|
||||||
|
});
|
||||||
|
let token = document.getElementById('_token').getAttribute('value');
|
||||||
|
let email = document.getElementById('email').value;
|
||||||
|
|
||||||
|
if(email == '' || email == null) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Email tidak boleh kosong!",
|
||||||
|
icon: "warning"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let xhttp = new XMLHttpRequest();
|
||||||
|
let formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('_token', token);
|
||||||
|
formData.append('email', email);
|
||||||
|
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if(this.status == 200) {
|
||||||
|
let jsonData = JSON.parse(this.responseText);
|
||||||
|
if(jsonData.status) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Link reset password telah dikirim ke email Anda!",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Gagal mengirim link reset password, cek email Anda!",
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Gagal mengirim link reset password, koneksi ke server gagal, coba lagi nanti!",
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhttp.open('POST', '{{ route("password.email") }}', false);
|
||||||
|
xhttp.send(formData);
|
||||||
|
} catch(error) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Gagal mengirim link reset password, kesalahan pada server, coba lagi nanti!",
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
<!-- [Body] end -->
|
||||||
|
</html>
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<!-- [Head] start -->
|
<!-- [Head] start -->
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Login | Smart Anxiety</title>
|
<title>Login | {{ env('APP_NAME') }}</title>
|
||||||
<!-- [Meta] -->
|
<!-- [Meta] -->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
<div class="auth-wrapper v3">
|
<div class="auth-wrapper v3">
|
||||||
<div class="auth-form">
|
<div class="auth-form">
|
||||||
<div class="auth-header">
|
<div class="auth-header">
|
||||||
<a href="#"><img src="{{ asset('assets/admin/assets/images/logo-dark.svg') }}" alt="img"></a>
|
<a href="{{ route('beranda.index') }}" class="fs-1 text-dark">{{ env('APP_NAME') }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="card my-5">
|
<div class="card my-5">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
<input type="password" id="password" class="form-control" placeholder="Password">
|
<input type="password" id="password" class="form-control" placeholder="Password">
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex mt-1 justify-content-between">
|
<div class="d-flex mt-1 justify-content-between">
|
||||||
<h5 class="text-secondary f-w-400">Forgot Password?</h5>
|
<h5 class="text-secondary f-w-400"><a href="{{ route('password.request') }}">Forgot Password?</a></h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-grid mt-4">
|
<div class="d-grid mt-4">
|
||||||
<button type="button" class="btn btn-primary" onclick="doLogin()">Login</button>
|
<button type="button" class="btn btn-primary" onclick="doLogin()">Login</button>
|
||||||
|
|
@ -81,8 +81,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto my-1">
|
<div class="col-auto my-1">
|
||||||
<ul class="list-inline footer-link mb-0">
|
<ul class="list-inline footer-link mb-0">
|
||||||
<li class="list-inline-item"><a href="#">Beranda</a></li>
|
<li class="list-inline-item"><a href="{{ route('beranda.index') }}">Beranda</a></li>
|
||||||
<li class="list-inline-item"><a href="#">Contact us</a></li>
|
<li class="list-inline-item"><a href="{{ route('beranda.index') }}#footer">Contact us</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,198 @@
|
||||||
<x-guest-layout>
|
<!DOCTYPE html>
|
||||||
<form method="POST" action="{{ route('password.store') }}">
|
<html lang="en">
|
||||||
@csrf
|
<!-- [Head] start -->
|
||||||
|
|
||||||
<!-- Password Reset Token -->
|
<head>
|
||||||
<input type="hidden" name="token" value="{{ $request->route('token') }}">
|
<title>Reset Password | {{ env('APP_NAME') }}</title>
|
||||||
|
<!-- [Meta] -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="description"
|
||||||
|
content="Mantis is made using Bootstrap 5 design framework. Download the free admin template & use it for your project.">
|
||||||
|
<meta name="keywords"
|
||||||
|
content="Mantis, Dashboard UI Kit, Bootstrap 5, Admin Template, Admin Dashboard, CRM, CMS, Bootstrap Admin Template">
|
||||||
|
<meta name="author" content="CodedThemes">
|
||||||
|
|
||||||
<!-- Email Address -->
|
<!-- [Favicon] icon -->
|
||||||
<div>
|
<link rel="icon" href="{{ asset('assets/admin/assets/images/favicon.svg') }}" type="image/x-icon"> <!-- [Google Font] Family -->
|
||||||
<x-input-label for="email" :value="__('Email')" />
|
<link rel="stylesheet"
|
||||||
<x-text-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email', $request->email)" required autofocus autocomplete="username" />
|
href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@300;400;500;600;700&display=swap"
|
||||||
<x-input-error :messages="$errors->get('email')" class="mt-2" />
|
id="main-font-link">
|
||||||
|
<!-- [Tabler Icons] https://tablericons.com -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/tabler-icons.min.css') }}">
|
||||||
|
<!-- [Feather Icons] https://feathericons.com -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/feather.css') }}">
|
||||||
|
<!-- [Font Awesome Icons] https://fontawesome.com/icons -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/fontawesome.css') }}">
|
||||||
|
<!-- [Material Icons] https://fonts.google.com/icons -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/fonts/material.css') }}">
|
||||||
|
<!-- [Template CSS Files] -->
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/css/style.css') }}" id="main-style-link">
|
||||||
|
<link rel="stylesheet" href="{{ asset('assets/admin/assets/css/style-preset.css') }}">
|
||||||
|
|
||||||
|
<meta id="_token" value="{{ csrf_token() }}">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<!-- [Head] end -->
|
||||||
|
<!-- [Body] Start -->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- [ Pre-loader ] start -->
|
||||||
|
<div class="loader-bg">
|
||||||
|
<div class="loader-track">
|
||||||
|
<div class="loader-fill"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Password -->
|
|
||||||
<div class="mt-4">
|
|
||||||
<x-input-label for="password" :value="__('Password')" />
|
|
||||||
<x-text-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" />
|
|
||||||
<x-input-error :messages="$errors->get('password')" class="mt-2" />
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- [ Pre-loader ] End -->
|
||||||
|
|
||||||
<!-- Confirm Password -->
|
<div class="auth-main">
|
||||||
<div class="mt-4">
|
<div class="auth-wrapper v3">
|
||||||
<x-input-label for="password_confirmation" :value="__('Confirm Password')" />
|
<div class="auth-form">
|
||||||
|
<div class="auth-header">
|
||||||
<x-text-input id="password_confirmation" class="block mt-1 w-full"
|
<a href="{{ route('beranda.index') }}" class="fs-1 text-dark">{{ env('APP_NAME') }}</a>
|
||||||
type="password"
|
|
||||||
name="password_confirmation" required autocomplete="new-password" />
|
|
||||||
|
|
||||||
<x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" />
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card my-5">
|
||||||
<div class="flex items-center justify-end mt-4">
|
<div class="card-body">
|
||||||
<x-primary-button>
|
<div class="d-flex justify-content-between align-items-end mb-4">
|
||||||
{{ __('Reset Password') }}
|
<h3 class="mb-0"><b>Reset Password</b></h3>
|
||||||
</x-primary-button>
|
{{-- <a href="#" class="link-primary">Don't have an account?</a> --}}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<div class="form-group mb-3">
|
||||||
</x-guest-layout>
|
<label class="form-label">Email Address</label>
|
||||||
|
<input type="email" id="email" class="form-control" placeholder="Email Address" value="{{ request()->get('email') }}">
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-3">
|
||||||
|
<label class="form-label">Password</label>
|
||||||
|
<input type="password" id="password" class="form-control" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-3">
|
||||||
|
<label class="form-label">Confirm Password</label>
|
||||||
|
<input type="password" id="password_confirmation" class="form-control" placeholder="Confirm Password">
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="reset_token" value="{{ request()->route('token') }}">
|
||||||
|
<div class="d-flex mt-1 justify-content-between">
|
||||||
|
<h5 class="text-secondary f-w-400"><a href="{{ route('password.request') }}">Forgot Password?</a></h5>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid mt-4">
|
||||||
|
<button type="button" class="btn btn-primary" onclick="doResetPassword()">Reset Password</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="auth-footer row">
|
||||||
|
<!-- <div class=""> -->
|
||||||
|
<div class="col my-1">
|
||||||
|
<p class="m-0">Copyright {{ date('Y') }} © <a href="https://polije.ac.id" target="_blank"> Politeknik Negeri Jember</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto my-1">
|
||||||
|
<ul class="list-inline footer-link mb-0">
|
||||||
|
<li class="list-inline-item"><a href="{{ route('beranda.index') }}">Beranda</a></li>
|
||||||
|
<li class="list-inline-item"><a href="{{ route('beranda.index') }}#footer">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- </div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- [ Main Content ] end -->
|
||||||
|
<!-- Required Js -->
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/popper.min.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/simplebar.min.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/bootstrap.min.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/fonts/custom-font.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/pcoded.js') }}"></script>
|
||||||
|
<script src="{{ asset('assets/admin/assets/js/plugins/feather.min.js') }}"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
<script>layout_change('light');</script>
|
||||||
|
<script>change_box_container('false');</script>
|
||||||
|
<script>layout_rtl_change('false');</script>
|
||||||
|
<script>preset_change("preset-1");</script>
|
||||||
|
<script>font_change("Public-Sans");</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function doResetPassword() {
|
||||||
|
try {
|
||||||
|
let csrfToken = document.getElementById('_token').getAttribute('value');
|
||||||
|
let resetToken = document.getElementById('reset_token').value;
|
||||||
|
let email = document.getElementById('email').value;
|
||||||
|
let password = document.getElementById('password').value;
|
||||||
|
let password_confirmation = document.getElementById('password_confirmation').value;
|
||||||
|
|
||||||
|
if(email == '' || email == null) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Email tidak boleh kosong!",
|
||||||
|
icon: "warning"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(password == '' || password == null) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Password tidak boleh kosong!",
|
||||||
|
icon: "warning"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(password !== password_confirmation) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Password dan konfirmasi password tidak cocok!",
|
||||||
|
icon: "warning"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let xhttp = new XMLHttpRequest();
|
||||||
|
let formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('_token', csrfToken);
|
||||||
|
formData.append('token', resetToken);
|
||||||
|
formData.append('email', email);
|
||||||
|
formData.append('password', password);
|
||||||
|
formData.append('password_confirmation', password_confirmation);
|
||||||
|
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if(this.status == 200) {
|
||||||
|
let jsonData = JSON.parse(this.responseText);
|
||||||
|
if(jsonData.status) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Password berhasil direset!",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
window.location.href = '{{ route('login') }}';
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Terdapat kesalahan!",
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Reset password gagal, koneksi ke server gagal, coba lagi nanti!",
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhttp.open('POST', '{{ route("password.store") }}', false);
|
||||||
|
xhttp.send(formData);
|
||||||
|
} catch(error) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Info",
|
||||||
|
text: "Reset password gagal, kesalahan pada server, coba lagi nanti!",
|
||||||
|
icon: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
<!-- [Body] end -->
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -198,9 +198,22 @@ function searchUserStatus() {
|
||||||
$('#result_test_form').show();
|
$('#result_test_form').show();
|
||||||
}
|
}
|
||||||
} else if(response.status_data == 2) {
|
} else if(response.status_data == 2) {
|
||||||
|
let test_session = getTestSession(response.id_booking);
|
||||||
|
|
||||||
$('#alert_status').removeClass();
|
$('#alert_status').removeClass();
|
||||||
$('#alert_status').addClass('alert alert-success');
|
$('#alert_status').addClass('alert alert-success');
|
||||||
$('#alert_status').html('Kamu sudah melakukan tes, dan bisa cek hasil dengan tombol dibawah');
|
$('#alert_status').html('Kamu sudah melakukan tes, dan bisa cek hasil dengan tombol dibawah');
|
||||||
|
|
||||||
|
$('#result_test_status').html('Selesai');
|
||||||
|
$('#result_test_status').removeClass();
|
||||||
|
$('#result_test_status').addClass('fw-bold text-white bg-success p-2 rounded-pill');
|
||||||
|
let test_url = '{{ route('hasil-tes.index', ['id_test_sessions' => '__ID_TEST_SESSIONS__']) }}';
|
||||||
|
$('#result_test_form').hide();
|
||||||
|
$('#result_test_link').show();
|
||||||
|
$('#result_test_link').html('Tes Sudah Selesai, Klik untuk melihat hasil');
|
||||||
|
$('#result_test_link').attr('href', test_url.replace('__ID_TEST_SESSIONS__', test_session.id_test_sessions));
|
||||||
|
|
||||||
|
$('#result_test').show();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,23 @@
|
||||||
@section('title', 'Hasil Tes')
|
@section('title', 'Hasil Tes')
|
||||||
@extends('user.layouts.index')
|
@extends('user.layouts.index')
|
||||||
@section('content')
|
@section('content')
|
||||||
|
<style>
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-custom {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<!-- Page Title -->
|
<!-- Page Title -->
|
||||||
<div class="page-title">
|
<div class="page-title">
|
||||||
<div class="heading">
|
<div class="heading">
|
||||||
|
|
@ -18,7 +35,7 @@
|
||||||
<nav class="breadcrumbs">
|
<nav class="breadcrumbs">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="index.html">Home</a></li>
|
<li><a href="{{ route('beranda.index') }}">Home</a></li>
|
||||||
<li class="current">Hasil Tes</li>
|
<li class="current">Hasil Tes</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -27,32 +44,303 @@
|
||||||
|
|
||||||
<!-- About Section -->
|
<!-- About Section -->
|
||||||
<section id="about" class="about section">
|
<section id="about" class="about section">
|
||||||
<div class="container" data-aos="fade-up" data-aos-delay="100">
|
<div class="container mt-5">
|
||||||
|
<h1 class="text-center mb-4">
|
||||||
|
Prediksi & Analisis Kecemasan
|
||||||
|
</h1>
|
||||||
|
<div class="row g-4">
|
||||||
|
<!-- STAI Score -->
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card h-100 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h4 class="card-title">
|
||||||
|
Skor STAI-T
|
||||||
|
</h4>
|
||||||
|
<h2 class="mt-4">
|
||||||
|
{{ $data_aswered['totalScore'] }}
|
||||||
|
</h2>
|
||||||
|
<p class="text-muted">
|
||||||
|
Hasil dari kuesioner kecemasan
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-clipboard2-pulse fs-3"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Anxiety Level -->
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card h-100 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h4 class="card-title">
|
||||||
|
Tingkat Kecemasan
|
||||||
|
</h4>
|
||||||
|
@if ($data_aswered['totalScore'] <= 37)
|
||||||
|
<h2 class="mt-4 text-success">
|
||||||
|
Normal
|
||||||
|
</h2>
|
||||||
|
@elseif ($data_aswered['totalScore'] <= 44)
|
||||||
|
<h2 class="mt-4 text-warning">
|
||||||
|
Sedang
|
||||||
|
</h2>
|
||||||
|
@elseif ($data_aswered['totalScore'] <= 80)
|
||||||
|
<h2 class="mt-4 text-danger">
|
||||||
|
Tinggi
|
||||||
|
</h2>
|
||||||
|
@endif
|
||||||
|
<p class="text-muted">
|
||||||
|
Berdasarkan skor <a href="https://headway.co/resources/state-trait-anxiety-inventory-scoring" target="_blank"><i>STAI-T</i></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-emoji-neutral fs-3"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- AI Prediction -->
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card h-100 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h4 class="card-title">
|
||||||
|
Prediksi AI
|
||||||
|
</h4>
|
||||||
|
<h2 class="mt-4" id="result-model">
|
||||||
|
Loading...
|
||||||
|
</h2>
|
||||||
|
<p class="text-muted">
|
||||||
|
Model Confidence: <span id="confidence-model"></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-cpu fs-3"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2 class="title text-center">Detail Tes/Ujian kamu</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Informasi Pribadi</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-person-vcard fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li><strong>Kode Booking:</strong> {{ $data_information['kode'] }}</li>
|
||||||
|
<li><strong>Nama:</strong> {{ $data_information['nama'] }}</li>
|
||||||
|
<li><strong>Email:</strong> {{ $data_information['email'] }}</li>
|
||||||
|
<li><strong>Nomor Handphone:</strong> {{ $data_information['no_hp'] }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Informasi Ujian</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-clipboard fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li><strong>Durasi Ujian:</strong> {{ $difference }}</li>
|
||||||
|
<li><strong>Resolusi Layar (saat ujian):</strong> {{ $screen_dim['width'] }} x {{ $screen_dim['height'] }}</li>
|
||||||
|
<li><strong>Jumlah Pergerakan Mata:</strong> <span id="total_movement">0</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Hasil Ujian (STAI-T)</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-easel fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li><strong>Jumlah Soal:</strong> {{ $data_aswered['total_question'] }}</li>
|
||||||
|
<li><strong>Soal terjawab:</strong> {{ $data_aswered['answered'] }}</li>
|
||||||
|
<li><strong>Soal tidak terjawab:</strong> {{ $data_aswered['unanswered'] }}</li>
|
||||||
|
<li><strong>Total Skor:</strong> {{ $data_aswered['totalScore'] }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Detail Confidence Prediksi Model</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-easel fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li><strong>Normal:</strong> <span id="normal-confidence">0%</span></li>
|
||||||
|
<li><strong>Sedang:</strong> <span id="sedang-confidence"></span></li>
|
||||||
|
<li><strong>Tinggi:</strong> <span id="tinggi-confidence"></span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Avg Velocity</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-speedometer2 fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4 id="avgVelocity"></h4>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="btn btn-link p-0" onclick="showInsight('velocity')"><i class="bi bi-info-circle"></i> Lihat Insight</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Fixation Ratio</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-bullseye fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4 id="fixationRatio"></h4>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="btn btn-link p-0" onclick="showInsight('fixation')"><i class="bi bi-info-circle"></i> Lihat Insight</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Total Eye Distance</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-arrows-fullscreen fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4 id="totalDistance"></h4>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="btn btn-link p-0" onclick="showInsight('distance')"><i class="bi bi-info-circle"></i> Lihat Insight</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="bg-custom p-4 my-3 border rounded">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<h5 class="text-body">Most Viewed Area</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 d-flex justify-content-center align-items-center bg-primary-subtle border border primary rounded-circle" style="aspect-ratio: 1/1;">
|
||||||
|
<i class="bi bi-geo-alt fs-4"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4 id="mostViewedArea"></h4>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="btn btn-link p-0" onclick="showInsight('area')"><i class="bi bi-info-circle"></i> Lihat Insight</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container mt-5" data-aos="fade-up" data-aos-delay="100">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h2 class="title text-center">Tabel soal yang telah dijawab</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12 mt-2">
|
||||||
<table class="table" id="table-data-hasil-ujian">
|
<table class="table" id="table-data-hasil-ujian">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>No</th>
|
<th>No</th>
|
||||||
<th>Pertanyaan</th>
|
<th>Pertanyaan</th>
|
||||||
<th>Jawaban</th>
|
<th>Jawaban</th>
|
||||||
|
<th>Skor</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody></tbody>
|
<tbody></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="col-lg-12">
|
||||||
|
<h2 class="title text-center">Tabel soal yang tidak dijawab</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12 mt-2">
|
||||||
|
<table class="table" id="table-data-soal-not-answer">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>No</th>
|
||||||
|
<th>Pertanyaan</th>
|
||||||
|
<th>Jawaban</th>
|
||||||
|
<th>Skor</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mt-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h2 class="title">Grafik Kecepatan Mata</h2>
|
<h2 class="title text-center">Grafik Kecepatan Mata</h2>
|
||||||
<canvas id="velocityChart"></canvas>
|
<canvas id="velocityChart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-12 mt-5">
|
<div class="col-lg-12 mt-5">
|
||||||
<h2 class="title">Heatmap Pergerakan Mata</h2>
|
<h2 class="title text-center">Heatmap Pergerakan Mata</h2>
|
||||||
<div style="position: relative; aspect-ratio: 16/9;">
|
<div style="position: relative; aspect-ratio: 16/9;">
|
||||||
<img src="{{ asset('assets/users/assets/img/overlay/overlay.png') }}" style="width:100%; height:100%; object-fit: cover;">
|
<img src="{{ asset('assets/users/assets/img/overlay/overlay.png') }}" style="width:100%; height:100%; object-fit: cover; position: absolute;">
|
||||||
<div id="heatmapChart" style="aspect-ratio: 16/9;"></div>
|
<div id="heatmapChart" style="aspect-ratio: 16/9;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-12 mt-5">
|
||||||
|
<h2 class="title text-center">Heatmap Pergerakan Mata (Grid)</h2>
|
||||||
|
<div style="position: relative; aspect-ratio: 16/9;">
|
||||||
|
<img src="{{ asset('assets/users/assets/img/overlay/overlay_grid.png') }}" style="width:100%; height:100%; object-fit: cover; position: absolute;">
|
||||||
|
<div id="heatmapChartGrid" style="aspect-ratio: 16/9;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section><!-- /About Section -->
|
</section><!-- /About Section -->
|
||||||
|
|
@ -82,9 +370,14 @@
|
||||||
let recordedScreenWidth = null
|
let recordedScreenWidth = null
|
||||||
let recordedScreenHeight = null
|
let recordedScreenHeight = null
|
||||||
let mappedHeatmapData = null;
|
let mappedHeatmapData = null;
|
||||||
|
let mappedHeatmapDataGrid = null;
|
||||||
let scaleX = null;
|
let scaleX = null;
|
||||||
let scaleY = null;
|
let scaleY = null;
|
||||||
let heatmapInstance = null;
|
let heatmapInstance = null;
|
||||||
|
let heatmapInstanceGrid = null;
|
||||||
|
let score = null;
|
||||||
|
let totalScore = null;
|
||||||
|
let soalTerjawab = 0;
|
||||||
|
|
||||||
function renderVelocityChart(timeseries) {
|
function renderVelocityChart(timeseries) {
|
||||||
const base = timeseries.timestamp[0];
|
const base = timeseries.timestamp[0];
|
||||||
|
|
@ -143,10 +436,136 @@ function renderVelocityChart(timeseries) {
|
||||||
max: 10,
|
max: 10,
|
||||||
data: mappedHeatmapData
|
data: mappedHeatmapData
|
||||||
});
|
});
|
||||||
|
mappedHeatmapDataGrid = result.heatmap.map(point => ({
|
||||||
|
x: point.x * scaleX,
|
||||||
|
y: point.y * scaleY,
|
||||||
|
value: point.value
|
||||||
|
}));
|
||||||
|
heatmapInstanceGrid.setData({
|
||||||
|
max: 10,
|
||||||
|
data: mappedHeatmapDataGrid
|
||||||
|
});
|
||||||
heatmapContainer.style.removeProperty('position');
|
heatmapContainer.style.removeProperty('position');
|
||||||
|
renderStats(result.statistics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getPredict(data) {
|
||||||
|
const res = await fetch("{{ env('PYTHON_API_URL') }}/predict", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await res.json();
|
||||||
|
if(result != null) {
|
||||||
|
let classBg = ['text-success', 'text-warning', 'text-danger'];
|
||||||
|
let textResult = ['Normal', 'Sedang', 'Tinggi'];
|
||||||
|
$('#result-model').addClass(classBg[result.hasil_prediksi]);
|
||||||
|
$('#result-model').html(textResult[result.hasil_prediksi]);
|
||||||
|
$('#confidence-model').html(result.confidence + '%');
|
||||||
|
$('#normal-confidence').html(result.detail_probabilitas.normal + "%");
|
||||||
|
$('#sedang-confidence').html(result.detail_probabilitas.sedang + "%");
|
||||||
|
$('#tinggi-confidence').html(result.detail_probabilitas.tinggi + "%");
|
||||||
|
Swal.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderStats(stats) {
|
||||||
|
document.getElementById("avgVelocity")
|
||||||
|
.innerText = stats.avg_velocity.toFixed(4);
|
||||||
|
|
||||||
|
document.getElementById("fixationRatio")
|
||||||
|
.innerText = stats.fixation_ratio.toFixed(2) + "%";
|
||||||
|
|
||||||
|
document.getElementById("totalDistance")
|
||||||
|
.innerText = stats.total_distance.toFixed(2);
|
||||||
|
|
||||||
|
document.getElementById("mostViewedArea")
|
||||||
|
.innerText = stats.most_viewed_area;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showInsight(type) {
|
||||||
|
let title = null;
|
||||||
|
let html = null;
|
||||||
|
|
||||||
|
if(type === "velocity") {
|
||||||
|
title = "Avg Velocity";
|
||||||
|
html = `
|
||||||
|
<p>
|
||||||
|
Rata-rata kecepatan gerakan mata selama ujian.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<b>Nilai tinggi:</b>
|
||||||
|
<p>
|
||||||
|
Mata aktif berpindah area,
|
||||||
|
Aktivitas visual tinggi
|
||||||
|
</p>
|
||||||
|
<b>Nilai rendah:</b>
|
||||||
|
<p>
|
||||||
|
Fokus lebih stabil,
|
||||||
|
Gerakan mata lebih tenang
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
} else if(type === "fixation") {
|
||||||
|
title = "Fixation Ratio";
|
||||||
|
|
||||||
|
html = `
|
||||||
|
<p>
|
||||||
|
Persentase waktu mata berada pada area tertentu.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<b>Semakin tinggi:</b>
|
||||||
|
<p>
|
||||||
|
Fokus lebih lama pada suatu area,
|
||||||
|
Perhatian lebih stabil
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(type === "distance") {
|
||||||
|
title = "Total Eye Distance";
|
||||||
|
html = `
|
||||||
|
<p>
|
||||||
|
Total jarak perpindahan mata selama ujian.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<b>Nilai besar:</b>
|
||||||
|
<p>
|
||||||
|
Mata banyak menjelajah layar,
|
||||||
|
Aktivitas visual tinggi
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(type === "area") {
|
||||||
|
title = "Most Viewed Area";
|
||||||
|
html = `
|
||||||
|
<p>
|
||||||
|
Area layar yang paling sering dilihat selama ujian.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<b>Insight:</b>
|
||||||
|
<p>
|
||||||
|
Menunjukkan fokus utama pengguna,
|
||||||
|
Dapat membantu memahami pola perhatian
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
title = "Huh?";
|
||||||
|
html = `<h1>Hello There :D</h1>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: title,
|
||||||
|
html: html,
|
||||||
|
icon: 'info',
|
||||||
|
showConfirmButton: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
table = new DataTable("#table-data-hasil-ujian", {
|
table = new DataTable("#table-data-hasil-ujian", {
|
||||||
searching: false,
|
searching: false,
|
||||||
|
|
@ -169,21 +588,71 @@ function renderVelocityChart(timeseries) {
|
||||||
data: null,
|
data: null,
|
||||||
render: function(data, type, row) {
|
render: function(data, type, row) {
|
||||||
let renderedJawaban = null;
|
let renderedJawaban = null;
|
||||||
|
|
||||||
if(row.jawaban_key == 'a') {
|
if(row.jawaban_key == 'a') {
|
||||||
renderedJawaban = `<span class="badge text-bg-primary">${row.jawaban}</span>`;
|
if(row.is_reverse == 1) {
|
||||||
} else if(row.jawaban_key == 'b') {
|
|
||||||
renderedJawaban = `<span class="badge" style="background-color: #fc7938; color: white;">${row.jawaban}</span>`;
|
|
||||||
} else if(row.jawaban_key == 'c') {
|
|
||||||
renderedJawaban = `<span class="badge text-bg-danger">${row.jawaban}</span>`;
|
renderedJawaban = `<span class="badge text-bg-danger">${row.jawaban}</span>`;
|
||||||
} else if(row.jawaban_key == 'd') {
|
} else {
|
||||||
|
renderedJawaban = `<span class="badge text-bg-primary">${row.jawaban}</span>`;
|
||||||
|
}
|
||||||
|
} else if(row.jawaban_key == 'b') {
|
||||||
|
if(row.is_reverse == 1) {
|
||||||
renderedJawaban = `<span class="badge text-bg-warning">${row.jawaban}</span>`;
|
renderedJawaban = `<span class="badge text-bg-warning">${row.jawaban}</span>`;
|
||||||
|
} else {
|
||||||
|
renderedJawaban = `<span class="badge" style="background-color: #fc7938; color: white;">${row.jawaban}</span>`;
|
||||||
|
}
|
||||||
|
} else if(row.jawaban_key == 'c') {
|
||||||
|
if(row.is_reverse == 1) {
|
||||||
|
renderedJawaban = `<span class="badge" style="background-color: #fc7938; color: white;">${row.jawaban}</span>`;
|
||||||
|
} else {
|
||||||
|
renderedJawaban = `<span class="badge text-bg-warning">${row.jawaban}</span>`;
|
||||||
|
}
|
||||||
|
} else if(row.jawaban_key == 'd') {
|
||||||
|
if(row.is_reverse == 1) {
|
||||||
|
renderedJawaban = `<span class="badge text-bg-primary">${row.jawaban}</span>`;
|
||||||
|
} else {
|
||||||
|
renderedJawaban = `<span class="badge text-bg-danger">${row.jawaban}</span>`;
|
||||||
|
}
|
||||||
} else if(row.jawaban_key == 'e') {
|
} else if(row.jawaban_key == 'e') {
|
||||||
renderedJawaban = `<span class="badge text-bg-success">${row.jawaban}</span>`;
|
renderedJawaban = `<span class="badge text-bg-success">${row.jawaban}</span>`;
|
||||||
|
score = 5;
|
||||||
} else {
|
} else {
|
||||||
renderedJawaban = `<span class="badge text-bg-secondary">${row.jawaban}</span>`;
|
renderedJawaban = `<span class="badge text-bg-secondary">${row.jawaban}</span>`;
|
||||||
}
|
}
|
||||||
return renderedJawaban;
|
return renderedJawaban;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'skor',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
table = new DataTable("#table-data-soal-not-answer", {
|
||||||
|
searching: false,
|
||||||
|
paging: false,
|
||||||
|
ajax: {
|
||||||
|
url: '{{ route('hasil-tes.getNotAnswered', ['id_test_sessions' => $id_session]) }}',
|
||||||
|
dataSrc: 'data' // Specify the key containing the data array
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
data: null,
|
||||||
|
render: function(data, type, row, meta) {
|
||||||
|
return meta.row + 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'soal'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: null,
|
||||||
|
render: function(data, type, row, meta) {
|
||||||
|
return `<span class="badge text-bg-secondary">Tidak dijawab</span>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'skor'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
@ -206,31 +675,45 @@ function renderVelocityChart(timeseries) {
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
|
// console.log(data);
|
||||||
if(data.type === 'json_file_data') {
|
if(data.type === 'json_file_data') {
|
||||||
if(data.data != null) {
|
if(data.data != null) {
|
||||||
data_tobii = data.data;
|
data_tobii = null;
|
||||||
let xhttp = new XMLHttpRequest();
|
let xhttp = new XMLHttpRequest();
|
||||||
|
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
if(this.readyState == 4 && this.status == 200) {
|
if(this.readyState == 4 && this.status == 200) {
|
||||||
let data = JSON.parse(this.responseText);
|
let data_ = JSON.parse(this.responseText);
|
||||||
if(data.status) {
|
$('#total_movement').html(data.data.length + " (1 detik = 3 pergerakan)");
|
||||||
|
if(data_.status) {
|
||||||
heatmapContainer = document.getElementById('heatmapChart');
|
heatmapContainer = document.getElementById('heatmapChart');
|
||||||
clientWidth = heatmapContainer.clientWidth;
|
clientWidth = heatmapContainer.clientWidth;
|
||||||
clientHeight = heatmapContainer.clientHeight;
|
clientHeight = heatmapContainer.clientHeight;
|
||||||
recordedScreenWidth = data.screen_w;
|
recordedScreenWidth = data_.screen_w;
|
||||||
recordedScreenHeight = data.screen_h;
|
recordedScreenHeight = data_.screen_h;
|
||||||
scaleX = clientWidth / recordedScreenWidth;
|
scaleX = clientWidth / recordedScreenWidth;
|
||||||
scaleY = clientHeight / recordedScreenHeight;
|
scaleY = clientHeight / recordedScreenHeight;
|
||||||
|
|
||||||
|
data_tobii = {
|
||||||
|
data: data.data,
|
||||||
|
screen_w: recordedScreenWidth,
|
||||||
|
screen_h: recordedScreenHeight
|
||||||
|
};
|
||||||
|
|
||||||
heatmapInstance = h337.create({
|
heatmapInstance = h337.create({
|
||||||
container: heatmapContainer,
|
container: heatmapContainer,
|
||||||
radius: 40,
|
radius: 40,
|
||||||
maxOpacity: 0.6,
|
maxOpacity: 0.6,
|
||||||
blur: 0.85
|
blur: 0.85
|
||||||
});
|
});
|
||||||
Swal.close();
|
heatmapInstanceGrid = h337.create({
|
||||||
|
container: document.getElementById('heatmapChartGrid'),
|
||||||
|
radius: 40,
|
||||||
|
maxOpacity: 0.6,
|
||||||
|
blur: 0.85
|
||||||
|
});
|
||||||
loadData(data_tobii);
|
loadData(data_tobii);
|
||||||
|
getPredict(data_tobii.data);
|
||||||
} else {
|
} else {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
|
|
@ -244,8 +727,17 @@ function renderVelocityChart(timeseries) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
xhttp.open('GET', '{{ route('test-sessions.getScreen', ['id_test_sessions', $id_session]) }}', true);
|
xhttp.open('GET', '{{ route('test-sessions.getScreen', ['id_test_sessions' => $id_session]) }}', true);
|
||||||
xhttp.send();
|
xhttp.send();
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Error',
|
||||||
|
text: 'Gagal memuat data mata, silahkan coba lagi nanti',
|
||||||
|
icon: 'error',
|
||||||
|
showConfirmButton: true,
|
||||||
|
allowOutsideClick: false,
|
||||||
|
allowEscapeKey: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@
|
||||||
<div class="row justify-content-center flex-column p-4">
|
<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 border-bottom fs-4 fw-bold p-2">Soal</div>
|
||||||
<div class="col-md-12 p-2 d-none" id="id_question" style="text-align: justify"></div>
|
<div class="col-md-12 p-2 d-none" id="id_question" style="text-align: justify"></div>
|
||||||
<div class="col-md-12 p-2" id="text_question" style="text-align: justify"></div>
|
<div class="col-md-12 p-2 fs-1 text-muted" id="text_question" style="text-align: justify"></div>
|
||||||
<div class="col-md-12" id="answer_field">
|
<div class="col-md-12 fs-1 text-muted" id="answer_field">
|
||||||
<div class="fs-4 fw-bold p-2">Jawaban:</div>
|
<div class="fs-4 fw-bold p-2">Jawaban:</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -300,6 +300,7 @@ function finishExam() {
|
||||||
ws.send(JSON.stringify({
|
ws.send(JSON.stringify({
|
||||||
type: "command",
|
type: "command",
|
||||||
action: "stop",
|
action: "stop",
|
||||||
|
finish: true,
|
||||||
session_id: SESSION_ID
|
session_id: SESSION_ID
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
Route::resource('cek-status', CekStatusController::class)->only(['index', 'show']);
|
Route::resource('cek-status', CekStatusController::class)->only(['index', 'show']);
|
||||||
Route::resource('tutorial-tes', TutorialTesController::class)->only(['index']);
|
Route::resource('tutorial-tes', TutorialTesController::class)->only(['index']);
|
||||||
Route::resource('test-sessions', TestSessionsController::class)->only(['store', 'show']);
|
Route::resource('test-sessions', TestSessionsController::class)->only(['store', 'show']);
|
||||||
Route::get('test-sessions/get/screen', [TestSessionsController::class, 'getScreen'])->name('test-sessions.getScreen');;
|
Route::get('test-sessions/get/screen', [TestSessionsController::class, 'getScreen'])->name('test-sessions.getScreen');
|
||||||
Route::resource('tobii-receiver', TobiiReceiverController::class)->only(['store', 'show']);
|
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::get('tobii-receiver/fetch/data/{id_test_sessions}', [TobiiReceiverController::class, 'fetchDataTobii'])->name('tobii-receiver.fetchData');
|
||||||
Route::resource('ujian', HalamanUjianController::class);
|
Route::resource('ujian', HalamanUjianController::class);
|
||||||
|
|
@ -46,8 +46,11 @@
|
||||||
Route::get('ujian/fetch/navigation-field', [HalamanUjianController::class, 'getNavigationField'])->name('ujian.navigationField');
|
Route::get('ujian/fetch/navigation-field', [HalamanUjianController::class, 'getNavigationField'])->name('ujian.navigationField');
|
||||||
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::get('hasil-tes/get/all-not-answer', [FinishUjianController::class, 'getNotAnswered'])->name('hasil-tes.getNotAnswered');
|
||||||
Route::middleware(['auth', 'role.auth'])->group(function() {
|
Route::middleware(['auth', 'role.auth'])->group(function() {
|
||||||
Route::resource('dashboard', DashboardController::class);
|
Route::resource('dashboard', DashboardController::class);
|
||||||
|
Route::get('dashboard/fetch/data', [DashboardController::class, 'getDataDashboard'])->name('dashboard.fetchData');
|
||||||
|
Route::get('dashboard/fetch/data-table', [DashboardController::class, 'getDataForDashboardTable'])->name('dashboard.fetchDataTable');
|
||||||
Route::resource('users', UsersController::class);
|
Route::resource('users', UsersController::class);
|
||||||
Route::get('users/fetch/data', [UsersController::class, 'getData'])->name('users.fetchData');
|
Route::get('users/fetch/data', [UsersController::class, 'getData'])->name('users.fetchData');
|
||||||
Route::resource('booking', BookingController::class)->except(['store']);
|
Route::resource('booking', BookingController::class)->except(['store']);
|
||||||
|
|
@ -55,6 +58,7 @@
|
||||||
Route::resource('soal', DataSoalController::class);
|
Route::resource('soal', DataSoalController::class);
|
||||||
Route::get('soal/fetch/data', [DataSoalController::class, 'getData'])->name('soal.fetchData');
|
Route::get('soal/fetch/data', [DataSoalController::class, 'getData'])->name('soal.fetchData');
|
||||||
Route::resource('hasil_tes', HasilTesController::class);
|
Route::resource('hasil_tes', HasilTesController::class);
|
||||||
|
Route::get('hasil_tes/fetch/data', [HasilTesController::class, 'fetchData'])->name('hasil-tes.fetchData');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::get('email/test', function(Request $req) {
|
Route::get('email/test', function(Request $req) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue