update tgl 14 juni
This commit is contained in:
parent
20eeb0c646
commit
621fec5d21
|
@ -13,7 +13,6 @@ public function logout(Request $request)
|
||||||
Session::flush();
|
Session::flush();
|
||||||
Auth::logout();
|
Auth::logout();
|
||||||
|
|
||||||
return redirect()->route('login')
|
return redirect()->route('login');
|
||||||
->with('success', 'Anda berhasil logout.');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use App\Models\DataKaryawanModel;
|
use App\Models\DataKaryawanModel;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
class DataKaryawanController extends Controller
|
class DataKaryawanController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -18,18 +19,29 @@ public function store(Request $request)
|
||||||
// Validasi input
|
// Validasi input
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'nama' => 'required|string|max:100',
|
'nama' => 'required|string|max:100',
|
||||||
'usia' => 'required|integer|min:17|max:65',
|
'tanggal_lahir' => 'required|date',
|
||||||
'jabatan' => 'required|string|max:50',
|
'jabatan' => 'required|string|max:50',
|
||||||
'gaji' => 'required'
|
'gaji' => 'required'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Hitung usia
|
||||||
|
$tanggalLahir = Carbon::parse($request->tanggal_lahir);
|
||||||
|
$usia = $tanggalLahir->age;
|
||||||
|
|
||||||
|
// Validasi usia
|
||||||
|
if ($usia < 17 || $usia > 65) {
|
||||||
|
return redirect()->back()
|
||||||
|
->with('error', 'Usia harus antara 17-65 tahun')
|
||||||
|
->withInput();
|
||||||
|
}
|
||||||
|
|
||||||
// Bersihkan format angka dari gaji
|
// Bersihkan format angka dari gaji
|
||||||
$gaji = str_replace('.', '', $request->gaji);
|
$gaji = str_replace('.', '', $request->gaji);
|
||||||
|
|
||||||
// Simpan data
|
// Simpan data
|
||||||
DataKaryawanModel::create([
|
DataKaryawanModel::create([
|
||||||
'nama' => $request->nama,
|
'nama' => $request->nama,
|
||||||
'usia' => $request->usia,
|
'tanggal_lahir' => $tanggalLahir->timestamp, // Simpan sebagai timestamp
|
||||||
'jabatan' => $request->jabatan,
|
'jabatan' => $request->jabatan,
|
||||||
'gaji' => $gaji
|
'gaji' => $gaji
|
||||||
]);
|
]);
|
||||||
|
@ -39,7 +51,8 @@ public function store(Request $request)
|
||||||
->with('success', 'Data karyawan berhasil ditambahkan!');
|
->with('success', 'Data karyawan berhasil ditambahkan!');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()->back()
|
return redirect()->back()
|
||||||
->with('error', 'Gagal menambahkan data karyawan: ' . $e->getMessage());
|
->with('error', 'Gagal menambahkan data karyawan: ' . $e->getMessage())
|
||||||
|
->withInput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,23 @@
|
||||||
|
|
||||||
use App\Models\GajiModel; // Import model
|
use App\Models\GajiModel; // Import model
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
class GajiController extends Controller
|
class GajiController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// Ambil data dari tabel karyawans termasuk usia dan jabatan
|
// Ambil data dari tabel karyawans
|
||||||
$gajiKaryawan = GajiModel::whereNotNull('gaji')
|
$gajiKaryawan = GajiModel::whereNotNull('gaji')
|
||||||
->where('gaji', '>', 0)
|
->where('gaji', '>', 0)
|
||||||
->select('id', 'nama', 'usia', 'jabatan', 'gaji', 'created_at')
|
->select('id', 'nama', 'tanggal_lahir', 'jabatan', 'gaji', 'created_at')
|
||||||
->get();
|
->get()
|
||||||
|
->map(function ($karyawan) {
|
||||||
|
// Hitung usia dari timestamp
|
||||||
|
$usia = Carbon::createFromTimestamp($karyawan->tanggal_lahir)->age;
|
||||||
|
$karyawan->usia = $usia;
|
||||||
|
return $karyawan;
|
||||||
|
});
|
||||||
|
|
||||||
return view('Gaji', compact('gajiKaryawan'));
|
return view('Gaji', compact('gajiKaryawan'));
|
||||||
}
|
}
|
||||||
|
@ -22,12 +29,16 @@ public function index()
|
||||||
public function show($id)
|
public function show($id)
|
||||||
{
|
{
|
||||||
$karyawan = GajiModel::findOrFail($id);
|
$karyawan = GajiModel::findOrFail($id);
|
||||||
|
// Hitung usia untuk response
|
||||||
|
$karyawan->usia = Carbon::createFromTimestamp($karyawan->tanggal_lahir)->age;
|
||||||
return response()->json($karyawan);
|
return response()->json($karyawan);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit($id)
|
public function edit($id)
|
||||||
{
|
{
|
||||||
$karyawan = GajiModel::findOrFail($id);
|
$karyawan = GajiModel::findOrFail($id);
|
||||||
|
// Konversi timestamp ke format date untuk form
|
||||||
|
$karyawan->tanggal_lahir = Carbon::createFromTimestamp($karyawan->tanggal_lahir)->format('Y-m-d');
|
||||||
return view('GajiEdit', compact('karyawan'));
|
return view('GajiEdit', compact('karyawan'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +47,13 @@ public function update(Request $request, $id)
|
||||||
try {
|
try {
|
||||||
$karyawan = GajiModel::findOrFail($id);
|
$karyawan = GajiModel::findOrFail($id);
|
||||||
|
|
||||||
|
// Konversi tanggal lahir ke timestamp
|
||||||
|
$tanggalLahir = Carbon::parse($request->tanggal_lahir)->timestamp;
|
||||||
|
|
||||||
// Bersihkan format angka dari gaji
|
// Bersihkan format angka dari gaji
|
||||||
$request->merge([
|
$request->merge([
|
||||||
'gaji' => str_replace('.', '', $request->gaji)
|
'gaji' => str_replace('.', '', $request->gaji),
|
||||||
|
'tanggal_lahir' => $tanggalLahir
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$karyawan->update($request->all());
|
$karyawan->update($request->all());
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use App\Http\Controllers\RiwayatController;
|
||||||
|
|
||||||
class LaporanController extends Controller
|
class LaporanController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -317,10 +318,34 @@ public function destroy($id)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$laporan = LaporanModel::findOrFail($id);
|
$laporan = LaporanModel::findOrFail($id);
|
||||||
|
|
||||||
|
// Catat riwayat sebelum menghapus
|
||||||
|
$riwayatController = new RiwayatController();
|
||||||
|
$keteranganRiwayat = "Menghapus laporan - Tanggal: " . date('d/m/Y', strtotime($laporan->Tanggal)) .
|
||||||
|
", Keterangan: " . $laporan->keterangan;
|
||||||
|
|
||||||
|
if (!empty($laporan->nama_karyawan)) {
|
||||||
|
$keteranganRiwayat .= ", Nama Karyawan: " . $laporan->nama_karyawan;
|
||||||
|
}
|
||||||
|
|
||||||
|
$riwayatController->store(
|
||||||
|
auth()->id(),
|
||||||
|
auth()->user()->nama,
|
||||||
|
'Hapus Laporan',
|
||||||
|
$keteranganRiwayat
|
||||||
|
);
|
||||||
|
|
||||||
$laporan->delete();
|
$laporan->delete();
|
||||||
return response()->json(['success' => true, 'message' => 'Data berhasil dihapus']);
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Data berhasil dihapus'
|
||||||
|
]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus data: ' . $e->getMessage()], 500);
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Gagal menghapus data: ' . $e->getMessage()
|
||||||
|
], 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Login;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class RegisterController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
if (Auth::check()) {
|
||||||
|
return redirect()->route('home');
|
||||||
|
}
|
||||||
|
return view('register');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'nama' => 'required|string|max:255',
|
||||||
|
'email' => 'required|string|email|max:255|unique:penggunas',
|
||||||
|
'password' => 'required|string|min:8|confirmed',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user = Login::create([
|
||||||
|
'nama' => $request->nama,
|
||||||
|
'email' => $request->email,
|
||||||
|
'password' => Hash::make($request->password),
|
||||||
|
'tipe_pengguna' => 'karyawan'
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->route('login')->with('success', 'Registrasi berhasil! Silakan login dengan akun Anda.');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\RiwayatModel;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
class RiwayatController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$riwayat = RiwayatModel::orderBy('tanggal', 'desc')
|
||||||
|
->orderBy('waktu', 'desc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return view('Riwayat', compact('riwayat'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store($userId, $namaUser, $aksi, $keterangan = '')
|
||||||
|
{
|
||||||
|
$now = Carbon::now();
|
||||||
|
|
||||||
|
RiwayatModel::create([
|
||||||
|
'user_id' => $userId,
|
||||||
|
'nama_user' => $namaUser,
|
||||||
|
'tanggal' => $now->format('Y-m-d'),
|
||||||
|
'waktu' => $now->format('H:i:s'),
|
||||||
|
'aksi' => $aksi,
|
||||||
|
'keterangan' => $keterangan
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use App\Models\UangMasukModel; // Import model
|
use App\Models\UangMasukModel; // Import model
|
||||||
use App\Models\GajiModel; // Import model gaji
|
use App\Models\GajiModel; // Import model gaji
|
||||||
|
use App\Models\LaporanModel; // Import model laporan
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class UangMasukController extends Controller
|
class UangMasukController extends Controller
|
||||||
|
@ -28,12 +29,13 @@ public function store(Request $request)
|
||||||
// Debug untuk melihat data yang diterima
|
// Debug untuk melihat data yang diterima
|
||||||
\Log::info('Request Data:', $request->all());
|
\Log::info('Request Data:', $request->all());
|
||||||
|
|
||||||
|
// Validasi input
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'Tanggal' => 'required|date',
|
'Tanggal' => 'required|date',
|
||||||
'keterangan_type' => 'required|in:karyawan,manual',
|
'keterangan_type' => 'required|in:karyawan,manual',
|
||||||
'kategori' => 'required|array',
|
'kategori' => 'required|array',
|
||||||
'posisi' => 'required|array',
|
'posisi' => 'required|array',
|
||||||
'nominal' => 'required|array',
|
'nominal' => 'required|array'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Gabungkan keterangan berdasarkan tipe input
|
// Gabungkan keterangan berdasarkan tipe input
|
||||||
|
@ -47,12 +49,6 @@ public function store(Request $request)
|
||||||
if ($request->filled('keterangan_tambahan')) {
|
if ($request->filled('keterangan_tambahan')) {
|
||||||
$keterangan .= ' - ' . $request->keterangan_tambahan;
|
$keterangan .= ' - ' . $request->keterangan_tambahan;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ambil gaji dari model GajiModel berdasarkan nama karyawan
|
|
||||||
$karyawan = GajiModel::where('nama', $request->keterangan)->first();
|
|
||||||
if (!$karyawan) {
|
|
||||||
throw new \Exception('Data karyawan tidak ditemukan');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (empty($request->keterangan_manual)) {
|
if (empty($request->keterangan_manual)) {
|
||||||
throw new \Exception('Keterangan manual harus diisi');
|
throw new \Exception('Keterangan manual harus diisi');
|
||||||
|
@ -60,42 +56,52 @@ public function store(Request $request)
|
||||||
$keterangan = $request->keterangan_manual;
|
$keterangan = $request->keterangan_manual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Proses data
|
||||||
$data = [
|
$data = [
|
||||||
'Tanggal' => $request->Tanggal,
|
'Tanggal' => $request->Tanggal,
|
||||||
'keterangan' => $keterangan,
|
'keterangan' => $keterangan,
|
||||||
|
'nama_karyawan' => $request->keterangan_type === 'karyawan' ? $request->keterangan : null,
|
||||||
|
'kode' => $this->generateKode($request->kategori[0]),
|
||||||
|
'kategori' => $request->kategori[0],
|
||||||
|
'uang_masuk' => str_replace(['.', ','], '', $request->nominal[0]) ?? 0,
|
||||||
|
'uang_keluar' => 0
|
||||||
];
|
];
|
||||||
|
|
||||||
// Proses setiap rekening
|
// Tambahkan data untuk rekening tambahan jika ada
|
||||||
foreach ($request->kategori as $index => $kategori) {
|
for ($i = 1; $i < count($request->kategori); $i++) {
|
||||||
$kode = $this->generateKode($kategori);
|
if ($request->posisi[$i] === 'debit') {
|
||||||
$nominal = str_replace(['.', ','], '', $request->nominal[$index]);
|
$data["uang_masuk" . ($i + 1)] = str_replace(['.', ','], '', $request->nominal[$i]);
|
||||||
|
$data["kode" . ($i + 1)] = $this->generateKode($request->kategori[$i]);
|
||||||
// Set kode dan kategori sesuai urutan
|
$data["kategori" . ($i + 1)] = $request->kategori[$i];
|
||||||
$positionIndex = $index === 0 ? '' : ($index + 1);
|
|
||||||
$data["kode" . $positionIndex] = $kode;
|
|
||||||
$data["kategori" . $positionIndex] = $kategori;
|
|
||||||
|
|
||||||
// Set uang_masuk atau uang_keluar berdasarkan posisi
|
|
||||||
if ($request->posisi[$index] === 'debit') {
|
|
||||||
$data["uang_masuk" . $positionIndex] = $nominal;
|
|
||||||
$data["uang_keluar" . $positionIndex] = null;
|
|
||||||
} else {
|
} else {
|
||||||
$data["uang_masuk" . $positionIndex] = null;
|
$data["uang_keluar" . ($i + 1)] = str_replace(['.', ','], '', $request->nominal[$i]);
|
||||||
$data["uang_keluar" . $positionIndex] = $nominal;
|
$data["kode" . ($i + 1)] = $this->generateKode($request->kategori[$i]);
|
||||||
|
$data["kategori" . ($i + 1)] = $request->kategori[$i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug untuk melihat data yang akan disimpan
|
|
||||||
\Log::info('Data to be saved:', $data);
|
|
||||||
|
|
||||||
// Simpan data
|
// Simpan data
|
||||||
$result = UangMasukModel::create($data);
|
$laporan = LaporanModel::create($data);
|
||||||
|
|
||||||
if (!$result) {
|
// Catat riwayat
|
||||||
throw new \Exception('Gagal menyimpan data');
|
$riwayatController = new RiwayatController();
|
||||||
|
$keteranganRiwayat = "Input transaksi baru - Tanggal: " . date('d/m/Y', strtotime($request->Tanggal)) .
|
||||||
|
", Keterangan: " . $keterangan;
|
||||||
|
|
||||||
|
if ($request->keterangan_type === 'karyawan') {
|
||||||
|
$keteranganRiwayat .= ", Nama Karyawan: " . $request->keterangan;
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back()->with('success', 'Data berhasil disimpan!');
|
$keteranganRiwayat .= ", Kategori: " . implode(", ", array_filter($request->kategori));
|
||||||
|
|
||||||
|
$riwayatController->store(
|
||||||
|
auth()->id(),
|
||||||
|
auth()->user()->nama,
|
||||||
|
'Input Transaksi',
|
||||||
|
$keteranganRiwayat
|
||||||
|
);
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', 'Data berhasil disimpan');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Log::error('Error in UangMasukController@store: ' . $e->getMessage());
|
\Log::error('Error in UangMasukController@store: ' . $e->getMessage());
|
||||||
return redirect()->back()->with('error', 'Gagal menyimpan data: ' . $e->getMessage());
|
return redirect()->back()->with('error', 'Gagal menyimpan data: ' . $e->getMessage());
|
||||||
|
|
|
@ -10,7 +10,7 @@ class DataKaryawanModel extends Model
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'nama',
|
'nama',
|
||||||
'usia',
|
'tanggal_lahir',
|
||||||
'jabatan',
|
'jabatan',
|
||||||
'gaji'
|
'gaji'
|
||||||
];
|
];
|
||||||
|
|
|
@ -24,7 +24,7 @@ class GajiModel extends Model
|
||||||
// Kolom yang dapat diisi
|
// Kolom yang dapat diisi
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'nama',
|
'nama',
|
||||||
'usia',
|
'tanggal_lahir',
|
||||||
'jabatan',
|
'jabatan',
|
||||||
'gaji'
|
'gaji'
|
||||||
];
|
];
|
||||||
|
@ -38,5 +38,6 @@ class GajiModel extends Model
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'gaji' => 'decimal:2',
|
'gaji' => 'decimal:2',
|
||||||
|
'tanggal_lahir' => 'integer'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
|
|
||||||
class Login extends Model
|
class Login extends Authenticatable
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasApiTokens, HasFactory, Notifiable;
|
||||||
|
|
||||||
protected $table = 'penggunas';
|
protected $table = 'penggunas';
|
||||||
|
|
||||||
|
@ -17,4 +19,14 @@ class Login extends Model
|
||||||
'password',
|
'password',
|
||||||
'tipe_pengguna'
|
'tipe_pengguna'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $hidden = [
|
||||||
|
'password',
|
||||||
|
'remember_token',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'email_verified_at' => 'datetime',
|
||||||
|
'password' => 'hashed',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class RiwayatModel extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'riwayat';
|
||||||
|
protected $primaryKey = 'id';
|
||||||
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
|
'nama_user',
|
||||||
|
'tanggal',
|
||||||
|
'waktu',
|
||||||
|
'aksi',
|
||||||
|
'keterangan'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Relasi dengan model User
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Login::class, 'user_id');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('riwayat', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('user_id')->constrained('penggunas')->onDelete('cascade');
|
||||||
|
$table->string('nama_user');
|
||||||
|
$table->date('tanggal');
|
||||||
|
$table->time('waktu');
|
||||||
|
$table->string('aksi');
|
||||||
|
$table->text('keterangan')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('riwayat');
|
||||||
|
}
|
||||||
|
};
|
|
@ -230,7 +230,12 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
|
<li class="mb-4">
|
||||||
|
<a href="{{ route('riwayat.index') }}" class="nav-link flex items-center p-2 rounded-lg hover:bg-blue-700 transition-colors">
|
||||||
|
<i class="fas fa-history mr-3"></i>
|
||||||
|
<span>Riwayat</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="mt-8">
|
<li class="mt-8">
|
||||||
<form action="{{ route('logout') }}" method="POST" id="logout-form">
|
<form action="{{ route('logout') }}" method="POST" id="logout-form">
|
||||||
@csrf
|
@csrf
|
||||||
|
|
|
@ -26,20 +26,25 @@ class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Usia -->
|
<!-- Tanggal Lahir -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Usia <span class="text-red-600">*</span>
|
Tanggal Lahir <span class="text-red-600">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="date"
|
||||||
name="usia"
|
name="tanggal_lahir"
|
||||||
|
id="tanggal_lahir"
|
||||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
placeholder="Masukkan usia"
|
|
||||||
min="17"
|
|
||||||
max="65"
|
|
||||||
required
|
required
|
||||||
|
max="{{ date('Y-m-d') }}"
|
||||||
|
onchange="hitungUsia(this.value)"
|
||||||
>
|
>
|
||||||
|
<div class="mt-2">
|
||||||
|
<span class="text-sm font-medium text-gray-700">Usia: </span>
|
||||||
|
<span id="usia" class="text-sm text-gray-600">-</span>
|
||||||
|
<span class="text-sm text-gray-600">tahun</span>
|
||||||
|
</div>
|
||||||
<p class="text-xs text-gray-500 mt-1">Usia minimal 17 tahun dan maksimal 65 tahun</p>
|
<p class="text-xs text-gray-500 mt-1">Usia minimal 17 tahun dan maksimal 65 tahun</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -113,6 +118,72 @@ function formatNumber(input) {
|
||||||
input.value = value;
|
input.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hitungUsia(tanggalLahir) {
|
||||||
|
const today = new Date();
|
||||||
|
const birthDate = new Date(tanggalLahir);
|
||||||
|
|
||||||
|
let usia = today.getFullYear() - birthDate.getFullYear();
|
||||||
|
const monthDiff = today.getMonth() - birthDate.getMonth();
|
||||||
|
|
||||||
|
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
||||||
|
usia--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi usia
|
||||||
|
if (usia < 17) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Usia Tidak Memenuhi Syarat',
|
||||||
|
text: 'Usia minimal harus 17 tahun',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
document.getElementById('tanggal_lahir').value = '';
|
||||||
|
document.getElementById('usia').textContent = '-';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usia > 65) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Usia Tidak Memenuhi Syarat',
|
||||||
|
text: 'Usia maksimal harus 65 tahun',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
document.getElementById('tanggal_lahir').value = '';
|
||||||
|
document.getElementById('usia').textContent = '-';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('usia').textContent = usia;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambahkan validasi form sebelum submit
|
||||||
|
document.getElementById('karyawanForm').addEventListener('submit', function(e) {
|
||||||
|
const tanggalLahir = document.getElementById('tanggal_lahir').value;
|
||||||
|
if (!tanggalLahir) {
|
||||||
|
e.preventDefault();
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Error!',
|
||||||
|
text: 'Silakan isi tanggal lahir',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const usia = parseInt(document.getElementById('usia').textContent);
|
||||||
|
if (isNaN(usia) || usia < 17 || usia > 65) {
|
||||||
|
e.preventDefault();
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Error!',
|
||||||
|
text: 'Usia harus antara 17-65 tahun',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Menampilkan notifikasi jika ada pesan sukses atau error
|
// Menampilkan notifikasi jika ada pesan sukses atau error
|
||||||
@if(session('success'))
|
@if(session('success'))
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
|
|
|
@ -23,9 +23,19 @@ class="border rounded w-full py-2 px-3" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-gray-700 text-sm font-bold mb-2">Usia</label>
|
<label class="block text-gray-700 text-sm font-bold mb-2">Tanggal Lahir</label>
|
||||||
<input type="number" name="usia" value="{{ $karyawan->usia }}"
|
<input type="date" name="tanggal_lahir" id="tanggal_lahir"
|
||||||
class="border rounded w-full py-2 px-3" required>
|
value="{{ $karyawan->tanggal_lahir }}"
|
||||||
|
class="border rounded w-full py-2 px-3"
|
||||||
|
required
|
||||||
|
max="{{ date('Y-m-d') }}"
|
||||||
|
onchange="hitungUsia(this.value)">
|
||||||
|
<div class="mt-2">
|
||||||
|
<span class="text-sm font-medium text-gray-700">Usia: </span>
|
||||||
|
<span id="usia" class="text-sm text-gray-600">{{ Carbon\Carbon::createFromTimestamp($karyawan->tanggal_lahir)->age }}</span>
|
||||||
|
<span class="text-sm text-gray-600">tahun</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-gray-500 mt-1">Usia minimal 17 tahun dan maksimal 65 tahun</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
@ -89,17 +99,56 @@ function formatNumber(input) {
|
||||||
input.value = value;
|
input.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hitungUsia(tanggalLahir) {
|
||||||
|
const today = new Date();
|
||||||
|
const birthDate = new Date(tanggalLahir);
|
||||||
|
|
||||||
|
let usia = today.getFullYear() - birthDate.getFullYear();
|
||||||
|
const monthDiff = today.getMonth() - birthDate.getMonth();
|
||||||
|
|
||||||
|
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
||||||
|
usia--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi usia
|
||||||
|
if (usia < 17) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Usia Tidak Memenuhi Syarat',
|
||||||
|
text: 'Usia minimal harus 17 tahun',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
document.getElementById('tanggal_lahir').value = '';
|
||||||
|
document.getElementById('usia').textContent = '-';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usia > 65) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Usia Tidak Memenuhi Syarat',
|
||||||
|
text: 'Usia maksimal harus 65 tahun',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
document.getElementById('tanggal_lahir').value = '';
|
||||||
|
document.getElementById('usia').textContent = '-';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('usia').textContent = usia;
|
||||||
|
}
|
||||||
|
|
||||||
// Form submission handling
|
// Form submission handling
|
||||||
document.getElementById('editGajiForm').addEventListener('submit', function(e) {
|
document.getElementById('editGajiForm').addEventListener('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// Validasi form di sini jika diperlukan
|
// Validasi form
|
||||||
const nama = document.querySelector('input[name="nama"]').value;
|
const nama = document.querySelector('input[name="nama"]').value;
|
||||||
const usia = document.querySelector('input[name="usia"]').value;
|
const tanggalLahir = document.querySelector('input[name="tanggal_lahir"]').value;
|
||||||
const jabatan = document.querySelector('input[name="jabatan"]').value;
|
const jabatan = document.querySelector('input[name="jabatan"]').value;
|
||||||
const gaji = document.querySelector('input[name="gaji"]').value;
|
const gaji = document.querySelector('input[name="gaji"]').value;
|
||||||
|
|
||||||
if (!nama || !usia || !jabatan || !gaji) {
|
if (!nama || !tanggalLahir || !jabatan || !gaji) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
title: 'Error!',
|
title: 'Error!',
|
||||||
|
@ -109,6 +158,18 @@ function formatNumber(input) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validasi usia
|
||||||
|
const usia = parseInt(document.getElementById('usia').textContent);
|
||||||
|
if (isNaN(usia) || usia < 17 || usia > 65) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Error!',
|
||||||
|
text: 'Usia harus antara 17-65 tahun',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Submit form jika validasi berhasil
|
// Submit form jika validasi berhasil
|
||||||
this.submit();
|
this.submit();
|
||||||
});
|
});
|
||||||
|
|
|
@ -48,6 +48,10 @@
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="w-full py-2 mb-4 text-white bg-gradient-to-r from-teal-400 to-pink-500 rounded-lg hover:from-teal-500 hover:to-pink-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500">LOGIN</button>
|
<button type="submit" class="w-full py-2 mb-4 text-white bg-gradient-to-r from-teal-400 to-pink-500 rounded-lg hover:from-teal-500 hover:to-pink-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500">LOGIN</button>
|
||||||
</form>
|
</form>
|
||||||
|
<div class="text-center">
|
||||||
|
<p class="text-sm text-gray-600 mb-2">Belum punya akun?</p>
|
||||||
|
<a href="{{ route('register') }}" class="inline-block w-full py-2 text-white bg-gradient-to-r from-blue-400 to-purple-500 rounded-lg hover:from-blue-500 hover:to-purple-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">REGISTER</a>
|
||||||
|
</div>
|
||||||
<!-- <div class="text-center text-sm text-gray-600 mb-4">Or Sign Up Using</div>
|
<!-- <div class="text-center text-sm text-gray-600 mb-4">Or Sign Up Using</div>
|
||||||
<div class="flex justify-center space-x-4">
|
<div class="flex justify-center space-x-4">
|
||||||
<a href="#" class="w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center text-white">
|
<a href="#" class="w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center text-white">
|
||||||
|
@ -92,5 +96,19 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if(session('success'))
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'success',
|
||||||
|
title: 'Berhasil!',
|
||||||
|
text: '{{ session("success") }}',
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endif
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,381 @@
|
||||||
|
@extends('Core.Sidebar')
|
||||||
|
@section('content')
|
||||||
|
<title>Riwayat Aktivitas</title>
|
||||||
|
<!-- Font Awesome -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Gradient Background */
|
||||||
|
body {
|
||||||
|
background: #f3f4f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card Styling */
|
||||||
|
.box {
|
||||||
|
background: white;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table Styling */
|
||||||
|
.print-table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-table th {
|
||||||
|
background-color: #f9fafb;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
border-bottom: 2px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-table td {
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-table tbody tr:hover {
|
||||||
|
background-color: #f9fafb;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filter Controls */
|
||||||
|
.filter-controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-input {
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #3b82f6;
|
||||||
|
ring: 2px;
|
||||||
|
ring-color: #93c5fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Action Badge */
|
||||||
|
.action-badge {
|
||||||
|
padding: 0.25rem 0.75rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-delete {
|
||||||
|
background-color: #fee2e2;
|
||||||
|
color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-edit {
|
||||||
|
background-color: #dbeafe;
|
||||||
|
color: #2563eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-create {
|
||||||
|
background-color: #dcfce7;
|
||||||
|
color: #16a34a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Design */
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.filter-controls {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-group {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keterangan Styling */
|
||||||
|
.keterangan {
|
||||||
|
max-width: 300px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.keterangan:hover {
|
||||||
|
white-space: normal;
|
||||||
|
overflow: visible;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pagination Controls */
|
||||||
|
.pagination-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-controls button:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-controls button:hover:not(:disabled) {
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows-per-page {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows-per-page select {
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows-per-page select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #3b82f6;
|
||||||
|
ring: 2px;
|
||||||
|
ring-color: #93c5fd;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="box p-4 intro-y mt-5">
|
||||||
|
<div class="intro-y">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="mb-4 bg-blue-600 text-white p-4 rounded-lg shadow-md">
|
||||||
|
<h1 class="text-2xl font-bold">Riwayat Aktivitas</h1>
|
||||||
|
<p class="text-sm mt-1">Halaman ini menampilkan riwayat aktivitas pengguna dalam sistem.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Filter -->
|
||||||
|
<div class="filter-controls">
|
||||||
|
<div class="filter-group">
|
||||||
|
<label for="searchRiwayat" class="font-medium">Cari:</label>
|
||||||
|
<input type="text" id="searchRiwayat" class="filter-input" placeholder="Cari nama/aksi...">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="filter-group">
|
||||||
|
<label for="dateFilter" class="font-medium">Tanggal:</label>
|
||||||
|
<input type="date" id="dateFilter" class="filter-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tabel Riwayat -->
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="print-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left">No</th>
|
||||||
|
<th class="text-left">Nama User</th>
|
||||||
|
<th class="text-left">Tanggal</th>
|
||||||
|
<th class="text-left">Waktu (WIB)</th>
|
||||||
|
<th class="text-left">Aksi</th>
|
||||||
|
<th class="text-left">Keterangan</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($riwayat as $index => $item)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $index + 1 }}</td>
|
||||||
|
<td>{{ $item->nama_user }}</td>
|
||||||
|
<td>{{ date('d/m/Y', strtotime($item->tanggal)) }}</td>
|
||||||
|
<td>{{ \Carbon\Carbon::parse($item->waktu)->setTimezone('Asia/Jakarta')->format('H:i:s') }} WIB</td>
|
||||||
|
<td>
|
||||||
|
<span class="action-badge
|
||||||
|
@if(str_contains(strtolower($item->aksi), 'hapus')) action-delete
|
||||||
|
@elseif(str_contains(strtolower($item->aksi), 'edit')) action-edit
|
||||||
|
@else action-create
|
||||||
|
@endif">
|
||||||
|
{{ $item->aksi }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="keterangan" title="{{ $item->keterangan }}">{{ $item->keterangan }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Pagination Controls -->
|
||||||
|
<div class="intro-y col-span-12 flex flex-wrap sm:flex-row sm:flex-nowrap items-center py-5 px-4 bg-white rounded-md shadow-md mt-4">
|
||||||
|
<!-- Filter Rows per Page -->
|
||||||
|
<div class="flex items-center space-x-2 flex-grow">
|
||||||
|
<label for="rowsPerPage" class="text-sm font-medium">Rows per page:</label>
|
||||||
|
<select id="rowsPerPage" class="border rounded-md py-3 px-6 ml-1 text-sm focus:outline-none focus:ring focus:border-blue-300">
|
||||||
|
<option value="5" selected>5</option>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="15">15</option>
|
||||||
|
<option value="all">All</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Pagination Controls -->
|
||||||
|
<div class="flex items-center space-x-4 ml-2">
|
||||||
|
<button id="prevPage" class="text-sm px-3 py-2 border rounded-md bg-gray-100 hover:bg-gray-200 focus:outline-none">Previous</button>
|
||||||
|
<span id="pageIndicator" class="text-sm font-medium">Page 1</span>
|
||||||
|
<button id="nextPage" class="text-sm px-3 py-2 border rounded-md bg-gray-100 hover:bg-gray-200 focus:outline-none">Next</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const searchInput = document.getElementById('searchRiwayat');
|
||||||
|
const dateFilter = document.getElementById('dateFilter');
|
||||||
|
const tableRows = document.querySelectorAll('tbody tr');
|
||||||
|
const rowsPerPageSelect = document.getElementById('rowsPerPage');
|
||||||
|
const prevButton = document.getElementById('prevPage');
|
||||||
|
const nextButton = document.getElementById('nextPage');
|
||||||
|
const pageIndicator = document.getElementById('pageIndicator');
|
||||||
|
|
||||||
|
let currentPage = 1;
|
||||||
|
let rowsPerPage = parseInt(rowsPerPageSelect.value);
|
||||||
|
|
||||||
|
function displayTableRows() {
|
||||||
|
const start = (currentPage - 1) * rowsPerPage;
|
||||||
|
const end = start + rowsPerPage;
|
||||||
|
let visibleRows = 0;
|
||||||
|
|
||||||
|
// Sembunyikan semua baris terlebih dahulu
|
||||||
|
Array.from(tableRows).forEach((row, index) => {
|
||||||
|
if (index >= start && index < end) {
|
||||||
|
row.style.display = '';
|
||||||
|
visibleRows++;
|
||||||
|
} else {
|
||||||
|
row.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update page indicator
|
||||||
|
const totalPages = Math.ceil(tableRows.length / rowsPerPage);
|
||||||
|
pageIndicator.textContent = `Page ${currentPage} of ${totalPages}`;
|
||||||
|
|
||||||
|
// Update button states
|
||||||
|
prevButton.disabled = currentPage === 1;
|
||||||
|
nextButton.disabled = currentPage >= totalPages;
|
||||||
|
|
||||||
|
// Tambahkan class untuk styling button disabled
|
||||||
|
if (prevButton.disabled) {
|
||||||
|
prevButton.classList.add('opacity-50', 'cursor-not-allowed');
|
||||||
|
} else {
|
||||||
|
prevButton.classList.remove('opacity-50', 'cursor-not-allowed');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextButton.disabled) {
|
||||||
|
nextButton.classList.add('opacity-50', 'cursor-not-allowed');
|
||||||
|
} else {
|
||||||
|
nextButton.classList.remove('opacity-50', 'cursor-not-allowed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterTable() {
|
||||||
|
const searchTerm = searchInput.value.toLowerCase();
|
||||||
|
const selectedDate = dateFilter.value;
|
||||||
|
|
||||||
|
tableRows.forEach(row => {
|
||||||
|
const namaUser = row.cells[1].textContent.toLowerCase();
|
||||||
|
const aksi = row.cells[4].textContent.toLowerCase();
|
||||||
|
const tanggal = row.cells[2].textContent;
|
||||||
|
const rowDate = tanggal.split('/').reverse().join('-');
|
||||||
|
|
||||||
|
const matchesSearch = namaUser.includes(searchTerm) || aksi.includes(searchTerm);
|
||||||
|
const matchesDate = !selectedDate || rowDate === selectedDate;
|
||||||
|
|
||||||
|
row.style.display = matchesSearch && matchesDate ? '' : 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset ke halaman pertama setelah filter
|
||||||
|
currentPage = 1;
|
||||||
|
displayTableRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listener untuk rows per page
|
||||||
|
rowsPerPageSelect.addEventListener('change', function() {
|
||||||
|
if (this.value === 'all') {
|
||||||
|
rowsPerPage = tableRows.length;
|
||||||
|
} else {
|
||||||
|
rowsPerPage = parseInt(this.value);
|
||||||
|
}
|
||||||
|
currentPage = 1;
|
||||||
|
displayTableRows();
|
||||||
|
|
||||||
|
// Simpan preferensi di localStorage
|
||||||
|
localStorage.setItem('preferredRowsPerPage', this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event listener untuk previous button
|
||||||
|
prevButton.addEventListener('click', function() {
|
||||||
|
if (currentPage > 1) {
|
||||||
|
currentPage--;
|
||||||
|
displayTableRows();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event listener untuk next button
|
||||||
|
nextButton.addEventListener('click', function() {
|
||||||
|
if (currentPage < Math.ceil(tableRows.length / rowsPerPage)) {
|
||||||
|
currentPage++;
|
||||||
|
displayTableRows();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event listener untuk pencarian dan filter tanggal
|
||||||
|
searchInput.addEventListener('input', filterTable);
|
||||||
|
dateFilter.addEventListener('change', filterTable);
|
||||||
|
|
||||||
|
// Load saved preference dari localStorage
|
||||||
|
const savedRowsPerPage = localStorage.getItem('preferredRowsPerPage');
|
||||||
|
if (savedRowsPerPage) {
|
||||||
|
rowsPerPageSelect.value = savedRowsPerPage;
|
||||||
|
if (savedRowsPerPage === 'all') {
|
||||||
|
rowsPerPage = tableRows.length;
|
||||||
|
} else {
|
||||||
|
rowsPerPage = parseInt(savedRowsPerPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard navigation
|
||||||
|
document.addEventListener('keydown', function(e) {
|
||||||
|
if (e.key === 'ArrowLeft' && !prevButton.disabled) {
|
||||||
|
prevButton.click();
|
||||||
|
} else if (e.key === 'ArrowRight' && !nextButton.disabled) {
|
||||||
|
nextButton.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial display
|
||||||
|
displayTableRows();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endsection
|
|
@ -25,6 +25,8 @@
|
||||||
name="Tanggal"
|
name="Tanggal"
|
||||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
required
|
required
|
||||||
|
min="{{ date('Y-m-d') }}"
|
||||||
|
value="{{ date('Y-m-d') }}"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
<!-- Font Awesome -->
|
<!-- Font Awesome -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
||||||
|
|
||||||
|
<!-- Tambahkan variabel PHP untuk tipe pengguna -->
|
||||||
|
@php
|
||||||
|
$isOwner = auth()->user()->tipe_pengguna === 'owner';
|
||||||
|
@endphp
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Gradient Background */
|
/* Gradient Background */
|
||||||
body {
|
body {
|
||||||
|
@ -136,10 +141,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="filter-group ml-auto">
|
<div class="filter-group ml-auto">
|
||||||
|
@if($isOwner)
|
||||||
<a href="{{ route('User.create') }}" id="createUser" class="btn btn-primary">
|
<a href="{{ route('User.create') }}" id="createUser" class="btn btn-primary">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
<span>Tambah User</span>
|
<span>Tambah User</span>
|
||||||
</a>
|
</a>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -164,6 +171,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// Tambahkan variabel JavaScript untuk tipe pengguna
|
||||||
|
const isOwner = @json($isOwner);
|
||||||
|
|
||||||
// Notifikasi SweetAlert2
|
// Notifikasi SweetAlert2
|
||||||
@if(session('success'))
|
@if(session('success'))
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
|
@ -215,12 +225,14 @@ function loadUsers(typeFilter = '', searchFilter = '') {
|
||||||
<td>${user.email}</td>
|
<td>${user.email}</td>
|
||||||
<td>${user.tipe_pengguna}</td>
|
<td>${user.tipe_pengguna}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
|
${isOwner ? `
|
||||||
<a href="/User/${user.id}/edit" class="text-blue-600 hover:text-blue-800 mx-1">
|
<a href="/User/${user.id}/edit" class="text-blue-600 hover:text-blue-800 mx-1">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</a>
|
</a>
|
||||||
<button onclick="deleteUser(${user.id})" class="text-red-600 hover:text-red-800 mx-1">
|
<button onclick="deleteUser(${user.id})" class="text-red-600 hover:text-red-800 mx-1">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
|
` : ''}
|
||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
tbody.appendChild(row);
|
tbody.appendChild(row);
|
||||||
|
@ -238,6 +250,16 @@ function loadUsers(typeFilter = '', searchFilter = '') {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteUser(id) {
|
function deleteUser(id) {
|
||||||
|
if (!isOwner) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Akses Ditolak!',
|
||||||
|
text: 'Anda tidak memiliki akses untuk menghapus user',
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Apakah Anda yakin?',
|
title: 'Apakah Anda yakin?',
|
||||||
text: "Data yang dihapus tidak dapat dikembalikan!",
|
text: "Data yang dihapus tidak dapat dikembalikan!",
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Register</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-light">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center mt-5">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="text-center">Register</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@if ($errors->any())
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<ul>
|
||||||
|
@foreach ($errors->all() as $error)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<form action="{{ route('register.store') }}" method="POST">
|
||||||
|
@csrf
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="nama" class="form-label">Nama</label>
|
||||||
|
<input type="text" class="form-control" id="nama" name="nama" value="{{ old('nama') }}" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="email" class="form-label">Email</label>
|
||||||
|
<input type="email" class="form-control" id="email" name="email" value="{{ old('email') }}" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="form-label">Password</label>
|
||||||
|
<input type="password" class="form-control" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password_confirmation" class="form-label">Konfirmasi Password</label>
|
||||||
|
<input type="password" class="form-control" id="password_confirmation" name="password_confirmation" required>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid">
|
||||||
|
<button type="submit" class="btn btn-primary">Register</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<p>Sudah punya akun? <a href="{{ route('login') }}">Login di sini</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -17,6 +17,8 @@
|
||||||
use App\Http\Controllers\RekeningController;
|
use App\Http\Controllers\RekeningController;
|
||||||
use App\Http\Controllers\NeracasaldoController;
|
use App\Http\Controllers\NeracasaldoController;
|
||||||
use App\Http\Controllers\LabarugiController;
|
use App\Http\Controllers\LabarugiController;
|
||||||
|
use App\Http\Controllers\RegisterController;
|
||||||
|
use App\Http\Controllers\RiwayatController;
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Web Routes
|
| Web Routes
|
||||||
|
@ -87,4 +89,10 @@
|
||||||
Route::get('/labarugi/filter', [LabarugiController::class, 'filter'])->name('labarugi.filter');
|
Route::get('/labarugi/filter', [LabarugiController::class, 'filter'])->name('labarugi.filter');
|
||||||
Route::get('/labarugi/export-excel', [LabarugiController::class, 'exportExcel'])->name('labarugi.export-excel');
|
Route::get('/labarugi/export-excel', [LabarugiController::class, 'exportExcel'])->name('labarugi.export-excel');
|
||||||
Route::get('/labarugi/export-pdf', [LabarugiController::class, 'exportPDF'])->name('labarugi.export-pdf');
|
Route::get('/labarugi/export-pdf', [LabarugiController::class, 'exportPDF'])->name('labarugi.export-pdf');
|
||||||
|
|
||||||
|
// Route untuk Riwayat
|
||||||
|
Route::get('/riwayat', [RiwayatController::class, 'index'])->name('riwayat.index');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::get('/register', [RegisterController::class, 'index'])->name('register');
|
||||||
|
Route::post('/register', [RegisterController::class, 'store'])->name('register.store');
|
||||||
|
|
Loading…
Reference in New Issue