feat(daftar-pustaka) : tambah daftar pustaka dan categori pustaka, lihat detail, tambah, edit

This commit is contained in:
majid
2025-07-07 17:27:49 +07:00
committed by putrakuningan
parent 5c57b9cb58
commit 8220466f03
16 changed files with 1318 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
@extends('layouts.main')
@section('breadcrumbs')
{{-- {{ Breadcrumbs::render(request()->route()->getName()) }} --}}
@endsection
@section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<form
action="{{ isset($daftarPustaka->id) ? route('daftar-pustaka.update', $daftarPustaka->id) : route('daftar-pustaka.store') }}"
method="POST" enctype="multipart/form-data">
@csrf
@if (isset($daftarPustaka->id))
<input type="hidden" name="id" value="{{ $daftarPustaka->id }}">
@method('PUT')
@endif
<div class="card border border-agi-100 pb-2.5">
<div class="card-header bg-agi-50" id="basic_settings">
<h3 class="card-title">
{{ isset($daftarPustaka->id) ? 'Edit' : 'Tambah' }} Daftar Pustaka
</h3>
<div class="flex items-center gap-2">
<a href="{{ route('daftar-pustaka.index') }}" class="btn btn-xs btn-info"><i
class="ki-filled ki-exit-left"></i> Back</a>
</div>
</div>
<div class="card-body grid gap-5">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Judul
</label>
<div class="flex flex-wrap items-baseline w-full">
<input class="input @error('judul') border-danger bg-danger-light @enderror" type="text"
name="judul" value="{{ $daftarPustaka->judul ?? old('judul') }}">
@error('judul')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Upload File
</label>
<div class="flex flex-wrap items-baseline w-full">
<input class="input @error('attachment') border-danger bg-danger-light @enderror" type="file"
name="attachment">
@error('attachment')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
@if (isset($daftarPustaka->attachment))
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
File
</label>
<div class="flex flex-wrap items-baseline w-full">
{{-- ambil nama file pathnya hilangkan --}}
<a href="{{ asset($daftarPustaka->attachment) }}" class="badge badge-outline badge-md badge-info">{{ basename($daftarPustaka->attachment) }} &nbsp;
<i class="ki-filled ki-cloud-download"></i>
</a>
</div>
</div>
@endif
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Kategori
</label>
<div class="flex flex-wrap items-baseline w-full">
<select class="select tomselect w-full" name="category_id">
<option value="">Pilih Kategori</option>
@if (isset($categories))
@foreach ($categories as $item)
<option value="{{ $item->id }}"
{{ old('category_id', $daftarPustaka->category_id ?? '') == $item->id ? 'selected' : '' }}>
{{ $item->name }}
</option>
@endforeach
@endif
</select>
@error('category_id')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Deskripsi
</label>
<div class="flex flex-wrap items-baseline w-full">
<textarea name="deskripsi" class="textarea" id="" cols="30" rows="10">{{ $daftarPustaka->deskripsi ?? old('deskripsi') }}</textarea>
@error('deskripsi')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex justify-end">
<button type="submit" class="btn btn-primary">
{{ isset($daftarPustaka->id) ? 'Update' : 'Simpan' }}
</button>
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@@ -0,0 +1,307 @@
@extends('layouts.main')
@section('breadcrumbs')
{{-- {{ Breadcrumbs::render('basicdata.ijin_usaha') }} --}}
@endsection
@section('content')
<div class="flex flex-col items-stretch gap-7">
<div class="flex items-center gap-3 w-full">
<div class="input w-full">
<i class="ki-filled ki-magnifier">
</i>
<input id="search" placeholder="Search Daftar Pustaka, Judul" type="text">
<span class="badge badge-outline -me-1.5">
K
</span>
</div>
<!--Filter-->
<a class="btn btn-info" id="search_filter" onclick="filterSearch()">
<i class="ki-filled ki-filter">
</i>
Filter
</a>
<a class="btn btn-light" id="reset_filter" onclick="resetFilter()">
<i class="ki-filled ki-arrow-circle-left"></i>
Reset Filter
</a>
</div>
<div class="flex flex-wrap items-center gap-5 justify-between mt-3">
<h3 class="text-sm text-mono font-medium">
page {{ $page }} of {{ $pageCount }} {{ $limit }} items per page, total
{{ $total }} items.
</h3>
<div class="flex gap-2.5">
<select id="category_id" name="category_id" class="select tomselect w-[300px]" multiple>
<option value="" selected disabled>Filter by Category</option>
@foreach ($categories as $item)
<option value="{{ $item->id }}">{{ $item->name }}</option>
@endforeach
</select>
<div class="flex toggle-group" data-kt-tabs="true" data-kt-tabs-initialized="true">
<a class="btn btn-icon active selected" data-kt-tab-toggle="#daftar_pustaka_grid" onclick="showGrid()"
href="javascript:void(0)">
<i class="ki-filled ki-category"></i>
</a>
<a class="btn btn-icon" data-kt-tab-toggle="#daftar_pustaka_list" onclick="showList()"
href="javascript:void(0)">
<i class="ki-filled ki-row-horizontal"></i>
</a>
@if (auth()->user()->hasRole(['administrator', 'admin']))
<a href="{{ route('daftar-pustaka.create') }}" class="btn btn-primary">
<i class="ki-filled ki-plus"></i>
Tambah
</a>
@endif
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 " id="daftar_pustaka_grid">
@if (isset($daftar_pustaka))
@foreach ($daftar_pustaka as $item)
<div class="card border shadow-none ">
<a class="show-pustaka h-[300px] w-full block" href="{{ route('daftar-pustaka.show', $item->id) }}"
data-url="{{ $item->attachment }}">
<div class="p-4 h-full w-full flex items-center justify-center overflow-hidden">
<div class="preview-content h-full w-full"></div>
</div>
</a>
<div class="card-body">
<a href="{{ route('daftar-pustaka.show', $item->id) }}">
<h3 class="text-md font-medium text-gray-900 hover:text-primary cursor-pointer">
{{ $item->judul }}</h3>
<p class="text-2sm text-gray-700">
{{-- batasi panjang deskripsi 50 --}}
{{ substr($item->deskripsi, 0, 50) }}
</p>
</a>
<div class="flex justify-between items-center gap-2.5 mt-2">
<p class="badge rounded-full badge-sm badge-outline badge-success text-xs text-gray-700">
# {{ $item->category->name }}</p>
@auth
@if (auth()->user()->hasRole(['administrator', 'admin']))
<div>
<a class="btn btn-sm btn-danger" onclick="deleteData({{ $item->id }})">
<i class="ki-filled ki-trash">
</i>
Hapus
</a>
<a class="btn btn-sm btn-info"
href="{{ route('daftar-pustaka.edit', $item->id) }}">
<i class="ki-filled ki-pencil">
</i>
Edit
</a>
</div>
@endif
@endauth
</div>
</div>
</div>
@endforeach
@endif
</div>
<div class="grid grid-cols-1 gap-4 hidden" id="daftar_pustaka_list">
@if (isset($daftar_pustaka))
@foreach ($daftar_pustaka as $item)
<div class="card">
<div class="card-body flex items-center flex-wrap justify-between p-2 pe-5 gap-4.5">
<div class="flex items-center gap-3.5">
<div
class="kt-card flex items-center justify-center bg-accent/50 h-[70px] w-[90px] shadow-none">
<a class="show-pustaka h-[90px] w-full block"
href="{{ route('daftar-pustaka.show', $item->id) }}"
data-url="{{ $item->attachment }}">
<div class="p-4 h-full w-full flex items-center justify-center overflow-hidden">
<div class="preview-content h-full w-full"></div>
</div>
</a>
</div>
<div class="flex flex-col gap-2 cursor-pointer">
<a href="{{ route('daftar-pustaka.show', $item->id) }}">
<div class="flex items-center mt-1">
<a class="hover:text-primary text-sm font-medium text-mono leading-5.5">
{{ $item->judul }}
</a>
</div>
<div class="flex items-center flex-wrap gap-3">
<span class="kt-badge kt-badge-warning kt-badge-sm rounded-full gap-1">
<span class="text-xs font-medium text-foreground">
{{ substr($item->deskripsi, 0, 50) }}
</span>
</span>
</div>
</a>
</div>
</div>
<div class="flex items-center gap-1.5">
<p class="badge rounded-full badge-sm badge-outline badge-success text-xs text-gray-700">
# {{ $item->category->name }}</p>
@auth
@if (auth()->user()->hasRole(['administrator', 'admin']))
<div>
<a class="btn btn-sm btn-danger" onclick="deleteData({{ $item->id }})">
<i class="ki-filled ki-trash">
</i>
Hapus
</a>
<a class="btn btn-sm btn-info"
href="{{ route('daftar-pustaka.edit', $item->id) }}">
<i class="ki-filled ki-pencil">
</i>
Edit
</a>
</div>
@endif
@endauth
</div>
</div>
</div>
@endforeach
@endif
</div>
<div class="pagination flex gap-2 justify-center mt-5">
@if ($daftar_pustaka->onFirstPage())
<span class="btn disabled"><i class="ki-filled ki-black-left"></i></span>
@else
<a href="{{ $daftar_pustaka->previousPageUrl() }}" class="btn">
<i class="ki-filled ki-black-left"></i>
</a>
@endif
@foreach ($daftar_pustaka->getUrlRange(1, $daftar_pustaka->lastPage()) as $page => $url)
<a href="{{ $url }}" class="btn {{ $page == $daftar_pustaka->currentPage() ? 'active' : '' }}">
{{ $page }}
</a>
@endforeach
@if ($daftar_pustaka->hasMorePages())
<a href="{{ $daftar_pustaka->nextPageUrl() }}" class="btn">
<i class="ki-filled ki-black-right"></i>
</a>
@else
<span class="btn disabled"><i class="ki-filled ki-black-right"></i></span>
@endif
</div>
</div>
@endsection
@push('scripts')
<script src="{{ asset('vendor/pdfobject.min.js') }}"></script>
<script type="text/javascript">
function deleteData(data) {
Swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.isConfirmed) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
});
$.ajax(`daftar-pustaka/${data}`, {
type: 'DELETE'
}).then((response) => {
swal.fire('Deleted!', 'User has been deleted.', 'success').then(() => {
window.location.reload();
});
}).catch((error) => {
console.error('Error:', error);
Swal.fire('Error!', 'An error occurred while deleting the file.', 'error');
});
}
})
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.show-pustaka').forEach(function(element) {
const url = element.getAttribute('data-url');
const previewContent = element.querySelector('.preview-content');
if (!previewContent || !url) return;
const fileExtension = url.split('.').pop().toLowerCase();
if (fileExtension === 'pdf') {
PDFObject.embed(url, previewContent, {
height: "100%",
width: "100%"
});
} else if (['jpg', 'jpeg', 'png', 'gif'].includes(fileExtension)) {
previewContent.innerHTML = `
<img src="${url}" alt="Preview"
class="w-full h-full object-cover rounded" />
`;
} else {
previewContent.innerHTML = '<p class="text-center">Unsupported file type</p>';
}
});
});
function showGrid() {
document.getElementById("daftar_pustaka_grid").classList.remove("hidden");
document.getElementById("daftar_pustaka_grid").classList.add("active");
document.getElementById("daftar_pustaka_list").classList.add("hidden");
document.getElementById("daftar_pustaka_list").classList.remove("active");
// Update button active class
document.querySelectorAll(".toggle-group a").forEach(btn => btn.classList.remove("selected", "active"));
event.currentTarget.classList.add("selected", "active");
}
function showList() {
document.getElementById("daftar_pustaka_list").classList.remove("hidden");
document.getElementById("daftar_pustaka_list").classList.add("active");
document.getElementById("daftar_pustaka_grid").classList.add("hidden");
document.getElementById("daftar_pustaka_grid").classList.remove("active");
// Update button active class
document.querySelectorAll(".toggle-group a").forEach(btn => btn.classList.remove("selected", "active"));
event.currentTarget.classList.add("selected", "active");
}
function filterSearch() {
const search = document.getElementById('search')?.value || '';
const select = document.getElementById('category_id');
const selectedCategories = Array.from(select.selectedOptions).map(option => option.value);
const categoryParam = selectedCategories.join(',');
const url = "{{ route('daftar-pustaka.index') }}?search=" + encodeURIComponent(search) + "&category=" +
encodeURIComponent(categoryParam);
window.location.href = url;
}
function resetFilter() {
const url = "{{ route('daftar-pustaka.index') }}";
window.location.href = url;
}
</script>
@endpush

