History detail & fixing

This commit is contained in:
misbahsurur 2024-12-20 21:20:37 +07:00
parent e7063b16f7
commit 7ac456577d
20 changed files with 357 additions and 20 deletions

View File

@ -58,6 +58,7 @@ public function store(Request $request)
'name' => $request->name, 'name' => $request->name,
'code' => $request->code, 'code' => $request->code,
'description' => $request->description, 'description' => $request->description,
'solution' => $request->solution,
'min_percentage' => $request->min_percentage, 'min_percentage' => $request->min_percentage,
'max_percentage' => $request->max_percentage, 'max_percentage' => $request->max_percentage,
'status' => $request->status, 'status' => $request->status,
@ -117,6 +118,7 @@ public function update(Request $request, Addiction $addiction)
'name' => $request->name, 'name' => $request->name,
'code' => $request->code, 'code' => $request->code,
'description' => $request->description, 'description' => $request->description,
'solution' => $request->solution,
'min_percentage' => $request->min_percentage, 'min_percentage' => $request->min_percentage,
'max_percentage' => $request->max_percentage, 'max_percentage' => $request->max_percentage,
'status' => $request->status, 'status' => $request->status,

View File

@ -54,7 +54,7 @@ public function store(Request $request)
*/ */
public function show(History $history) public function show(History $history)
{ {
// return view('admin.histories.show', compact('history'));
} }
/** /**

View File

@ -35,9 +35,16 @@ public function history()
return view('user.history', compact('histories')); return view('user.history', compact('histories'));
} }
public function detailHistory($id)
{
$history = History::with('user', 'addiction', 'details')->find($id);
return view('user.history-detail', compact('history'));
}
public function addiction() public function addiction()
{ {
$items = Item::where('status', 'active')->get(); $items = Item::where('status', 'active')->inRandomOrder()->get();
$likerts = Likert::orderBy('score')->get(); $likerts = Likert::orderBy('score')->get();
return view('user.addiction', compact('items', 'likerts')); return view('user.addiction', compact('items', 'likerts'));
@ -45,6 +52,7 @@ public function addiction()
public function storeAddiction(Request $request) public function storeAddiction(Request $request)
{ {
$items = $request->items;
$values = $request->values; $values = $request->values;
$answers = $request->answers; $answers = $request->answers;
$maxLikert = Likert::orderBy('score', 'desc')->first()->score; $maxLikert = Likert::orderBy('score', 'desc')->first()->score;
@ -53,7 +61,8 @@ public function storeAddiction(Request $request)
$maxScores = []; $maxScores = [];
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$userScores[] = $value * $answers[$key]; $score = Likert::find($answers[$key])->score;
$userScores[] = $value * $score;
$maxScores[] = $value * $maxLikert; $maxScores[] = $value * $maxLikert;
} }
@ -67,16 +76,23 @@ public function storeAddiction(Request $request)
->where('status', 'active') ->where('status', 'active')
->first(); ->first();
if ($addiction === null) { if (is_null($addiction)) {
return redirect()->back()->with('error', 'Terjadi kesalahan saat mencari jenis kecanduan'); return redirect()->back()->with('error', 'Terjadi kesalahan saat mencari jenis kecanduan');
} }
History::create([ $history = History::create([
'user_id' => Auth::id(), 'user_id' => Auth::id(),
'addiction_id' => $addiction->id, 'addiction_id' => $addiction->id,
'result' => $percentage.'%', 'result' => $percentage,
]); ]);
foreach ($items as $key => $item) {
$history->details()->create([
'item_id' => $item,
'likert_id' => $answers[$key],
]);
}
return redirect()->route('user.history')->with('success', 'Berhasil menambahkan riwayat'); return redirect()->route('user.history')->with('success', 'Berhasil menambahkan riwayat');
} }
} }

View File

@ -20,4 +20,9 @@ public function addiction()
{ {
return $this->belongsTo(Addiction::class, 'addiction_id', 'id'); return $this->belongsTo(Addiction::class, 'addiction_id', 'id');
} }
public function details()
{
return $this->hasMany(HistoryDetail::class, 'history_id', 'id');
}
} }

View File

@ -0,0 +1,28 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class HistoryDetail extends Model
{
use HasFactory;
protected $guarded = [];
public function history()
{
return $this->belongsTo(History::class, 'history_id', 'id');
}
public function item()
{
return $this->belongsTo(Item::class, 'item_id', 'id');
}
public function likert()
{
return $this->belongsTo(Likert::class, 'likert_id', 'id');
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\HistoryDetail>
*/
class HistoryDetailFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
//
];
}
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('history_details', function (Blueprint $table) {
$table->id();
$table->foreignId('history_id')->constrained()->onDelete('cascade');
$table->foreignId('item_id')->constrained()->onDelete('cascade');
$table->foreignId('likert_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('history_details');
}
};

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('addictions', function (Blueprint $table) {
$table->text('solution')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('addictions', function (Blueprint $table) {
//
});
}
};

View File

@ -0,0 +1,19 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class HistoryDetailSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
}
}

