481 lines
16 KiB
PHP
481 lines
16 KiB
PHP
@extends('layout.app')
|
|
|
|
@section('title', 'Perbandingan Alternatif')
|
|
|
|
@push('styles')
|
|
<style>
|
|
.card {
|
|
border: none;
|
|
border-radius: 15px;
|
|
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
|
margin-bottom: 2rem;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.card:hover {
|
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.card-header {
|
|
background: linear-gradient(45deg, #0d6efd, #0dcaf0);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 15px 15px 0 0 !important;
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.card-body {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.table {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.table th {
|
|
background-color: #f8f9fa;
|
|
font-weight: 600;
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.table td {
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.table-hover tbody tr:hover {
|
|
background-color: rgba(0,0,0,.075);
|
|
}
|
|
|
|
.score-cell {
|
|
font-weight: 500;
|
|
color: #0d6efd;
|
|
}
|
|
|
|
.highest-score {
|
|
background-color: #d1e7dd !important;
|
|
color: #0f5132;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.alert-info {
|
|
background-color: #e8f4f8;
|
|
border-color: #d6e9f9;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.komponen-section {
|
|
border: none;
|
|
border-radius: 15px;
|
|
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
|
margin-bottom: 2rem;
|
|
transition: all 0.3s ease;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.komponen-section:hover {
|
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.komponen-header {
|
|
background: linear-gradient(45deg, #0d6efd, #0dcaf0);
|
|
color: white;
|
|
padding: 1.5rem;
|
|
border-radius: 15px 15px 0 0;
|
|
}
|
|
|
|
.komponen-body {
|
|
background: white;
|
|
padding: 1.5rem;
|
|
border-radius: 0 0 15px 15px;
|
|
}
|
|
|
|
.rekomendasi-section {
|
|
background: #d1e7dd;
|
|
border-radius: 10px;
|
|
padding: 1.5rem;
|
|
margin-bottom: 1.5rem;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.rekomendasi-section:hover {
|
|
box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.rekomendasi-section h6 {
|
|
color: #0f5132;
|
|
margin-bottom: 1rem;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.rekomendasi-section h6 i {
|
|
margin-right: 0.75rem;
|
|
}
|
|
|
|
.rekomendasi-list {
|
|
list-style: none;
|
|
padding-left: 0;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.rekomendasi-list li {
|
|
padding: 1rem;
|
|
background: #fff;
|
|
border-radius: 10px;
|
|
margin-bottom: 0.75rem;
|
|
transition: all 0.3s ease;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.rekomendasi-list li:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.rekomendasi-list li i {
|
|
margin-right: 0.75rem;
|
|
color: #0f5132;
|
|
}
|
|
|
|
.rekomendasi-list li:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.breadcrumb {
|
|
background: transparent;
|
|
padding: 0;
|
|
}
|
|
|
|
.breadcrumb-item a {
|
|
color: #0d6efd;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.breadcrumb-item.active {
|
|
color: #6c757d;
|
|
}
|
|
|
|
#loadingOverlay {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
z-index: 9999;
|
|
backdrop-filter: blur(5px);
|
|
}
|
|
|
|
.loading-content {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
text-align: center;
|
|
color: white;
|
|
background: rgba(13, 110, 253, 0.9);
|
|
padding: 2rem;
|
|
border-radius: 15px;
|
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
.loading-spinner {
|
|
width: 3rem;
|
|
height: 3rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.table-responsive {
|
|
border-radius: 10px;
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
.card-header, .komponen-header {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.card-body, .komponen-body {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.table td, .table th {
|
|
padding: 0.75rem;
|
|
}
|
|
|
|
.rekomendasi-section {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.rekomendasi-list li {
|
|
padding: 0.75rem;
|
|
}
|
|
}
|
|
|
|
/* Consistency Ratio Cards */
|
|
.cr-card {
|
|
padding: 1rem;
|
|
border-radius: 0.75rem;
|
|
color: white;
|
|
height: 100%;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.cr-card:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.cr-title {
|
|
font-weight: 600;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.cr-value {
|
|
font-size: 1.1rem;
|
|
font-weight: 500;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.cr-status {
|
|
font-size: 0.9rem;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.bg-success {
|
|
background: linear-gradient(135deg, #4caf50, #388e3c);
|
|
}
|
|
|
|
.bg-warning {
|
|
background: linear-gradient(135deg, #ff9800, #f57c00);
|
|
}
|
|
</style>
|
|
@endpush
|
|
|
|
@section('content')
|
|
<div class="content-wrapper">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<!-- Page Title -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h4 class="card-title mb-0">Hasil Normalisasi Kriteria</h4>
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb mb-0">
|
|
<li class="breadcrumb-item"><a href="{{ route('admindash') }}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{{ route('alternatif.pilih') }}">Pilih Alternatif</a></li>
|
|
<li class="breadcrumb-item"><a href="{{ route('alternatif.view') }}">Lihat Alternatif</a></li>
|
|
<li class="breadcrumb-item active">Perbandingan</li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
|
|
@if(session('error'))
|
|
<div class="alert alert-danger">
|
|
<i class="fas fa-exclamation-circle me-2"></i>
|
|
{{ session('error') }}
|
|
</div>
|
|
@endif
|
|
|
|
<div class="alert alert-info mb-4">
|
|
<h5 class="alert-heading mb-2">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
Informasi Kriteria
|
|
</h5>
|
|
<ul class="mb-0">
|
|
<li>Untuk kriteria cost (Lemak dan Natrium): Nilai yang lebih kecil lebih baik</li>
|
|
<li>Untuk kriteria benefit (Energi dan Karbohidrat): Nilai yang lebih besar lebih baik</li>
|
|
<li>Total normalisasi untuk setiap kriteria selalu berjumlah 1.0000</li>
|
|
</ul>
|
|
</div>
|
|
|
|
@php
|
|
$alternatifsByKomponen = session('alternatifs_by_komponen');
|
|
@endphp
|
|
|
|
@foreach($alternatifsByKomponen as $komponenId => $komponenData)
|
|
<div class="komponen-section mb-4">
|
|
<div class="komponen-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-utensils me-2"></i>
|
|
{{ $komponenData['nama_komponen'] }}
|
|
</h5>
|
|
</div>
|
|
<div class="komponen-body">
|
|
<!-- Consistency Ratio Section -->
|
|
<div class="consistency-info mb-4">
|
|
<h6 class="section-title mb-3">
|
|
<i class="fas fa-check-circle me-2"></i>
|
|
Consistency Ratio (CR) per Kriteria
|
|
</h6>
|
|
<div class="alert alert-info">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
Perhitungan CR sementara dinonaktifkan untuk troubleshooting.
|
|
</div>
|
|
<!-- <div class="row g-3">
|
|
@foreach($kriterias as $kriteria)
|
|
@php
|
|
$crData = \App\Models\ConsistencyRatioAlternatif::where([
|
|
'kriteria_id' => $kriteria->id,
|
|
'komponen_id' => $komponenId,
|
|
'waktu_makan_id' => session('hasil_rekomendasi.waktu_makan_id')
|
|
])->first();
|
|
@endphp
|
|
<div class="col-md-3">
|
|
<div class="cr-card {{ $crData && $crData->is_consistent ? 'bg-success' : 'bg-warning' }}">
|
|
<div class="cr-title">{{ $kriteria->nama }}</div>
|
|
<div class="cr-value">
|
|
CR: {{ $crData ? number_format($crData->cr, 4) : 'N/A' }}
|
|
</div>
|
|
<div class="cr-status">
|
|
@if($crData && $crData->is_consistent)
|
|
<i class="fas fa-check-circle me-1"></i> Konsisten
|
|
@else
|
|
<i class="fas fa-exclamation-circle me-1"></i> Perlu Review
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div> -->
|
|
</div>
|
|
|
|
<!-- Normalization Table -->
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 60px">No</th>
|
|
<th>Nama Makanan</th>
|
|
<th>Lemak (Normalisasi)</th>
|
|
<th>Natrium (Normalisasi)</th>
|
|
<th>Energi (Normalisasi)</th>
|
|
<th>Karbohidrat (Normalisasi)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@php
|
|
$no = 1;
|
|
// Hitung total untuk setiap kriteria
|
|
$totalLemakInvers = array_sum(array_column($komponenData['alternatifs'], 'lemak_invers'));
|
|
$totalNatriumInvers = array_sum(array_column($komponenData['alternatifs'], 'natrium_invers'));
|
|
$totalEnergi = array_sum(array_column($komponenData['alternatifs'], 'energi'));
|
|
$totalKarbohidrat = array_sum(array_column($komponenData['alternatifs'], 'karbohidrat'));
|
|
@endphp
|
|
|
|
@foreach($komponenData['alternatifs'] as $alternatif)
|
|
<tr>
|
|
<td>{{ $no++ }}</td>
|
|
<td class="text-start">{{ $alternatif['nama'] }}</td>
|
|
<td class="score-cell">{{ number_format($alternatif['lemak_invers'] / $totalLemakInvers, 4) }}</td>
|
|
<td class="score-cell">{{ number_format($alternatif['natrium_invers'] / $totalNatriumInvers, 4) }}</td>
|
|
<td class="score-cell">{{ number_format($alternatif['energi'] / $totalEnergi, 4) }}</td>
|
|
<td class="score-cell">{{ number_format($alternatif['karbohidrat'] / $totalKarbohidrat, 4) }}</td>
|
|
</tr>
|
|
@endforeach
|
|
|
|
<tr>
|
|
<td colspan="2" class="text-end fw-bold">Total</td>
|
|
<td class="fw-bold">1.0000</td>
|
|
<td class="fw-bold">1.0000</td>
|
|
<td class="fw-bold">1.0000</td>
|
|
<td class="fw-bold">1.0000</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
|
|
<!-- Form untuk menyimpan normalisasi -->
|
|
<form action="{{ route('alternatif.simpan.normalisasi') }}" method="POST" id="formNormalisasi">
|
|
@csrf
|
|
<!-- Simpan semua data dalam satu input JSON -->
|
|
<input type="hidden" name="normalisasi_data_json" value="{{ json_encode([
|
|
'data' => collect($alternatifsByKomponen)->map(function($komponenData, $komponenId) use ($totalLemakInvers, $totalNatriumInvers, $totalEnergi, $totalKarbohidrat) {
|
|
return [
|
|
'nama_komponen' => $komponenData['nama_komponen'],
|
|
'alternatifs' => collect($komponenData['alternatifs'])->map(function($alternatif) use ($totalLemakInvers, $totalNatriumInvers, $totalEnergi, $totalKarbohidrat) {
|
|
return [
|
|
'id' => $alternatif['id'],
|
|
'nama' => $alternatif['nama'],
|
|
'lemak_normalized' => $alternatif['lemak_invers'] / $totalLemakInvers,
|
|
'natrium_normalized' => $alternatif['natrium_invers'] / $totalNatriumInvers,
|
|
'energi_normalized' => $alternatif['energi'] / $totalEnergi,
|
|
'karbohidrat_normalized' => $alternatif['karbohidrat'] / $totalKarbohidrat
|
|
];
|
|
})->values()->all()
|
|
];
|
|
})->all()
|
|
]) }}">
|
|
|
|
<div class="text-center mt-4 mb-5">
|
|
<button type="button" id="btnSimpanNormalisasi" class="btn btn-success btn-lg">
|
|
<i class="fas fa-save me-2"></i>Simpan dan Lanjutkan
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Loading Overlay -->
|
|
<div id="loadingOverlay">
|
|
<div class="loading-content">
|
|
<div class="spinner-border text-light loading-spinner" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
<h5 class="mb-0">Memproses Data...</h5>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize tooltips
|
|
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
|
return new bootstrap.Tooltip(tooltipTriggerEl)
|
|
});
|
|
|
|
// Animate on scroll
|
|
AOS.init({
|
|
duration: 800,
|
|
easing: 'ease-in-out',
|
|
once: true,
|
|
mirror: false
|
|
});
|
|
|
|
// Handle form submission with confirmation
|
|
$('#btnSimpanNormalisasi').on('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Konfirmasi sebelum submit
|
|
Swal.fire({
|
|
title: 'Konfirmasi',
|
|
text: 'Apakah Anda yakin data perbandingan ini sudah benar dan ingin disimpan untuk proses normalisasi?',
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonText: 'Ya, Simpan',
|
|
cancelButtonText: 'Batal',
|
|
reverseButtons: true
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// Tampilkan loading overlay
|
|
$('#loadingOverlay').fadeIn();
|
|
// Submit form secara normal
|
|
$('#formNormalisasi').submit();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
@endpush
|