View File

@@ -0,0 +1,71 @@
@extends('layouts.main')
@section('breadcrumbs')
{{-- {{ Breadcrumbs::render(request()->route()->getName()) }} --}}
@endsection
@section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<form
action="{{ isset($daftarPustaka->id) ? route('daftar-pustaka.update', $daftarPustaka->id) : route('daftar-pustaka.store') }}"
method="POST">
@csrf
<div class="card border border-agi-100 pb-2.5">
<div class="card-header bg-agi-50" id="basic_settings">
<h3 class="card-title">
{{ $daftarPustaka->judul ?? '' }}
</h3>
<div class="flex items-center gap-2">
<a href="{{ route('daftar-pustaka.index') }}" class="btn btn-xs btn-info"><i
class="ki-filled ki-exit-left"></i> Back</a>
</div>
</div>
<div class="card-body grid gap-5">
<div
class=" min-w-3xl w-[1280px] h-[768px]">
<div class="p-4 h-full flex flex-col">
<div class="flex justify-between items-center mb-4">
<button type="button" id="downloadBtn" class="btn btn-primary btn-sm">
<i class="ki-duotone ki-cloud-download me-1"><span class="path1"></span><span
class="path2"></span></i>
Download File
</button>
</div>
<div id="previewContent" class="flex-grow"></div>
</div>
</div>
<div class="border border-t">
</div>
<div>
{{ $daftarPustaka->deskripsi ?? '' }}
</div>
</div>
</div>
</form>
</div>
@endsection
@push('scripts')
<script src="{{ asset('vendor/pdfobject.min.js') }}"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
let url = @json($daftarPustaka->attachment);
console.log(url);
const fileExtension = url.split('.').pop().toLowerCase();
const previewContent = document.getElementById('previewContent');
if (['pdf'].includes(fileExtension)) {
PDFObject.embed(url, "#previewContent");
} else if (['jpg', 'jpeg', 'png', 'gif'].includes(fileExtension)) {
previewContent.innerHTML =
`<img src="${url}" alt="Preview" class="max-w-full max-h-full object-contain">`;
} else {
previewContent.innerHTML = '<p class="text-center">Unsupported file type</p>';
}
});
</script>
@endpush