View File

@ -69,6 +69,16 @@
@enderror @enderror
</div> </div>
<div class="mb-3">
<label class="form-label">Solution</label>
<textarea name="solution" id="solution" rows="5" class="form-control @error('solution') is-invalid @enderror" placeholder="Enter solution">{{ old('solution') }}</textarea>
@error('solution')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Status</label> <label class="form-label">Status</label>
<select name="status" id="statusAddiction" class="form-select" required> <select name="status" id="statusAddiction" class="form-select" required>

View File

@ -69,6 +69,16 @@
@enderror @enderror
</div> </div>
<div class="mb-3">
<label class="form-label">Solution</label>
<textarea name="solution" id="solution" rows="5" class="form-control @error('solution') is-invalid @enderror" placeholder="Enter solution" disabled>{{ old('solution', $addiction->solution) }}</textarea>
@error('solution')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Status</label> <label class="form-label">Status</label>
<select name="status" id="statusAddiction" class="form-select" disabled> <select name="status" id="statusAddiction" class="form-select" disabled>

View File

@ -69,6 +69,16 @@
@enderror @enderror
</div> </div>
<div class="mb-3">
<label class="form-label">Solution</label>
<textarea name="solution" id="solution" rows="5" class="form-control @error('solution') is-invalid @enderror" placeholder="Enter solution">{{ old('solution', $addiction->solution) }}</textarea>
@error('solution')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Status</label> <label class="form-label">Status</label>
<select name="status" id="statusAddiction" class="form-select" required> <select name="status" id="statusAddiction" class="form-select" required>

View File

@ -22,13 +22,14 @@
<h4 class="card-title">Addiction Data</h4> <h4 class="card-title">Addiction Data</h4>
<a href="{{ route('admin.addictions.create') }}" class="btn btn-primary mb-3">Create Addiction</a> <a href="{{ route('admin.addictions.create') }}" class="btn btn-primary mb-3">Create Addiction</a>
<div class="table-responsive"> <div class="table-responsive">
<table id="datatable" class="table align-middle"> <table id="datatable" class="table align-middle text-wrap w-100">
<thead> <thead>
<tr> <tr>
<th width="10px" class="text-center">#</th> <th width="10px" class="text-center">#</th>
<th>Name</th> <th>Name</th>
<th>Percentage</th> <th>Percentage</th>
<th>Description</th> <th>Description</th>
<th>Solution</th>
<th class="text-center">Status</th> <th class="text-center">Status</th>
<th width="10px" class="text-center">#</th> <th width="10px" class="text-center">#</th>
</tr> </tr>
@ -41,7 +42,8 @@
{{ $addiction->name }} <br> <p class="text-muted m-0"> Code: {{ $addiction->code }}</p> {{ $addiction->name }} <br> <p class="text-muted m-0"> Code: {{ $addiction->code }}</p>
</td> </td>
<td>{{ $addiction->min_percentage }} % - {{ $addiction->max_percentage }} %</td> <td>{{ $addiction->min_percentage }} % - {{ $addiction->max_percentage }} %</td>
<td>{{ $addiction->description }}</td> <td class="text-wrap">{{ $addiction->description }}</td>
<td class="text-wrap">{{ $addiction->solution }}</td>
<td class="text-center"> <td class="text-center">
<span class="badge rounded-pill bg-{{ $addiction->status == 'active' ? 'success' : 'danger' }}">{{ ucwords($addiction->status) }}</span> <span class="badge rounded-pill bg-{{ $addiction->status == 'active' ? 'success' : 'danger' }}">{{ ucwords($addiction->status) }}</span>
</td> </td>

View File

@ -29,16 +29,27 @@
<th>Addiction</th> <th>Addiction</th>
<th>Result</th> <th>Result</th>
<th>Date Time</th> <th>Date Time</th>
<th width="10px" class="text-center">#</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach ($histories as $history) @foreach ($histories as $history)
<tr> <tr>
<td>{{ $loop->iteration }}</td> <td class="text-center">{{ $loop->iteration }}</td>
<td>{{ $history->user->name }}</td> <td>{{ $history->user->name }}</td>
<td>{{ $history->addiction->name }}</td> <td>{{ $history->addiction->name }}</td>
<td>{{ $history->result }}%</td> <td>{{ $history->result }}%</td>
<td>{{ $history->created_at->format('d-m-Y H:i:s') }}</td> <td>{{ $history->created_at->format('d-m-Y H:i:s') }}</td>
<td class="text-center">
<div class="dropdown d-inline-block">
<button class="btn btn-inverse-secondary btn-xs dropdown py-0 px-1" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i data-feather="more-horizontal"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="{{ route('admin.histories.show', $history->id) }}"><i class="mdi mdi-eye-outline align-bottom me-2 text-muted"></i> Detail</a></li>
</ul>
</div>
</td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>

