done -> next review pengembangan gizi
This commit is contained in:
parent
cf29cd2695
commit
258ba46cb7
@ -399,6 +399,7 @@ class CustomerController extends Controller
|
||||
session()->flash('no_order', $noOrder);
|
||||
return response([
|
||||
'status' => true,
|
||||
'no_order' => $noOrder,
|
||||
'message' => 'Terima kasih atas pesanan Anda. Mohon tunggu, kami sedang memprosesnya'
|
||||
], 200);
|
||||
return back()->with('success', 'Bukti pembayaran berhasil diunggah.');
|
||||
|
||||
178
app/Http/Controllers/SurveyController.php
Normal file
178
app/Http/Controllers/SurveyController.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Survey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Arr;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
|
||||
class SurveyController extends Controller
|
||||
{
|
||||
public function index(Request $request){
|
||||
if(!session()->has('payment_success')){
|
||||
return redirect('/');
|
||||
}
|
||||
$no_order = $request->query('no_order');
|
||||
$type = $request->query('type');
|
||||
$data = [
|
||||
'title' => 'Survey Gizi',
|
||||
'mcu' => false,
|
||||
'no_order' => $no_order,
|
||||
'type' => $type
|
||||
];
|
||||
return view('guest.survey.index', $data);
|
||||
}
|
||||
|
||||
public function store(){
|
||||
DB::connection('dbOrderGizi')->beginTransaction();
|
||||
try {
|
||||
$payload =[
|
||||
'no_order' => request('no_order'),
|
||||
'type' => request('type'),
|
||||
'keterangan' => request('kritik_saran'),
|
||||
'kepuasan' => request('kepuasan'),
|
||||
'created_at' => now()
|
||||
];
|
||||
Survey::create($payload);
|
||||
DB::connection('dbOrderGizi')->commit();
|
||||
session()->flash('payment_success', true);
|
||||
session()->flash('no_order', $payload['no_order']);
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'Survei berhasil disimpan'
|
||||
]);
|
||||
} catch (\Throwable $th) {
|
||||
DB::connection('dbOrderGizi')->rollBack();
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Data gagal disimpan ' . $th->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function datatable(){
|
||||
$data = Survey::query();
|
||||
$tanggal = request('tanggal');
|
||||
if(!empty($tanggal)){
|
||||
$flattened = is_array($tanggal[0]) ? Arr::flatten($tanggal) : $tanggal;
|
||||
$data->whereIn(DB::raw('DATE(created_at)'), $flattened);
|
||||
}else{
|
||||
$now = Carbon::now()->format('Y-m-d');
|
||||
$data->whereDate('created_at', $now);
|
||||
}
|
||||
$data = $data->get();
|
||||
return response()->json([
|
||||
'rows' => $data->values(),
|
||||
'total' => $data->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function chartDataSurvey(Request $request)
|
||||
{
|
||||
$tanggal = $request->query('tanggal');
|
||||
if(is_string($tanggal)) $tanggal = json_decode($tanggal, true);
|
||||
|
||||
$query = Survey::query();
|
||||
if (!empty($tanggal) && is_array($tanggal)) {
|
||||
$query->whereIn(DB::raw('DATE(created_at)'), $tanggal);
|
||||
} else {
|
||||
$query->whereDate('created_at', Carbon::today());
|
||||
}
|
||||
|
||||
$allData = $query->get();
|
||||
|
||||
// Pisahkan data untuk perhitungan Card
|
||||
$dataBaru = $allData->where('type', 'pengguna_baru');
|
||||
$dataLama = $allData->where('type', 'pelanggan_setia');
|
||||
|
||||
return response()->json([
|
||||
'responden' => [
|
||||
'baru' => $dataBaru->count(),
|
||||
'lama' => $dataLama->count(),
|
||||
],
|
||||
'kepuasan_baru' => [
|
||||
'total' => $dataBaru->count(),
|
||||
'puas' => $dataBaru->where('kepuasan', 'Puas')->count(),
|
||||
'tidak_puas' => $dataBaru->where('kepuasan', 'Tidak Puas')->count(),
|
||||
],
|
||||
'kepuasan_lama' => [
|
||||
'total' => $dataLama->count(),
|
||||
'puas' => $dataLama->where('kepuasan', 'Puas')->count(),
|
||||
'tidak_puas' => $dataLama->where('kepuasan', 'Tidak Puas')->count(),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function dashboardSurvey(){
|
||||
$data = [
|
||||
'title' => 'List Survey Order Gizi'
|
||||
];
|
||||
return view('dashboard.survey.index', $data);
|
||||
}
|
||||
|
||||
public function exportSurveyExcel(){
|
||||
$startDate = Carbon::parse(request('start_date'))->startOfDay();
|
||||
$endDate = Carbon::parse(request('end_date'))->endOfDay();
|
||||
$data = Survey::whereBetween('created_at', [$startDate, $endDate])->get();
|
||||
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->setCellValue('A1', "Laporan Survei dari {$startDate->format('Y-m-d')} sampai {$endDate->format('Y-m-d')}");
|
||||
$sheet->mergeCells('A1:E1');
|
||||
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14);
|
||||
$sheet->getStyle('A1')->getAlignment()->setHorizontal('center');
|
||||
|
||||
$sheet->setCellValue('A2', "Waktu Cetak: {$waktu_cetak}");
|
||||
$sheet->mergeCells('A2:E2');
|
||||
$sheet->getStyle('A2')->getAlignment()->setHorizontal('center');
|
||||
|
||||
// Header tabel
|
||||
$headers = ["No", "Nama", "Tipe Survei", "Kepuasan", "Kritik dan Saran"];
|
||||
$sheet->fromArray($headers, null, 'A4');
|
||||
$sheet->getStyle('A4:E4')->applyFromArray([
|
||||
'font' => ['bold' => true],
|
||||
'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER],
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN
|
||||
]
|
||||
]
|
||||
]);
|
||||
$sheet->getStyle('A4:E4')->getFont()->setBold(true);
|
||||
$sheet->getStyle('A4:E4')->getAlignment()->setHorizontal('center');
|
||||
$sheet->getStyle('A4:E4')->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
|
||||
// Isi data
|
||||
$row = 5;
|
||||
foreach ($data as $index => $item) {
|
||||
$sheet->setCellValue("A{$row}", $index + 1);
|
||||
$sheet->setCellValue("B{$row}", $item->order->nama_pemesan);
|
||||
$sheet->setCellValue("C{$row}", $item->type === "pelanggan_setia" ? "Pelanggan Setia" : "Pengguna Baru");
|
||||
$sheet->setCellValue("D{$row}", $item->kepuasan);
|
||||
$sheet->setCellValue("E{$row}", $item->keterangan);
|
||||
$row++;
|
||||
}
|
||||
// Auto size kolom
|
||||
foreach(range('A', 'E') as $col){
|
||||
$sheet->getColumnDimension($col)->setAutoSize(true);
|
||||
}
|
||||
$lastRow = $row - 1;
|
||||
$sheet->setAutoFilter("A4:E{$lastRow}");
|
||||
// Download file
|
||||
$fileName = "Laporan Survei {$startDate->format('Y-m-d')} sampai {$endDate->format('Y-m-d')} ". '.xlsx';
|
||||
$writer = new Xlsx($spreadsheet);
|
||||
|
||||
// Output ke browser
|
||||
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
header("Content-Disposition: attachment; filename=\"{$fileName}\"");
|
||||
header('Cache-Control: max-age=0');
|
||||
|
||||
$writer->save('php://output');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
25
app/Models/Survey.php
Normal file
25
app/Models/Survey.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Survey extends Model
|
||||
{
|
||||
protected $connection = 'dbOrderGizi';
|
||||
protected $table = 'public.survey';
|
||||
public $timestamps = false;
|
||||
protected $primaryKey = "id";
|
||||
protected $with = ['order'];
|
||||
protected $fillable =[
|
||||
'no_order',
|
||||
'type',
|
||||
'keterangan',
|
||||
'kepuasan',
|
||||
'created_at'
|
||||
];
|
||||
|
||||
public function order(){
|
||||
return $this->belongsTo(Order::class, 'no_order', 'no_order')->select('no_order', 'nama_pemesan');
|
||||
}
|
||||
}
|
||||
2
env_prod
2
env_prod
@ -23,7 +23,7 @@ LOG_LEVEL=debug
|
||||
DB_CONNECTION_ORDER_GIZI= pgsql
|
||||
DB_HOST_ORDER_GIZI = 172.16.88.22
|
||||
DB_PORT_ORDER_GIZI = 5432
|
||||
DB_DATABASE_ORDER_GIZI = order_gizi
|
||||
DB_DATABASE_ORDER_GIZI = lms_mutu
|
||||
DB_USERNAME_ORDER_GIZI = simrs
|
||||
DB_PASSWORD_ORDER_GIZI = @S1mrs.3205@
|
||||
|
||||
|
||||
@ -305,7 +305,7 @@ h6 {
|
||||
}
|
||||
|
||||
.header .logo img {
|
||||
max-height: 36px;
|
||||
max-height: 60px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
@ -347,6 +347,10 @@ h6 {
|
||||
.header .navmenu {
|
||||
order: 3;
|
||||
}
|
||||
.header .logo img {
|
||||
max-height: 35px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.scrolled .header {
|
||||
|
||||
BIN
public/assets/img/avatars/8.jpg
Normal file
BIN
public/assets/img/avatars/8.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 258 KiB |
@ -109,16 +109,41 @@ async function submitOrderToServer(){
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.status) {
|
||||
// ✅ Hapus sessionStorage di client
|
||||
clearSession()
|
||||
Swal.fire({
|
||||
title: 'Pesanan Berhasil!',
|
||||
text: 'Terima kasih, pesanan Anda sedang kami siapkan.',
|
||||
title: '<span style="color: #00796b;">Pesanan Berhasil!</span>',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'Berhasil!',
|
||||
confirmButtonColor: '#28a745'
|
||||
iconColor: '#2e7d32', // Warna hijau Kemenkes
|
||||
html: `
|
||||
<p class="text-muted mb-4">Terima kasih, pesanan Anda sedang kami siapkan.</p>
|
||||
<div class="p-3 border-0 rounded-4 shadow-sm mb-3" style="background-color: #f1f8f7;">
|
||||
<p class="small fw-bold mb-3 text-uppercase" style="color: #004d40; letter-spacing: 1px;">Bantu Kami Meningkatkan Layanan:</p>
|
||||
|
||||
<button type="button" onclick="location.href='/survey?no_order=${result.no_order}&type=pengguna_baru'"
|
||||
class="btn w-100 mb-3 py-3 border-0 shadow-sm transition-hover"
|
||||
style="background-color: #00a99d; color: white; border-radius: 12px;">
|
||||
<div class="fw-bold px-2">Saya Pengguna Baru</div>
|
||||
<div style="font-size: 0.75rem; opacity: 0.9;">Survei kemudahan aplikasi pemesanan</div>
|
||||
</button>
|
||||
|
||||
<button type="button" onclick="location.href='/survey?no_order=${result.no_order}&type=pelanggan_setia'"
|
||||
class="btn w-100 py-3 border-0 shadow-sm transition-hover"
|
||||
style="background-color: #005eb8; color: white; border-radius: 12px;">
|
||||
<div class="fw-bold px-2">Saya Pelanggan Setia</div>
|
||||
<div style="font-size: 0.75rem; opacity: 0.9;">Survei rasa, variasi, dan penampilan menu</div>
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
showConfirmButton: false,
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Lewati & Selesai',
|
||||
cancelButtonColor: '#6c757d',
|
||||
customClass: {
|
||||
popup: 'rounded-4',
|
||||
cancelButton: 'px-4 py-2 rounded-3'
|
||||
}
|
||||
}).then(() => {
|
||||
window.location.href = "/success-page"; // kehalaman success
|
||||
});
|
||||
|
||||
@ -246,13 +246,28 @@ function toggleCustomerFields() {
|
||||
$("#help_email_karyawan").removeClass('d-none')
|
||||
selectKaryawan(); // inisialisasi ulang selectize
|
||||
break;
|
||||
case 'Karyawan RSAB Harapan Kita (Rapat Internal, Seminar /Pelatihan)':
|
||||
$('.karyawan').show();
|
||||
$nama.val('')
|
||||
$nama.removeClass('form-control')
|
||||
$("#help_nama_pemesan").removeClass('d-none')
|
||||
$("#help_email_karyawan").removeClass('d-none')
|
||||
selectKaryawan(); // inisialisasi ulang selectize
|
||||
break;
|
||||
case 'Keluarga Pasien / Penunggu Pasien':
|
||||
$('.pasien').show();
|
||||
$nama.addClass('form-control')
|
||||
$("#help_nama_pemesan").addClass('d-none')
|
||||
$("#help_email_karyawan").addClass('d-none')
|
||||
break;
|
||||
case 'Masyarakat Umum' :
|
||||
case 'Masyarakat Umum (Corporate)' :
|
||||
$('.umum').show();
|
||||
$nama.addClass('form-control')
|
||||
$("#help_nama_pemesan").addClass('d-none')
|
||||
$("#help_email_karyawan").addClass('d-none')
|
||||
$("#modalAttentionModeUmum").modal('show');
|
||||
break;
|
||||
case 'Masyarakat Umum (Personal)' :
|
||||
$('.umum').show();
|
||||
$nama.addClass('form-control')
|
||||
$("#help_nama_pemesan").addClass('d-none')
|
||||
|
||||
BIN
public/logo/gizi.png
Normal file
BIN
public/logo/gizi.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 216 KiB |
BIN
public/logo/nice.png
Normal file
BIN
public/logo/nice.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
BIN
public/logo/no_nice.png
Normal file
BIN
public/logo/no_nice.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
@ -109,6 +109,14 @@
|
||||
<div data-i18n="User interface">Laporan Pesanan </div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item {{ Request::is('dashboard/survey') ? 'active' : '' }}">
|
||||
<a href="/dashboard/survey" class="menu-link">
|
||||
<i class="menu-icon tf-icons bx bx-box"></i>
|
||||
<div data-i18n="User interface">Survei </div>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
{{-- <li class="menu-item {{ Request::is('dashboard/laporan-pesanan') ? 'active' : '' }}">
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
<li class="nav-item navbar-dropdown dropdown-user dropdown">
|
||||
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<div class="avatar avatar-online">
|
||||
<img src="/assets/img/avatars/1.png" alt class="w-px-40 h-auto rounded-circle" />
|
||||
<img src="/assets/img/avatars/8.jpg" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
@ -39,12 +39,11 @@
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar avatar-online">
|
||||
<img src="/assets/img/avatars/1.png" alt class="w-px-40 h-auto rounded-circle" />
|
||||
<img src="/assets/img/avatars/8.jpg" alt class="w-px-40 h-auto rounded-circle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<span class="fw-semibold d-block">John Doe</span>
|
||||
<small class="text-muted">Admin</small>
|
||||
<span class="fw-semibold d-block">Admin</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
183
resources/views/dashboard/survey/index.blade.php
Normal file
183
resources/views/dashboard/survey/index.blade.php
Normal file
@ -0,0 +1,183 @@
|
||||
@extends('dashboard.layouts.main')
|
||||
@section('body_main')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<h4 class="fw-bold py-3 mb-4">
|
||||
<span class="text-muted fw-light">Dashboard /</span> Survei
|
||||
</h4>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card border-0 shadow-sm h-100" style="border-left: 5px solid #00a99d !important;">
|
||||
<div class="card-header pb-0">
|
||||
<h6 class=" fw-normal mb-0">Statistik Pengguna Baru Total <b id="confirm_pb_total"></b></h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="barChartBaru" style="max-height: 150px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card border-0 shadow-sm h-100" style="border-left: 5px solid #005eb8 !important;">
|
||||
<div class="card-header pb-0">
|
||||
<h6 class=" fw-normal mb-0">Statistik Pelanggan Setia Total <b id="confirm_ps_total"></b></h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="barChartLama" style="max-height: 150px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">Data Detail Survei <strong id="confirm_date_survey"></strong></h5>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="exportSurvei()">
|
||||
<i class="fa fa-download me-1"></i> Export
|
||||
</button>
|
||||
<div class="input-group input-group-sm" style="width: 240px;">
|
||||
<span class="input-group-text bg-white"><i class="fa fa-calendar-alt"></i></span>
|
||||
<input type="text" class="form-control tanggal-input" id="tanggal" placeholder="Pilih tanggal" readonly>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table" id="datatableSurvey"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('dashboard.survey.modal.export')
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
|
||||
<script>
|
||||
const datatable = $("#datatableSurvey");
|
||||
const modalExport = document.getElementById('modalExportSurvei');
|
||||
// Inisialisasi variabel Chart agar bisa di-destroy saat update
|
||||
let chartBaruObj, chartLamaObj;
|
||||
|
||||
function initDt(selectDate = []) {
|
||||
datatable.bootstrapTable('destroy');
|
||||
datatable.bootstrapTable({
|
||||
url: "/dashboard/datatable/survey",
|
||||
method: 'get',
|
||||
queryParams: function(params) {
|
||||
params.tanggal = selectDate;
|
||||
return params;
|
||||
},
|
||||
showColumns: true,
|
||||
pagination: true,
|
||||
serverSide: true,
|
||||
pageSize: 10,
|
||||
columns: [
|
||||
{ title: "Nama Pelanggan", field: 'order.nama_pemesan' },
|
||||
{
|
||||
title: "Type Survei",
|
||||
field: 'type',
|
||||
formatter: (v, row) => row?.type === "pengguna_baru" ? "Pengguna Baru" : "Pelanggan Setia"
|
||||
},
|
||||
{ title: "Kepuasan", field: 'kepuasan' },
|
||||
{ title: "Kritik dan Saran", field: 'keterangan' },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Fungsi perbaikan untuk Bar Chart Horizontal
|
||||
function updateBarChart(chartId, puas, tidakPuas) {
|
||||
const ctx = document.getElementById(chartId).getContext('2d');
|
||||
|
||||
// Hancurkan instance lama agar tidak tumpang tindih saat hover
|
||||
if (chartId === 'barChartBaru' && chartBaruObj) chartBaruObj.destroy();
|
||||
if (chartId === 'barChartLama' && chartLamaObj) chartLamaObj.destroy();
|
||||
|
||||
const config = {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['Puas', 'Tidak Puas'],
|
||||
datasets: [{
|
||||
data: [puas, tidakPuas],
|
||||
backgroundColor: [
|
||||
chartId === 'barChartBaru' ? '#00a99d' : '#005eb8',
|
||||
'#dc3545'
|
||||
],
|
||||
borderRadius: 5,
|
||||
barThickness: 20
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
indexAxis: 'y',
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: { display: false },
|
||||
tooltip: { enabled: true }
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
beginAtZero: true,
|
||||
grid: { display: false },
|
||||
ticks: { stepSize: 1, precision: 0 }
|
||||
},
|
||||
y: { grid: { display: false } }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (chartId === 'barChartBaru') chartBaruObj = new Chart(ctx, config);
|
||||
else chartLamaObj = new Chart(ctx, config);
|
||||
}
|
||||
|
||||
async function loadCharts(selectDate = []) {
|
||||
try {
|
||||
const dateParam = encodeURIComponent(JSON.stringify(selectDate));
|
||||
const response = await fetch(`/dashboard/chart/survey?tanggal=${dateParam}`);
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
|
||||
// 1. Update Statistik Bar Chart Pengguna Baru
|
||||
if(data.kepuasan_baru) {
|
||||
updateBarChart('barChartBaru', data.kepuasan_baru.puas, data.kepuasan_baru.tidak_puas);
|
||||
$("#confirm_pb_total").text(data.kepuasan_baru.total);
|
||||
}
|
||||
|
||||
// 2. Update Statistik Bar Chart Pelanggan Setia
|
||||
if(data.kepuasan_lama) {
|
||||
updateBarChart('barChartLama', data.kepuasan_lama.puas, data.kepuasan_lama.tidak_puas);
|
||||
$("#confirm_ps_total").text(data.kepuasan_lama.total);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error load chart:", error);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
flatpickr('#tanggal', {
|
||||
dateFormat: "Y-m-d",
|
||||
mode: "multiple",
|
||||
locale: "id",
|
||||
onValueUpdate: function(selectedDates) {
|
||||
const formatted = selectedDates.map(d => {
|
||||
const year = d.getFullYear();
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(d.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
});
|
||||
|
||||
initDt(formatted);
|
||||
loadCharts(formatted);
|
||||
|
||||
let text = formatted.length > 0 ? ': ' + formatted.join(', ') : 'Hari Ini';
|
||||
$("#confirm_date_survey").text(text);
|
||||
}
|
||||
});
|
||||
|
||||
$("#confirm_date_survey").text('Hari Ini');
|
||||
initDt();
|
||||
loadCharts();
|
||||
});
|
||||
|
||||
function exportSurvei(){
|
||||
new bootstrap.Modal(modalExport).show()
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
50
resources/views/dashboard/survey/modal/export.blade.php
Normal file
50
resources/views/dashboard/survey/modal/export.blade.php
Normal file
@ -0,0 +1,50 @@
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="modalExportSurvei" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fs-5">Export Data</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<!-- Modal Form -->
|
||||
<form action="/dashboard/survey/export" method="POST">
|
||||
@csrf
|
||||
<div class="modal-body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="exampleFormControlInput1">Start Date</label>
|
||||
<input type="date" class="form-control" name="start_date" id="start_date" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="exampleFormControlInput1">End Date</label>
|
||||
<input type="date" class="form-control" name="end_date" id="end_date" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Footer -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
|
||||
<button type="submit" class="btn btn-primary">Export</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const today = new Date().toISOString().split('T')[0]; // Mendapatkan tanggal hari ini dalam format YYYY-MM-DD
|
||||
$('#start_date').val(today);
|
||||
$('#end_date').val(today);
|
||||
});
|
||||
</script>
|
||||
@ -3,12 +3,6 @@
|
||||
<input type="hidden" name="cart_data" id="cart_data">
|
||||
<div class="col-md-6">
|
||||
<label for="exampleInputEmail1" class="form-label">Apakah Anda Seorang ? <span class="text-danger">*</span></label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_karyawan" value="Karyawan RSAB Harapan Kita" required>
|
||||
<label class="form-check-label" for="radio_karyawan" >
|
||||
Karyawan RSAB Harapan Kita
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_kp" value="Keluarga Pasien / Penunggu Pasien" required>
|
||||
<label class="form-check-label" for="radio_kp">
|
||||
@ -16,10 +10,34 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_karyawan" value="Karyawan RSAB Harapan Kita" required>
|
||||
<label class="form-check-label" for="radio_karyawan" >
|
||||
Karyawan RSAB Harapan Kita
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_karyawan" value="Karyawan RSAB Harapan Kita (Rapat Internal, Seminar /Pelatihan)" required>
|
||||
<label class="form-check-label" for="radio_karyawan" >
|
||||
Karyawan RSAB Harapan Kita (Rapat Internal, Seminar /Pelatihan)
|
||||
</label>
|
||||
</div>
|
||||
{{-- <div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_public" value="Masyarakat Umum" required>
|
||||
<label class="form-check-label" for="radio_public">
|
||||
Masyarakat Umum
|
||||
</label>
|
||||
</div> --}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_public" value="Masyarakat Umum (Personal)" required>
|
||||
<label class="form-check-label" for="radio_public">
|
||||
Masyarakat Umum (Personal)
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_public" value="Masyarakat Umum (Corporate)" required>
|
||||
<label class="form-check-label" for="radio_public">
|
||||
Masyarakat Umum (Corporate)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
<div class="container position-relative d-flex align-items-center justify-content-between">
|
||||
<a href="/" class="logo d-flex align-items-center me-auto">
|
||||
<!-- Uncomment the line below if you also wish to use an image logo -->
|
||||
<img src="/logo/gizi.png" alt="Logo RSAB HARAPAN KITA" class="" style="height:125px;">
|
||||
<img src="/logo/logo_rsabhk.png" alt="Logo RSAB HARAPAN KITA" class="logo-img">
|
||||
<h1 class="sitename"></h1>
|
||||
</a>
|
||||
@ -16,7 +17,7 @@
|
||||
MCU
|
||||
</button>
|
||||
@endif
|
||||
<button type="button" class="btn btn-outline-success position-relative me-1 d-flex" style="font-size:14px;" onclick="checkOrderHref()">
|
||||
<button type="button" class="btn btn-outline-success position-relative d-flex lh-sm" style="font-size:14px;" onclick="checkOrderHref()">
|
||||
Check Order
|
||||
</button>
|
||||
|
||||
|
||||
155
resources/views/guest/survey/index.blade.php
Normal file
155
resources/views/guest/survey/index.blade.php
Normal file
@ -0,0 +1,155 @@
|
||||
@extends('guest.layout.main')
|
||||
@section('body_main_guests')
|
||||
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8 col-lg-7">
|
||||
|
||||
<div class="text-center mb-5">
|
||||
@if($type === "pengguna_baru")
|
||||
<h2 class="fw-bold text-dark mb-3">Form Kepuasan Pelanggan Terkait Penggunaan Aplikasi Catering Gizi RSABHK</h2>
|
||||
@else
|
||||
<h2 class="fw-bold text-dark mb-3">Form Kepuasan Pelanggan Catering Instalasi Gizi RSAB HK </h2>
|
||||
@endif
|
||||
<p class="text-secondary mx-auto" style="max-width: 500px;">
|
||||
Terima kasih telah memesan di <strong>Catering Instalasi Gizi RSAB HK</strong>. Masukan Anda sangat berarti bagi peningkatan kualitas layanan kami.
|
||||
</p>
|
||||
<div class="mx-auto mt-3"></div>
|
||||
</div>
|
||||
<form action="" method="POST" id="surveyForm">
|
||||
@csrf
|
||||
<div class="card border-0 shadow-sm mb-4 overflow-hidden" style="border-radius: 15px;">
|
||||
{{-- <div class="card-body p-4">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="bg-light rounded-circle p-2 me-3">
|
||||
<i class="fas fa-user text-primary"></i>
|
||||
</div>
|
||||
<label class="form-label fw-semibold mb-0">Nama Pelanggan <span class="text-danger">*</span></label>
|
||||
</div>
|
||||
<input type="text" name="nama_pelanggan" class="form-control custom-input" placeholder="Masukkan nama lengkap Anda..." required>
|
||||
</div> --}}
|
||||
</div>
|
||||
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 15px;">
|
||||
<div class="card-body p-4 text-center">
|
||||
@if($type === "pengguna_baru")
|
||||
<label class="form-label fw-semibold d-block mb-4">Menurut Anda apakah aplikasi pemesanan catering gizi saat ini mudah untuk digunakan? <span class="text-danger">*</span></label>
|
||||
@else
|
||||
<label class="form-label fw-semibold d-block mb-4">Bagaimana pelayanan catering gizi yang anda dapatkan ? <span class="text-danger">*</span></label>
|
||||
@endif
|
||||
<p class="text-muted small mb-4"><i class="fas fa-info-circle me-1"></i> Silakan pilih salah satu ikon di bawah ini</p>
|
||||
<input type="hidden" name="type" value={{ $type }} />
|
||||
<input type="hidden" name="no_order" value={{ $no_order }} />
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
<input type="radio" class="btn-check" name="kepuasan" id="puas" value="Puas" required>
|
||||
<label class="btn btn-outline-light w-100 p-4 emoji-card" for="puas">
|
||||
<div class="emoji-icon mb-2"><img src="/logo/nice.png" style="height:120px;"/> </div>
|
||||
<div class="fw-bold text-dark">Puas</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input type="radio" class="btn-check" name="kepuasan" id="tidak_puas" value="Tidak Puas">
|
||||
<label class="btn btn-outline-light w-100 p-4 emoji-card" for="tidak_puas">
|
||||
<div class="emoji-icon mb-2"><img src="/logo/no_nice.png" style="height:120px;"/></div>
|
||||
<div class="fw-bold text-dark">Tidak Puas</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 15px;">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="bg-light rounded-circle p-2 me-3">
|
||||
<i class="fas fa-comment-dots text-primary"></i>
|
||||
</div>
|
||||
<label class="form-label fw-semibold mb-0">Kritik dan Saran <span class="text-danger">*</span></label>
|
||||
</div>
|
||||
<textarea name="kritik_saran" class="form-control custom-input" rows="3" placeholder="Tuliskan masukan atau saran Anda di sini..." required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end mb-5">
|
||||
{{-- <button type="reset" class="btn btn-light px-4 fw-medium text-muted">Tutup</button> --}}
|
||||
<button type="submit" class="btn btn-primary px-5 fw-bold shadow-sm">Kirim Masukan</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Emoji Card Selector */
|
||||
.emoji-card {
|
||||
border: 2px solid #9b9c9e !important;
|
||||
border-radius: 15px !important;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.emoji-icon {
|
||||
font-size: 2.5rem;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-check:checked + .emoji-card {
|
||||
background-color: #b8ddff !important;
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.btn-check:checked + .emoji-card .emoji-icon {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.emoji-card:hover {
|
||||
border-color: #0c0c0c !important;
|
||||
background: #0f0f0f;
|
||||
}
|
||||
|
||||
/* Requirement text */
|
||||
.text-danger {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$("#surveyForm").on('submit', async function(e){
|
||||
e.preventDefault()
|
||||
const buttonSubmit = $(this).find('button[type="submit"]')
|
||||
if(buttonSubmit.prop('disabled')) return;
|
||||
buttonSubmit.prop('disabled', true).html('<i class="fas fa-spinner fa-spin me-2"></i>Memperoses')
|
||||
const formData = new FormData(this);
|
||||
try {
|
||||
const response = await fetch('/survey', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||||
}
|
||||
});
|
||||
const result = await response.json()
|
||||
if(result.status){
|
||||
Swal.fire({
|
||||
title: 'Survei Berhasil!',
|
||||
text: 'Terima kasih, Masukan anda sangat berarti bagi kami.',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'Berhasil!',
|
||||
confirmButtonColor: '#28a745'
|
||||
}).then(() => {
|
||||
window.location.href = "/success-page"; // kehalaman success
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
Swal.fire({
|
||||
title: 'Gagal!',
|
||||
text: "Terjadi kesalahan saat mengirim melakukan survei.",
|
||||
icon: 'error',
|
||||
confirmButtonText: 'Tutup!'
|
||||
})
|
||||
}finally{
|
||||
buttonSubmit.prop('disabled', false).html('Selesaikan Survei')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@endsection
|
||||
@ -10,6 +10,7 @@ use App\Http\Controllers\KlasifikasiMenuController;
|
||||
use App\Http\Controllers\MasterMcuController;
|
||||
use App\Http\Controllers\MenuController;
|
||||
use App\Http\Controllers\PesananController;
|
||||
use App\Http\Controllers\SurveyController;
|
||||
use App\Mail\NotifikasiCustomer;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Barryvdh\Snappy\Facades\SnappyPdf;
|
||||
@ -83,6 +84,11 @@ Route::group(['middleware' => ['auth']], function(){
|
||||
Route::get('/pekerjaan/detail/{id}', [PesananController::class, 'getPekerjaanDetail']);
|
||||
Route::get('/pekerjaan/label', [PesananController::class, 'downloadLabel']);
|
||||
Route::get('/data/pending-pekerjaan', [PesananController::class, 'dataPekerjaanPending']);
|
||||
|
||||
Route::get('/survey', [SurveyController::class, 'dashboardSurvey']);
|
||||
Route::get('/datatable/survey', [SurveyController::class, 'datatable']);
|
||||
Route::get('/chart/survey', [SurveyController::class, 'chartDataSurvey']);
|
||||
Route::post('/survey/export', [SurveyController::class, 'exportSurveyExcel']);
|
||||
});
|
||||
|
||||
Route::post('/logout', [AuthController::class, 'logout']);
|
||||
@ -103,6 +109,9 @@ Route::get('/success-mcu', [CustomerController::class, 'successMcu']);
|
||||
Route::get('/karyawan', [CustomerController::class, 'karyawan']);
|
||||
Route::get('/unit-instalasi', [CustomerController::class, 'unitInstalasi']);
|
||||
Route::get('/server-time', fn()=> response()->json(['now' => now()]));
|
||||
Route::get('/survey', [SurveyController::class, 'index']);
|
||||
Route::post('/survey', [SurveyController::class, 'store']);
|
||||
|
||||
|
||||
// Route::get('/send-mail', function(){
|
||||
// Mail::to('skyjok14@gmail.com')->queue(new NotifikasiCustomer('Test'));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user