initial commit

This commit is contained in:
2026-06-06 10:05:39 +07:00
commit b22608adbc
1577 changed files with 641460 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Illuminate\Support\Facades\Auth;
class AdminController extends Controller
{
public function new_user(Request $request)
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
'user_type' => ['required', 'string'],
'created_by' => ['required', 'integer'],
]);
if ($request->user_type === 'admin') {
return redirect()->back()->withErrors(['user_type' => 'Invalid user type.']);
}
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'user_type' => $request->user_type,
'created_by' => $request->created_by,
]);
return redirect()->route('admin_dashboard')->with('success', 'User created successfully!');
}
public function index(Request $request)
{
$query = User::query();
$query->where('created_by', Auth::id());
if ($request->filled('role') && $request->role !== '') {
$query->where('user_type', $request->role);
}
if ($request->filled('email')) {
$query->where('email', 'like', '%' . $request->email . '%');
}
if ($request->filled('name')) {
$query->where('name', 'like', '%' . $request->name . '%');
}
$users = $query->orderBy('created_at', 'desc')->simplePaginate(15);
return view('admin_dashboard', compact('users'));
}
public function editUser($id)
{
$user = User::findOrFail($id);
$currentUserId = auth()->id();
if ($user->created_by != $currentUserId) {
return redirect()->route('admin_dashboard')->with('error', 'You do not have permission to edit this user.');
}
return view('edit_user_form', compact('user'));
}
public function updateUser(Request $request, $id)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users,email,' . $id,
'password' => 'sometimes|nullable|string|min:8|confirmed',
'user_type' => 'required|string',
]);
$user = User::findOrFail($id);
$currentUserId = auth()->id();
if ($user->created_by != $currentUserId) {
return redirect()->route('admin_dashboard')->with('error', 'You do not have permission to edit this user.');
}
$user->name = $request->name;
$user->email = $request->email;
if ($request->password) {
$user->password = Hash::make($request->password);
}
$user->user_type = $request->user_type;
$user->save();
return redirect()->route('admin_dashboard')->with('success', 'User updated successfully.');
}
public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return redirect()->route('admin_dashboard')->with('success', 'User deleted successfully.');
}
public function request_log()
{
$currentUserId = Auth::id();
$users = User::where('created_by', $currentUserId)->get();
return view('request_log', compact('users'));
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*/
public function create(): View
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*/
public function store(LoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(route('dashboard', absolute: false));
}
/**
* Destroy an authenticated session.
*/
public function destroy(Request $request): RedirectResponse
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
@@ -0,0 +1,40 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
class ConfirmablePasswordController extends Controller
{
/**
* Show the confirm password view.
*/
public function show(): View
{
return view('auth.confirm-password');
}
/**
* Confirm the user's password.
*/
public function store(Request $request): RedirectResponse
{
if (! Auth::guard('web')->validate([
'email' => $request->user()->email,
'password' => $request->password,
])) {
throw ValidationException::withMessages([
'password' => __('auth.password'),
]);
}
$request->session()->put('auth.password_confirmed_at', time());
return redirect()->intended(route('dashboard', absolute: false));
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class EmailVerificationNotificationController extends Controller
{
/**
* Send a new email verification notification.
*/
public function store(Request $request): RedirectResponse
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->intended(route('dashboard', absolute: false));
}
$request->user()->sendEmailVerificationNotification();
return back()->with('status', 'verification-link-sent');
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class EmailVerificationPromptController extends Controller
{
/**
* Display the email verification prompt.
*/
public function __invoke(Request $request): RedirectResponse|View
{
return $request->user()->hasVerifiedEmail()
? redirect()->intended(route('dashboard', absolute: false))
: view('auth.verify-email');
}
}
@@ -0,0 +1,61 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;
use Illuminate\View\View;
class NewPasswordController extends Controller
{
/**
* Display the password reset view.
*/
public function create(Request $request): View
{
return view('auth.reset-password', ['request' => $request]);
}
/**
* Handle an incoming new password request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'token' => ['required'],
'email' => ['required', 'email'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user) use ($request) {
$user->forceFill([
'password' => Hash::make($request->password),
'remember_token' => Str::random(60),
])->save();
event(new PasswordReset($user));
}
);
// 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
// redirect them back to where they came from with their error message.
return $status == Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}
@@ -0,0 +1,29 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
class PasswordController extends Controller
{
/**
* Update the user's password.
*/
public function update(Request $request): RedirectResponse
{
$validated = $request->validateWithBag('updatePassword', [
'current_password' => ['required', 'current_password'],
'password' => ['required', Password::defaults(), 'confirmed'],
]);
$request->user()->update([
'password' => Hash::make($validated['password']),
]);
return back()->with('status', 'password-updated');
}
}
@@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\View\View;
class PasswordResetLinkController extends Controller
{
/**
* Display the password reset link request view.
*/
public function create(): View
{
return view('auth.forgot-password');
}
/**
* Handle an incoming password reset link request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'email' => ['required', 'email'],
]);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}
@@ -0,0 +1,50 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Illuminate\View\View;
class RegisteredUserController extends Controller
{
/**
* Display the registration view.
*/
public function create(): View
{
return view('auth.register');
}
/**
* Handle an incoming registration request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(route('dashboard', absolute: false));
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\Verified;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\RedirectResponse;
class VerifyEmailController extends Controller
{
/**
* Mark the authenticated user's email address as verified.
*/
public function __invoke(EmailVerificationRequest $request): RedirectResponse
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect()->intended(route('dashboard', absolute: false).'?verified=1');
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace App\Http\Controllers;
abstract class Controller
{
//
}
@@ -0,0 +1,55 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\operation as Operation;
use Illuminate\Http\request;
class DashboardController extends Controller
{
public function getUsersByRoleData()
{
// Mengambil jumlah data berdasarkan user_type
$usersByRoleData = User::selectRaw('user_type, count(*) as count')
->groupBy('user_type')
->orderBy('user_type')
->pluck('count')
->toArray();
// Jika terdapat user_type yang belum memiliki data, inisialisasi dengan 0
$usersByRoleData = array_pad($usersByRoleData, 5, 0);
return response()->json(['data' => $usersByRoleData]);
}
public function getDataJenisTerapi()
{
// Mengambil jumlah data berdasarkan jenis_terapi
$dataJenisTerapi = Operation::selectRaw('jenis_terapi, count(*) as count')
->groupBy('jenis_terapi')
->orderBy('jenis_terapi')
->pluck('count')
->toArray();
// Jika terdapat jenis_terapi yang belum memiliki data, inisialisasi dengan 0
$dataJenisTerapi = array_pad($dataJenisTerapi, 3, 0);
return response()->json(['data' => $dataJenisTerapi]);
}
public function getDataJenisKelamin()
{
// Mengambil jumlah data berdasarkan kelamin
$dataJenisKelamin = Operation::selectRaw('kelamin, count(*) as count')
->groupBy('kelamin')
->orderBy('kelamin')
->pluck('count')
->toArray();
// Jika terdapat kelamin yang belum memiliki data, inisialisasi dengan 0
$dataJenisKelamin = array_pad($dataJenisKelamin, 2, 0);
return response()->json(['data' => $dataJenisKelamin]);
}
}
@@ -0,0 +1,521 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\operation;
use App\Models\photo;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use ZipArchive;
use App\Http\Controllers\RequestController;
class OperationController extends Controller
{
public function store(Request $request)
{
try {
// Validate the request data
$validated = $request->validate([
'nama' => 'required|string|max:255',
'tanggal_lahir' => 'required|date',
'umur' => 'required|integer',
'alamat' => 'required|string|max:255',
'suku' => 'required|string|max:255',
'kelamin' => 'required|string|in:Laki-laki,Perempuan',
'anak_ke' => 'required|integer',
'riwayathamil' => 'required|string',
'riwayatkeluarga' => 'required|string',
'riwayat_kawin_kerabat' => 'required|string',
'riwayat_penyakit_terdahulu' => 'required|string',
'kelainan_kongenital' => 'required|string|max:255',
'jenis_cleft' => 'required|string|in:sindromik,non_sindromik',
'jenis_terapi' => 'required|string|in:labioplasty,palatoplasty,gnatoplasty',
'diagnosa' => 'required|string|in:labioschisis,palatoschisis,labiopalatoschisis,labiognatoschisis,labiopalatognatoschisis',
'tanggal_operasi' => 'required|date',
'teknikoperasi' => 'required|string|max:255',
'operator' => 'required|string|max:255',
'lokasioperasi' => 'required|string|max:255',
'followup' => 'required|string',
'created_by_id' => 'required|integer',
'created_by_name' => 'required|string|max:255',
'photos_pre_op' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
'photos_post_op' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
'photos_kontrol' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
]);
// Check for existing operation with the same nama, tanggal_lahir, and tanggal_operasi
$existingOperation = operation::where('nama', $validated['nama'])
->where('tanggal_lahir', $validated['tanggal_lahir'])
->where('tanggal_operasi', $validated['tanggal_operasi'])
// ->where('teknikoperasi', $validated['teknikoperasi'])
->first();
if ($existingOperation) {
return redirect()->back()->with('error', 'Terdapat data dengan Nama Pasien, Tanggal lahir, Tanggal operasi yang sama, Pastikan Data yang diinput bukan duplikat')->withInput();
}
// Create the operation
$operation = operation::create($validated);
// Handle photo uploads
$categories = ['pre_op', 'post_op', 'kontrol'];
foreach ($categories as $category) {
if ($request->hasFile("photos_$category")) {
$file = $request->file("photos_$category");
$fileName = time() . '_' . $category . '.' . $file->getClientOriginalExtension();
$file->move(public_path('photos'), $fileName);
photo::create([
'operation_id' => $operation->id,
// 'gambar' => 'photos/' . $fileName,
// Kalo pake server humic yang aneh pake yang dibawah ini, yang atas ini dikomen
'gambar' => 'public/photos/' . $fileName,
'kategori' => $category,
]);
}
}
return redirect()->route('upload_data')->with('success', 'Operation created successfully!');
} catch (\Exception $e) {
return redirect()->back()->with('error', 'An error occurred while creating the operation. ' . $e->getMessage());
}
}
public function index(Request $request)
{
$query = Operation::query();
if ($request->filled('pengunggah')) {
$query->where('created_by_name', 'like', '%' . $request->pengunggah . '%');
}
if ($request->filled('teknik')) {
$query->where('teknikoperasi', 'like', '%' . $request->teknik . '%');
}
if ($request->filled('gender') && $request->gender !== 'Semua') {
$query->where('kelamin', $request->gender);
}
if ($request->filled('umur_min')) {
$query->where('umur', '>=', $request->umur_min);
}
if ($request->filled('umur_max')) {
$query->where('umur', '<=', $request->umur_max);
}
if ($request->filled('nama_pasien')) {
$query->where('nama', 'like', '%' . $request->nama_pasien . '%');
}
$totalCount = $query->count();
$operations = $query->orderBy('created_at', 'desc')->simplePaginate(15);
$displayedCount = $operations->count();
return view('browse_data', compact('operations', 'totalCount', 'displayedCount'));
}
public function mydata(Request $request)
{
$userId = auth()->user()->id;
$query = Operation::where('created_by_id', $userId);
if ($request->filled('nama_pasien')) {
$query->where('nama', 'like', '%' . $request->nama_pasien . '%');
}
if ($request->filled('teknik')) {
$query->where('teknikoperasi', 'like', '%' . $request->teknik . '%');
}
if ($request->filled('gender') && $request->gender !== 'Semua') {
$query->where('kelamin', $request->gender);
}
if ($request->filled('umur_min')) {
$query->where('umur', '>=', $request->umur_min);
}
if ($request->filled('umur_max')) {
$query->where('umur', '<=', $request->umur_max);
}
$totalCount = $query->count();
$operations = $query->orderBy('created_at', 'desc')->simplePaginate(15);
$displayedCount = $operations->count();
return view('my_data', compact('operations', 'totalCount', 'displayedCount'));
}
public function edit(operation $operation)
{
// Check if the current authenticated user is the creator of the operation
if ($operation->created_by_id == Auth::id()) {
$preOpPhoto = photo::where('operation_id', $operation->id)->where('kategori', 'pre_op')->first();
$kontrolPhoto = photo::where('operation_id', $operation->id)->where('kategori', 'kontrol')->first();
$postOpPhoto = photo::where('operation_id', $operation->id)->where('kategori', 'post_op')->first();
return view('edit_data', compact('operation', 'preOpPhoto', 'kontrolPhoto', 'postOpPhoto'));
}
// If the user is not the creator, you can redirect them or show an error message
return redirect()->route('dashboard')->with('error', 'You do not have permission to edit this operation.');
}
public function update(Request $request, operation $operation)
{
// Check if the current authenticated user is the creator of the operation
if ($operation->created_by_id != Auth::id()) {
return redirect()->route('dashboard')->with('error', 'You do not have permission to update this operation.');
}
try{
// Validate the request data
$validated = $request->validate([
'nama' => 'required|string|max:255',
'tanggal_lahir' => 'required|date',
'umur' => 'required|integer',
'alamat' => 'required|string|max:255',
'suku' => 'required|string|max:255',
'kelamin' => 'required|string|in:Laki-laki,Perempuan',
'anak_ke' => 'required|integer',
'riwayathamil' => 'required|string',
'riwayatkeluarga' => 'required|string',
'riwayat_kawin_kerabat' => 'required|string',
'riwayat_penyakit_terdahulu' => 'required|string',
'kelainan_kongenital' => 'required|string|max:255',
'jenis_cleft' => 'required|string|in:sindromik,non_sindromik',
'jenis_terapi' => 'required|string|in:labioplasty,palatoplasty,gnatoplasty',
'diagnosa' => 'required|string|in:labioschisis,palatoschisis,labiopalatoschisis,labiognatoschisis,labiopalatognatoschisis',
'tanggal_operasi' => 'required|date',
'teknikoperasi' => 'required|string|max:255',
'operator' => 'required|string|max:255',
'lokasioperasi' => 'required|string|max:255',
'followup' => 'required|string',
'photos_pre_op' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
'photos_post_op' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
'photos_kontrol' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
]);
// Update the operation
$operation->update($validated);
// Handle photo uploads
$categories = ['pre_op', 'post_op', 'kontrol'];
foreach ($categories as $category) {
if ($request->hasFile("photos_$category")) {
$file = $request->file("photos_$category");
$fileName = time() . '_' . $category . '.' . $file->getClientOriginalExtension();
// Find existing photo or create a new one
$photo = photo::where('operation_id', $operation->id)->where('kategori', $category)->first();
if ($photo) {
// Delete the old photo file
if (File::exists(public_path($photo->gambar))) {
File::delete(public_path($photo->gambar));
}
// Update the photo record
$file->move(public_path('photos'), $fileName);
// $photo->update(['gambar' => 'photos/' . $fileName]);
// Kalo pake server humic yang aneh pake yang dibawah ini, yang atas ini dikomen
$photo->update(['gambar' => 'public/photos/' . $fileName]);
} else {
// Create a new photo record
$file->move(public_path('photos'), $fileName);
photo::create([
'operation_id' => $operation->id,
// 'gambar' => 'photos/' . $fileName,
// Kalo pake server humic yang aneh pake yang dibawah ini, yang atas ini dikomen
'gambar' => 'public/photos/' . $fileName,
'kategori' => $category,
]);
}
}
}
return redirect()->route('my_data')->with('success', 'Operation updated successfully!');
} catch (\Exception $e) {
return redirect()->back()->with('error', 'An error occurred while updating the operation. ' . $e->getMessage());
}
}
public function show($id)
{
$operation = operation::findOrFail($id);
$preOpPhoto = photo::where('operation_id', $operation->id)->where('kategori', 'pre_op')->first();
$kontrolPhoto = photo::where('operation_id', $operation->id)->where('kategori', 'kontrol')->first();
$postOpPhoto = photo::where('operation_id', $operation->id)->where('kategori', 'post_op')->first();
return view('specific_data', compact('operation', 'preOpPhoto', 'kontrolPhoto', 'postOpPhoto'));
}
public function request_data($id)
{
$operation = operation::findOrFail($id);
return view('request_specific_data', compact('operation'));
}
// public function store_request_data(Request $request)
// {
// // Validate the request data
// $validated = $request->validate([
// 'nama_lengkap' => 'required|string|max:255',
// 'nomor_handphone' => 'required|integer',
// 'email' => 'required|string',
// 'nik' => 'required|integer',
// 'jenis_pengajuan' => 'required|string',
// 'tujuan_permohonan' => 'required|string',
// ]);
// // Create the request
// $operation = Operation::create([
// ]);
// return redirect()->route('upload_data')->with('success', 'Operation created successfully!');
// }
public function destroy(operation $operation)
{
// Check if the user has permission to delete this operation
if ($operation->created_by_id != Auth::id()) {
return redirect()->back()->with('error', 'You do not have permission to delete this operation.');
}
try {
DB::beginTransaction();
// Delete related photos first
photo::where('operation_id', $operation->id)->delete();
// Now delete the operation
$operation->delete();
DB::commit();
return redirect()->route('my_data')->with('success', 'Operation and related photos deleted successfully.');
} catch (\Exception $e) {
DB::rollBack();
return redirect()->back()->with('error', 'An error occurred while deleting the operation. ' . $e->getMessage());
}
}
public function download($id)
{
$operation = operation::findOrFail($id);
// Create a text file with operation data
$textContent = "";
foreach ($operation->getAttributes() as $key => $value) {
if (!in_array($key, ['id', 'created_by_id'])) {
$textContent .= ucfirst(str_replace('_', ' ', $key)) . ": " . $value . "\n";
}
}
$zipFileName = "operation_{$id}_data.zip";
$zipFilePath = storage_path("app/{$zipFileName}");
$zip = new \ZipArchive();
if ($zip->open($zipFilePath, \ZipArchive::CREATE) === TRUE) {
$zip->addFromString('operation_data.txt', $textContent);
// Add photos to the zip file
$photoCategories = ['pre_op', 'post_op'];
foreach ($photoCategories as $category) {
$photo = photo::where('operation_id', $operation->id)
->where('kategori', $category)
->first();
if ($photo) {
// Remove 'public/' from the beginning of the path
$relativePath = str_replace('public/', '', $photo->gambar);
$photoPath = public_path($relativePath);
if (file_exists($photoPath)) {
$zip->addFile($photoPath, $category . '_photo.' . pathinfo($photoPath, PATHINFO_EXTENSION));
}
}
}
$zip->close();
}
return response()->download($zipFilePath)->deleteFileAfterSend(true);
}
public function downall(Request $request)
{
function getExcelColumn($n) {
$string = '';
while ($n > 0) {
$n--;
$string = chr(65 + ($n % 26)) . $string;
$n = intdiv($n, 26);
}
return $string;
}
$query = Operation::query();
// Apply filters if they exist
if ($request->filled('pengunggah')) {
$query->where('created_by_name', 'like', '%' . $request->pengunggah . '%');
}
if ($request->filled('teknik')) {
$query->where('teknikoperasi', 'like', '%' . $request->teknik . '%');
}
if ($request->filled('gender') && $request->gender !== 'Semua') {
$query->where('kelamin', $request->gender);
}
if ($request->filled('umur_min')) {
$query->where('umur', '>=', $request->umur_min);
}
if ($request->filled('umur_max')) {
$query->where('umur', '<=', $request->umur_max);
}
if ($request->filled('nama_pasien')) {
$query->where('nama', 'like', '%' . $request->nama_pasien . '%');
}
$operations = $query->get();
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// Set headers
$headers = ['ID', 'Nama', 'Tanggal Lahir', 'Umur', 'Alamat', 'Suku', 'Kelamin', 'Anak Ke', 'Riwayat Hamil', 'Riwayat Keluarga', 'Riwayat Kawin Kerabat', 'Riwayat Penyakit Terdahulu', 'Kelainan Kongenital', 'Jenis Cleft', 'Jenis Terapi', 'Diagnosa', 'Tanggal Operasi', 'Teknik Operasi', 'Operator', 'Lokasi Operasi', 'Follow Up', 'Created By Name', 'Created At', 'Updated At', 'Pre Op Photo', 'Post Op Photo', 'Kontrol Photo'];
$sheet->fromArray([$headers], NULL, 'A1');
// Populate data
$row = 2;
foreach ($operations as $operation) {
$data = [
$operation->id,
$operation->nama,
$operation->tanggal_lahir,
$operation->umur,
$operation->alamat,
$operation->suku,
$operation->kelamin,
$operation->anak_ke,
$operation->riwayathamil,
$operation->riwayatkeluarga,
$operation->riwayat_kawin_kerabat,
$operation->riwayat_penyakit_terdahulu,
$operation->kelainan_kongenital,
$operation->jenis_cleft,
$operation->jenis_terapi,
$operation->diagnosa,
$operation->tanggal_operasi,
$operation->teknikoperasi,
$operation->operator,
$operation->lokasioperasi,
$operation->followup,
$operation->created_by_name,
$operation->created_at,
$operation->updated_at,
];
$sheet->fromArray([$data], NULL, 'A' . $row);
// Add photos
$photoCategories = ['pre_op', 'post_op'];
$col = 25; // Start from column Y
foreach ($photoCategories as $category) {
$photo = photo::where('operation_id', $operation->id)
->where('kategori', $category)
->first();
if ($photo) {
$relativePath = str_replace('public/', '', $photo->gambar);
$photoPath = public_path($relativePath);
if (file_exists($photoPath)) {
$drawing = new Drawing();
$drawing->setName($category);
$drawing->setDescription($category);
$drawing->setPath($photoPath);
$drawing->setCoordinates(getExcelColumn($col) . $row);
$drawing->setWidth(100);
$drawing->setHeight(100);
$drawing->setWorksheet($sheet);
$sheet->getColumnDimension(getExcelColumn($col))->setWidth(15);
$sheet->getRowDimension($row)->setRowHeight(75);
}
}
$col++;
}
$row++;
}
// Auto-size columns
foreach (range('A', 'X') as $column) {
$sheet->getColumnDimension($column)->setAutoSize(true);
}
$writer = new Xlsx($spreadsheet);
$excelFilename = 'operations_data_' . time() . '.xlsx';
$zipFilename = 'operations_data_' . time() . '.zip';
$excelFilePath = storage_path('app/temp/' . $excelFilename);
$zipFilePath = storage_path('app/temp/' . $zipFilename);
// Ensure the temp directory exists
if (!file_exists(storage_path('app/temp'))) {
mkdir(storage_path('app/temp'), 0755, true);
}
// Save Excel file
$writer->save($excelFilePath);
// Create ZIP file
$zip = new ZipArchive();
if ($zip->open($zipFilePath, ZipArchive::CREATE) === TRUE) {
$zip->addFile($excelFilePath, $excelFilename);
// Add photos to ZIP
foreach ($operations as $operation) {
foreach ($photoCategories as $category) {
$photo = photo::where('operation_id', $operation->id)
->where('kategori', $category)
->first();
if ($photo) {
$relativePath = str_replace('public/', '', $photo->gambar);
$photoPath = public_path($relativePath);
if (file_exists($photoPath)) {
$zip->addFile($photoPath, "photos/{$operation->id}_{$category}." . pathinfo($photoPath, PATHINFO_EXTENSION));
}
}
}
}
$zip->close();
// Delete the Excel file after adding it to the zip
unlink($excelFilePath);
// Set headers for download
$headers = [
'Content-Type' => 'application/zip',
'Content-Disposition' => 'attachment; filename="' . $zipFilename . '"',
'Content-Length' => filesize($zipFilePath),
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
'Pragma' => 'no-cache',
];
// Return the file download response
return response()->download($zipFilePath, $zipFilename, $headers)->deleteFileAfterSend(true);
} else {
return redirect()->back()->with('error', 'Failed to create zip file');
}
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PhotoController extends Controller
{
//
}
@@ -0,0 +1,60 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ProfileUpdateRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\View\View;
class ProfileController extends Controller
{
/**
* Display the user's profile form.
*/
public function edit(Request $request): View
{
return view('profile.edit', [
'user' => $request->user(),
]);
}
/**
* Update the user's profile information.
*/
public function update(ProfileUpdateRequest $request): RedirectResponse
{
$request->user()->fill($request->validated());
if ($request->user()->isDirty('email')) {
$request->user()->email_verified_at = null;
}
$request->user()->save();
return Redirect::route('profile.edit')->with('status', 'profile-updated');
}
/**
* Delete the user's account.
*/
public function destroy(Request $request): RedirectResponse
{
$request->validateWithBag('userDeletion', [
'password' => ['required', 'current_password'],
]);
$user = $request->user();
Auth::logout();
$user->delete();
$request->session()->invalidate();
$request->session()->regenerateToken();
return Redirect::to('/');
}
}
+219
View File
@@ -0,0 +1,219 @@
<?php
namespace App\Http\Controllers;
use App\Models\request as DataRequest; // Renamed to avoid conflict with Illuminate\Http\Request
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RequestController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([
'nama' => 'required|string|max:255',
'handphone' => 'required|string|max:255',
'email' => 'required|email|max:255',
'nik' => 'required|string|max:255',
'kategori' => 'required|string|max:255',
'tujuan' => 'required|string',
'created_by_id' => 'required|exists:users,id',
'operation_id' => 'nullable|exists:operations,id',
]);
$validated['status'] = 'Pending';
$validated['keterangan'] = '';
// Check if operation_id is present in the request
if ($request->has('operation_id')) {
$validated['operation_id'] = $request->operation_id;
} else {
// If operation_id is not in the request, set it to null
$validated['operation_id'] = null;
}
DataRequest::create($validated);
if ($validated['operation_id']) {
return redirect()->route('operations.show', ['id' => $validated['operation_id']])
->with('success', 'Your request has been submitted successfully.');
} else {
return redirect()->route('browse_data')
->with('success', 'Your request for all data has been submitted successfully.');
}
}
// public function index()
// {
// return view('request_log');
// }
// public function getData(Request $request)
// {
// $query = DataRequest::query();
// if ($request->filled('category')) {
// $query->where('kategori', $request->category);
// }
// if ($request->filled('status') && $request->status !== '') {
// $query->where('status', $request->status);
// }
// // Remove the else clause that was setting the default to 'Pending'
// if ($request->filled('email')) {
// $query->where('email', 'like', '%' . $request->email . '%');
// }
// if ($request->filled('name')) {
// $query->where('nama', 'like', '%' . $request->name . '%');
// }
// $requests = $query->orderBy('created_at', 'desc')->paginate(1);
// return view('partials.requests_table', compact('requests'))->render();
// }
public function index(Request $request)
{
$query = DataRequest::query();
if ($request->filled('category')) {
$query->where('kategori', $request->category);
}
if ($request->filled('status') && $request->status !== 'all') {
$query->where('status', $request->status);
}
if ($request->filled('email')) {
$query->where('email', 'like', '%' . $request->email . '%');
}
if ($request->filled('name')) {
$query->where('nama', 'like', '%' . $request->name . '%');
}
$requests = $query->orderBy('created_at', 'desc')->simplePaginate(15)->appends($request->all());
return view('request_log', compact('requests'));
}
public function show($id)
{
$request = DataRequest::findOrFail($id);
return view('request_log_specific_user', compact('request'));
}
public function destroy($id)
{
$request = DataRequest::findOrFail($id);
$request->delete();
return redirect()->route('request_log')->with('success', 'Request deleted successfully');
}
public function approve($id)
{
$request = DataRequest::findOrFail($id);
$request->update([
'status' => 'Approved',
'keterangan' => 'Request approved'
]);
return redirect()->route('requests.show', $id)->with('success', 'Request has been approved.');
}
public function reject(Request $httpRequest, $id)
{
$request = DataRequest::findOrFail($id);
$request->update([
'status' => 'Rejected',
'keterangan' => $httpRequest->keterangan
]);
return redirect()->route('requests.show', $id)->with('success', 'Request has been rejected.');
}
public function checkLatestRequest($operationId)
{
$request = DataRequest::where('operation_id', $operationId)
->where('created_by_id', Auth::id())
->latest()
->first();
return response()->json(['request' => $request]);
}
public function getRejectionReason($operationId)
{
$request = DataRequest::where('operation_id', $operationId)
->where('created_by_id', Auth::id())
->where('status', 'Rejected')
->latest()
->first();
return response()->json(['keterangan' => $request ? $request->keterangan : 'No reason provided']);
}
public function cancelRequest($operationId)
{
$user = Auth::user();
$request = DataRequest::where('operation_id', $operationId)
->where('created_by_id', $user->id)
->where('status', 'Pending')
->latest()
->first();
if ($request) {
$request->delete();
return redirect()->route('operations.show', ['id' => $operationId])
->with('success', 'Request cancelled successfully');
}
return redirect()->route('operations.show', ['id' => $operationId])
->with('error', 'No pending request found to cancel');
}
public function reqall()
{
return view('request_all_data');
}
public function checkAllDataRequest()
{
$user = Auth::user();
return DataRequest::where('created_by_id', $user->id)
->whereNull('operation_id')
->latest()
->first();
}
public function cancelAllRequest()
{
$user = Auth::user();
$request = DataRequest::where('created_by_id', $user->id)
->whereNull('operation_id')
->where('status', 'Pending')
->latest()
->first();
if ($request) {
$request->delete();
return redirect()->route('browse_data')
->with('success', 'All data request cancelled successfully');
}
return redirect()->route('browse_data')
->with('error', 'No pending request found to cancel');
}
public static function checkAllDataRequestforOp()
{
$user = Auth::user();
return DataRequest::where('created_by_id', $user->id)
->whereNull('operation_id')
->latest()
->first();
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AdminCheck
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (auth()->user()->user_type !== 'admin') {
return redirect()->route('landing');
}
return $next($request);
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use App\Http\Controllers\RequestController;
class CheckApprovedAllDataRequest
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
$latestRequest = RequestController::checkAllDataRequestforOp();
if (!$latestRequest || $latestRequest->status !== 'Approved') {
return redirect()->back()->with('error', 'You do not have an approved request to download all data.');
}
return $next($request);
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class OperatorHigherCheck
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (auth()->user()->user_type == 'operator' || auth()->user()->user_type == 'admin') {
return $next($request);
}
return redirect()->route('landing');
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate(): void
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited(): void
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*/
public function throttleKey(): string
{
return Str::transliterate(Str::lower($this->string('email')).'|'.$this->ip());
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Requests;
use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class ProfileUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)],
];
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'user_type',
'created_by',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class operation extends Model
{
use HasFactory;
protected $fillable = [
'nama',
'umur',
'tanggal_lahir',
'suku',
'kelamin',
'alamat',
'anak_ke',
'riwayathamil',
'riwayatkeluarga',
'riwayat_penyakit_terdahulu',
'riwayat_kawin_kerabat',
'diagnosa',
'jenis_terapi',
'jenis_cleft',
'kelainan_kongenital',
'tanggal_operasi',
'teknikoperasi',
'operator',
'lokasioperasi',
'followup',
'created_by_id',
'created_by_name',
];
protected $dates = ['tanggal_lahir', 'tanggal_operasi'];
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class photo extends Model
{
use HasFactory;
protected $fillable = [
'operation_id', 'gambar', 'kategori',
];
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class request extends Model
{
use HasFactory;
protected $fillable = [
'nama', 'handphone', 'email', 'nik', 'kategori', 'tujuan', 'status', 'keterangan', 'created_by_id', 'operation_id',
];
protected $nullable = ['operation_id'];
public function operation()
{
return $this->belongsTo(Operation::class);
}
public function createdBy()
{
return $this->belongsTo(User::class, 'created_by_id');
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
if($this->app->environment('production')) {
\URL::forceScheme('https');
}
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\View\Components;
use Illuminate\View\Component;
use Illuminate\View\View;
class AppLayout extends Component
{
/**
* Get the view / contents that represents the component.
*/
public function render(): View
{
return view('layouts.app');
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\View\Components;
use Illuminate\View\Component;
use Illuminate\View\View;
class GuestLayout extends Component
{
/**
* Get the view / contents that represents the component.
*/
public function render(): View
{
return view('layouts.guest');
}
}