View File

@ -0,0 +1,67 @@
@extends('layouts.master')
@section('title', 'Detail History')
@section('content')
<div class="page-content">
<nav class="page-breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Master</a></li>
<li class="breadcrumb-item"><a href="{{ route('admin.histories.index') }}">History</a></li>
<li class="breadcrumb-item active" aria-current="page">Detail History</li>
</ol>
</nav>
<div class="row">
<div class="col-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title">Detail History</h4>
<div class="row">
<div class="col-md-12 col-lg-6">
<div class="mb-3">
<label class="form-label">Addiction</label>
<input type="text" class="form-control" value="{{ $history->addiction->name }}" disabled placeholder="Enter addiction">
</div>
<div class="mb-3">
<label class="form-label">Result (%)</label>
<input type="text" class="form-control" value="{{ $history->result }}" disabled placeholder="Enter result"/>
</div>
</div>
<div class="col-md-12 col-lg-6">
<div class="mb-3">
<label class="form-label">Date Time</label>
<input type="text" class="form-control" value="{{ $history->created_at->format('d-m-Y H:i:s') }}" disabled placeholder="Enter date time">
</div>
<div class="mb-3">
<label class="form-label">Solution</label>
<textarea class="form-control" disabled placeholder="Enter solution">{{ $history->addiction->solution ?? '' }}</textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<h4 class="card-title">Addiction Test Result</h4>
<table class="table table-bordered w-100 text-wrap align-middle">
<thead>
<tr>
<th width="10px" class="text-center">#</th>
<th>Item Content</th>
<th class="text-center">Answer</th>
</tr>
</thead>
<tbody>
@foreach ($history->details as $detail)
<tr>
<td class="text-center">{{ $loop->iteration }}</td>
<td class="text-wrap">{{ $detail->item->content }}</td>
<td class="text-center">{{ $detail->likert->name }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -23,7 +23,7 @@
<h4 class="card-title">Item Data</h4> <h4 class="card-title">Item Data</h4>
<a href="{{ route('admin.items.create') }}" class="btn btn-primary mb-3">Create Item</a> <a href="{{ route('admin.items.create') }}" class="btn btn-primary mb-3">Create Item</a>
<div class="table-responsive"> <div class="table-responsive">
<table id="datatable" class="table align-middle"> <table id="datatable" class="table align-middle text-wrap w-100">
<thead> <thead>
<tr> <tr>
<th width="10px" class="text-center">#</th> <th width="10px" class="text-center">#</th>
@ -39,10 +39,10 @@
@foreach ($items as $factorName => $groupedItems) @foreach ($items as $factorName => $groupedItems)
@foreach ($groupedItems as $index => $item) @foreach ($groupedItems as $index => $item)
<tr> <tr>
<td>{{ $loop->iteration }}</td> <td class="text-center">{{ $loop->iteration }}</td>
<td><strong>{{ $factorName }}</strong></td> <td><strong>{{ $factorName }}</strong></td>
<td>{{ $item->code }}</td> <td>{{ $item->code }}</td>
<td>{{ $item->content }}</td> <td class="text-wrap">{{ $item->content }}</td>
<td>{{ $item->value }}</td> <td>{{ $item->value }}</td>
<td class="text-center"> <td class="text-center">
<span class="badge rounded-pill bg-{{ $item->status == 'active' ? 'success' : 'danger' }}">{{ ucwords($item->status) }}</span> <span class="badge rounded-pill bg-{{ $item->status == 'active' ? 'success' : 'danger' }}">{{ ucwords($item->status) }}</span>
@ -96,7 +96,8 @@
columnDefs: [ columnDefs: [
{ targets: 1, visible: false } { targets: 1, visible: false }
], ],
responsive: true, responsive: false,
scrollX: true,
order: [[1, 'asc']], order: [[1, 'asc']],
}); });
}); });

View File

@ -29,11 +29,12 @@
<tr> <tr>
<td class="text-wrap">{{ $item->content }}</td> <td class="text-wrap">{{ $item->content }}</td>
<td class="text-center"> <td class="text-center">
<input type="hidden" name="items[]" value="{{ $item->id }}">
<input type="hidden" name="values[]" value="{{ $item->value }}"> <input type="hidden" name="values[]" value="{{ $item->value }}">
<select name="answers[]" class="form-select" required> <select name="answers[]" class="form-select" required>
<option value="" hidden>Select Answer</option> <option value="" hidden>Select Answer</option>
@foreach ($likerts as $likert) @foreach ($likerts as $likert)
<option value="{{ $likert->score }}" {{ in_array($likert->score, old('answers', [])) ? 'selected' : '' }}> <option value="{{ $likert->id }}" {{ in_array($likert->id, old('answers', [])) ? 'selected' : '' }}>
{{ $likert->name }} {{ $likert->name }}
</option> </option>
@endforeach @endforeach

View File

@ -0,0 +1,60 @@
@extends('layouts.masteruser')
@section('title', 'Detail History')
@section('content')
<div class="page-content">
<div class="row">
<div class="col-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title">Detail History</h4>
<div class="row">
<div class="col-md-12 col-lg-6">
<div class="mb-3">
<label class="form-label">Addiction</label>
<input type="text" class="form-control" value="{{ $history->addiction->name }}" disabled placeholder="Enter addiction">
</div>
<div class="mb-3">
<label class="form-label">Result (%)</label>
<input type="text" class="form-control" value="{{ $history->result }}" disabled placeholder="Enter result"/>
</div>
</div>
<div class="col-md-12 col-lg-6">
<div class="mb-3">
<label class="form-label">Date Time</label>
<input type="text" class="form-control" value="{{ $history->created_at->format('d-m-Y H:i:s') }}" disabled placeholder="Enter date time">
</div>
<div class="mb-3">
<label class="form-label">Solution</label>
<textarea class="form-control" disabled placeholder="Enter solution">{{ $history->addiction->solution ?? '' }}</textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<h4 class="card-title">Addiction Test Result</h4>
<table class="table table-bordered w-100 text-wrap align-middle">
<thead>
<tr>
<th width="10px" class="text-center">#</th>
<th>Item Content</th>
<th class="text-center">Answer</th>
</tr>
</thead>
<tbody>
@foreach ($history->details as $detail)
<tr>
<td class="text-center">{{ $loop->iteration }}</td>
<td class="text-wrap">{{ $detail->item->content }}</td>
<td class="text-center">{{ $detail->likert->name }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -9,12 +9,6 @@
@endsection @endsection
@section('content') @section('content')
<div class="page-content"> <div class="page-content">
<nav class="page-breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Master</a></li>
<li class="breadcrumb-item active" aria-current="page">History</li>
</ol>
</nav>
<div class="row"> <div class="row">
<div class="col-md-12 grid-margin stretch-card"> <div class="col-md-12 grid-margin stretch-card">
<div class="card"> <div class="card">
@ -28,6 +22,7 @@
<th>Addiction</th> <th>Addiction</th>
<th>Result</th> <th>Result</th>
<th>Date Time</th> <th>Date Time</th>
<th width="10px" class="text-center">#</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -37,6 +32,16 @@
<td>{{ $history->addiction->name }}</td> <td>{{ $history->addiction->name }}</td>
<td>{{ $history->result }}%</td> <td>{{ $history->result }}%</td>
<td>{{ $history->created_at->format('d-m-Y H:i:s') }}</td> <td>{{ $history->created_at->format('d-m-Y H:i:s') }}</td>
<td class="text-center">
<div class="dropdown d-inline-block">
<button class="btn btn-inverse-secondary btn-xs dropdown py-0 px-1" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i data-feather="more-horizontal"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="{{ route('user.history.show', $history->id) }}"><i class="mdi mdi-eye-outline align-bottom me-2 text-muted"></i> Detail</a></li>
</ul>
</div>
</td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>

View File

@ -50,6 +50,7 @@
Route::get('/home', [HomeController::class, 'index'])->name('dashboard'); Route::get('/home', [HomeController::class, 'index'])->name('dashboard');
Route::get('dashboard', [App\Http\Controllers\User\DashboardController::class, 'index'])->name('dashboard'); Route::get('dashboard', [App\Http\Controllers\User\DashboardController::class, 'index'])->name('dashboard');
Route::get('history', [App\Http\Controllers\User\DashboardController::class, 'history'])->name('history'); Route::get('history', [App\Http\Controllers\User\DashboardController::class, 'history'])->name('history');
Route::get('history/{id}', [App\Http\Controllers\User\DashboardController::class, 'detailHistory'])->name('history.show');
Route::get('addiction', [App\Http\Controllers\User\DashboardController::class, 'addiction'])->name('addiction'); Route::get('addiction', [App\Http\Controllers\User\DashboardController::class, 'addiction'])->name('addiction');
Route::post('addiction', [App\Http\Controllers\User\DashboardController::class, 'storeAddiction'])->name('addiction.store'); Route::post('addiction', [App\Http\Controllers\User\DashboardController::class, 'storeAddiction'])->name('addiction.store');
}); });