update tgl 22 maret
This commit is contained in:
parent
7785425676
commit
b9e522fdd2
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public function logout(Request $request)
|
||||
{
|
||||
Session::flush();
|
||||
Auth::logout();
|
||||
|
||||
return redirect()->route('login')
|
||||
->with('success', 'Anda berhasil logout.');
|
||||
}
|
||||
}
|
|
@ -3,11 +3,41 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Login;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('Login');
|
||||
if (Auth::check()) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
return view('login');
|
||||
}
|
||||
|
||||
public function authenticate(Request $request)
|
||||
{
|
||||
$credentials = $request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required'],
|
||||
]);
|
||||
|
||||
if (Auth::attempt($credentials)) {
|
||||
$request->session()->regenerate();
|
||||
return redirect()->intended(route('home'));
|
||||
}
|
||||
|
||||
return back()->withErrors([
|
||||
'email' => 'Email atau password salah.',
|
||||
])->withInput($request->only('email'));
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
Session::flush();
|
||||
return redirect()->route('login');
|
||||
}
|
||||
}
|
|
@ -3,11 +3,138 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('User');
|
||||
$users = User::all();
|
||||
return view('User', compact('users'));
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
$users = User::all();
|
||||
return response()->json($users);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('TambahAkun');
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:penggunas'],
|
||||
'password' => ['required', Password::min(8)->mixedCase()->numbers()],
|
||||
'tipe_pengguna' => ['required', 'in:owner,karyawan']
|
||||
], [
|
||||
'nama.required' => 'Nama harus diisi',
|
||||
'nama.max' => 'Nama maksimal 255 karakter',
|
||||
'email.required' => 'Email harus diisi',
|
||||
'email.email' => 'Format email tidak valid',
|
||||
'email.unique' => 'Email sudah terdaftar',
|
||||
'password.required' => 'Password harus diisi',
|
||||
'password.min' => 'Password minimal 8 karakter',
|
||||
'tipe_pengguna.required' => 'Tipe pengguna harus dipilih',
|
||||
'tipe_pengguna.in' => 'Tipe pengguna tidak valid'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
try {
|
||||
User::create([
|
||||
'nama' => $request->nama,
|
||||
'email' => $request->email,
|
||||
'password' => Hash::make($request->password),
|
||||
'tipe_pengguna' => $request->tipe_pengguna
|
||||
]);
|
||||
|
||||
return redirect()->route('User.index')
|
||||
->with('success', 'Akun berhasil ditambahkan!');
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()
|
||||
->with('error', 'Gagal menambahkan akun. ' . $e->getMessage())
|
||||
->withInput();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
return view('EditAkun', compact('user'));
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:penggunas,email,'.$id],
|
||||
'password' => ['nullable', Password::min(8)->mixedCase()->numbers()],
|
||||
'tipe_pengguna' => ['required', 'in:owner,karyawan']
|
||||
], [
|
||||
'nama.required' => 'Nama harus diisi',
|
||||
'nama.max' => 'Nama maksimal 255 karakter',
|
||||
'email.required' => 'Email harus diisi',
|
||||
'email.email' => 'Format email tidak valid',
|
||||
'email.unique' => 'Email sudah terdaftar',
|
||||
'password.min' => 'Password minimal 8 karakter',
|
||||
'tipe_pengguna.required' => 'Tipe pengguna harus dipilih',
|
||||
'tipe_pengguna.in' => 'Tipe pengguna tidak valid'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
try {
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
$data = [
|
||||
'nama' => $request->nama,
|
||||
'email' => $request->email,
|
||||
'tipe_pengguna' => $request->tipe_pengguna
|
||||
];
|
||||
|
||||
// Update password hanya jika diisi
|
||||
if ($request->filled('password')) {
|
||||
$data['password'] = Hash::make($request->password);
|
||||
}
|
||||
|
||||
$user->update($data);
|
||||
|
||||
return redirect()->route('User.index')
|
||||
->with('success', 'Akun berhasil diperbarui!');
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()
|
||||
->with('error', 'Gagal memperbarui akun. ' . $e->getMessage())
|
||||
->withInput();
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
try {
|
||||
$user = User::findOrFail($id);
|
||||
$user->delete();
|
||||
|
||||
return redirect()->route('User.index')
|
||||
->with('success', 'Akun berhasil dihapus!');
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()
|
||||
->with('error', 'Gagal menghapus akun. ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,4 +8,13 @@
|
|||
class Login extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'penggunas';
|
||||
|
||||
protected $fillable = [
|
||||
'nama',
|
||||
'email',
|
||||
'password',
|
||||
'tipe_pengguna'
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2,44 +2,29 @@
|
|||
|
||||
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;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
protected $table = 'penggunas';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'nama',
|
||||
'email',
|
||||
'password',
|
||||
'tipe_pengguna'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
|
|
|
@ -6,25 +6,20 @@
|
|||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
public function up()
|
||||
{
|
||||
Schema::create('logins', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nama');
|
||||
$table->string('email')->unique();
|
||||
$table->string('password');
|
||||
$table->string('role');
|
||||
$table->enum('role', ['admin', 'user'])->default('user');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('logins');
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('penggunas', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nama');
|
||||
$table->string('email')->unique();
|
||||
$table->string('password');
|
||||
$table->enum('tipe_pengguna', ['owner', 'karyawan'])->default('karyawan');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('penggunas');
|
||||
}
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('penggunas', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nama');
|
||||
$table->string('email')->unique();
|
||||
$table->string('password');
|
||||
$table->enum('tipe_pengguna', ['owner', 'karyawan'])->default('karyawan');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('penggunas');
|
||||
}
|
||||
};
|
|
@ -18,5 +18,9 @@ public function run(): void
|
|||
// 'name' => 'Test User',
|
||||
// 'email' => 'test@example.com',
|
||||
// ]);
|
||||
|
||||
$this->call([
|
||||
PenggunaSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class PenggunaSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
DB::table('penggunas')->insert([
|
||||
'nama' => 'Budi',
|
||||
'email' => 'budivespaendut@gmail.com',
|
||||
'password' => Hash::make('budi1234'),
|
||||
'tipe_pengguna' => 'owner',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -151,10 +151,13 @@
|
|||
</a>
|
||||
</li>
|
||||
<li class="mt-8">
|
||||
<a href="#" class="nav-link flex items-center p-2 rounded-lg hover:bg-red-600 transition-colors">
|
||||
<form action="{{ route('logout') }}" method="POST" id="logout-form">
|
||||
@csrf
|
||||
<button type="submit" class="nav-link w-full flex items-center p-2 rounded-lg hover:bg-red-600 transition-colors">
|
||||
<i class="fas fa-sign-out-alt mr-3"></i>
|
||||
<span>Logout</span>
|
||||
</a>
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
@extends('Core.Sidebar')
|
||||
|
||||
@section('content')
|
||||
<div class="p-6 animate-fade-in">
|
||||
<div class="mb-4 bg-blue-600 text-white p-4 rounded-lg shadow-md">
|
||||
<h1 class="text-2xl font-bold">Edit Akun</h1>
|
||||
<p class="text-sm mt-1">Form untuk mengubah data akun pengguna</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg shadow-lg p-6">
|
||||
@if ($errors->any())
|
||||
<div class="mb-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg">
|
||||
<strong>Oops! Ada beberapa masalah:</strong>
|
||||
<ul class="mt-2 list-disc list-inside">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('User.update', $user->id) }}" method="POST" class="space-y-4">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<!-- Nama -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Nama <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="nama"
|
||||
value="{{ old('nama', $user->nama) }}"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('nama') border-red-500 @enderror"
|
||||
required
|
||||
>
|
||||
@error('nama')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Email <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value="{{ old('email', $user->email) }}"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('email') border-red-500 @enderror"
|
||||
required
|
||||
>
|
||||
@error('email')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Password -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('password') border-red-500 @enderror"
|
||||
placeholder="Kosongkan jika tidak ingin mengubah password"
|
||||
>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Kosongkan jika tidak ingin mengubah password. Jika diisi, password harus minimal 8 karakter, mengandung huruf besar, huruf kecil, dan angka.
|
||||
</p>
|
||||
@error('password')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Tipe Pengguna -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Tipe Pengguna <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<select
|
||||
name="tipe_pengguna"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('tipe_pengguna') border-red-500 @enderror"
|
||||
required
|
||||
>
|
||||
<option value="">Pilih tipe pengguna</option>
|
||||
<option value="owner" {{ old('tipe_pengguna', $user->tipe_pengguna) == 'owner' ? 'selected' : '' }}>Owner</option>
|
||||
<option value="karyawan" {{ old('tipe_pengguna', $user->tipe_pengguna) == 'karyawan' ? 'selected' : '' }}>Karyawan</option>
|
||||
</select>
|
||||
@error('tipe_pengguna')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Tombol Submit -->
|
||||
<div class="flex justify-end space-x-3 pt-4">
|
||||
<button
|
||||
type="button"
|
||||
class="px-4 py-2 border rounded-lg hover:bg-gray-100 transition-colors"
|
||||
onclick="window.history.back()"
|
||||
>
|
||||
Kembali
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
Simpan Perubahan
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SweetAlert2 -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
<script>
|
||||
@if(session('success'))
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil!',
|
||||
text: '{{ session('success') }}',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal!',
|
||||
text: '{{ session('error') }}',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
@endif
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn 0.5s ease-out;
|
||||
}
|
||||
|
||||
.form-group input:hover,
|
||||
.form-group select:hover {
|
||||
border-color: #93C5FD;
|
||||
}
|
||||
|
||||
button {
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
</style>
|
||||
@endsection
|
|
@ -14,23 +14,39 @@
|
|||
<body class="flex items-center justify-center min-h-screen">
|
||||
<div class="bg-white p-8 rounded-lg shadow-lg w-80">
|
||||
<h2 class="text-2xl font-bold text-center mb-6">Login</h2>
|
||||
<form>
|
||||
@if(session('error'))
|
||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
<form method="POST" action="{{ route('login.authenticate') }}">
|
||||
@csrf
|
||||
<div class="mb-4">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-600" for="username">
|
||||
<i class="fas fa-user"></i> Type your username
|
||||
<label class="block mb-2 text-sm font-medium text-gray-600" for="email">
|
||||
<i class="fas fa-user"></i> Email
|
||||
</label>
|
||||
<input class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" type="text" id="username" placeholder="Type your username">
|
||||
<input class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="Type your email"
|
||||
required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-600" for="password">
|
||||
<i class="fas fa-lock"></i> Type your password
|
||||
<i class="fas fa-lock"></i> Password
|
||||
</label>
|
||||
<input class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" type="password" id="password" placeholder="Type your password">
|
||||
<input class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder="Type your password"
|
||||
required>
|
||||
</div>
|
||||
<div class="text-right mb-4">
|
||||
<a href="#" class="text-sm text-gray-600 hover:underline">Forgot password?</a>
|
||||
</div>
|
||||
<button type="submit" formaction="{{ route('home') }}" 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>
|
||||
<div class="text-center text-sm text-gray-600 mb-4">Or Sign Up Using</div>
|
||||
<div class="flex justify-center space-x-4">
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
@extends('Core.Sidebar')
|
||||
|
||||
@section('content')
|
||||
<div class="p-6 animate-fade-in">
|
||||
<!-- Header -->
|
||||
<div class="mb-4 bg-blue-600 text-white p-4 rounded-lg shadow-md">
|
||||
<h1 class="text-2xl font-bold">Tambah Akun</h1>
|
||||
<p class="text-sm mt-1">Formulir untuk menambahkan akun pengguna baru</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg shadow-lg p-6">
|
||||
@if ($errors->any())
|
||||
<div class="mb-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg">
|
||||
<strong>Oops! Ada beberapa masalah:</strong>
|
||||
<ul class="mt-2 list-disc list-inside">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form id="penggunaForm" action="{{ route('User.store') }}" method="POST" class="space-y-4">
|
||||
@csrf
|
||||
|
||||
<!-- Nama -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Nama <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="nama"
|
||||
value="{{ old('nama') }}"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('nama') border-red-500 @enderror"
|
||||
placeholder="Masukkan nama"
|
||||
required
|
||||
>
|
||||
@error('nama')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Email <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value="{{ old('email') }}"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('email') border-red-500 @enderror"
|
||||
placeholder="Masukkan email"
|
||||
required
|
||||
>
|
||||
@error('email')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Password -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Password <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('password') border-red-500 @enderror"
|
||||
placeholder="Masukkan password"
|
||||
required
|
||||
>
|
||||
<p class="mt-1 text-sm text-gray-500">Password harus minimal 8 karakter, mengandung huruf besar, huruf kecil, dan angka</p>
|
||||
@error('password')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Tipe Pengguna -->
|
||||
<div class="form-group">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Tipe Pengguna <span class="text-red-600">*</span>
|
||||
</label>
|
||||
<select
|
||||
name="tipe_pengguna"
|
||||
class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('tipe_pengguna') border-red-500 @enderror"
|
||||
required
|
||||
>
|
||||
<option value="">Pilih tipe pengguna</option>
|
||||
<option value="owner" {{ old('tipe_pengguna') == 'owner' ? 'selected' : '' }}>Owner</option>
|
||||
<option value="karyawan" {{ old('tipe_pengguna') == 'karyawan' ? 'selected' : '' }}>Karyawan</option>
|
||||
</select>
|
||||
@error('tipe_pengguna')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<!-- Tombol Submit -->
|
||||
<div class="flex justify-end space-x-3 pt-4">
|
||||
<button
|
||||
type="button"
|
||||
class="px-4 py-2 border rounded-lg hover:bg-gray-100 transition-colors"
|
||||
onclick="window.history.back()"
|
||||
>
|
||||
Kembali
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
Simpan
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SweetAlert2 -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
<script>
|
||||
// Menampilkan notifikasi jika ada pesan sukses atau error
|
||||
@if(session('success'))
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil!',
|
||||
text: '{{ session('success') }}',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal!',
|
||||
text: '{{ session('error') }}',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
@endif
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn 0.5s ease-out;
|
||||
}
|
||||
|
||||
.form-group input:hover,
|
||||
.form-group select:hover {
|
||||
border-color: #93C5FD;
|
||||
}
|
||||
|
||||
button {
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
</style>
|
||||
@endsection
|
|
@ -155,6 +155,13 @@
|
|||
<label class="mr-2 text-sm font-medium text-gray-600">Password:</label>
|
||||
<input type="password" id="userPassword" class="border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Password User">
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<label class="mr-2 text-sm font-medium text-gray-600">Tipe Pengguna:</label>
|
||||
<select id="userType" class="border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<option value="karyawan">Karyawan</option>
|
||||
<option value="owner">Owner</option>
|
||||
</select>
|
||||
</div>
|
||||
<button id="createUser" class="btn btn-primary">Buat Akun</button>
|
||||
</div>
|
||||
|
||||
|
@ -165,6 +172,7 @@
|
|||
<th class="py-3 px-4 text-left">No</th>
|
||||
<th class="py-3 px-4 text-left">Nama</th>
|
||||
<th class="py-3 px-4 text-left">Email</th>
|
||||
<th class="py-3 px-4 text-left">Tipe Pengguna</th>
|
||||
<th class="py-3 px-4 text-center">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -188,60 +196,16 @@ function loadUsers() {
|
|||
fetch('/users/data')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("Data dari API:", data);
|
||||
const userTableBody = document.getElementById('userTableBody');
|
||||
userTableBody.innerHTML = '';
|
||||
|
||||
// Menambahkan data pengguna baru
|
||||
userTableBody.innerHTML += `
|
||||
<tr class="border-b border-gray-200 hover:bg-gray-50">
|
||||
<td class="py-3 px-4">1</td>
|
||||
<td class="py-3 px-4">Widodo</td>
|
||||
<td class="py-3 px-4">widodo@gmail.com</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button onclick="editUser(1)" class="text-blue-600 hover:text-blue-800">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button onclick="deleteUser(1)" class="text-red-600 hover:text-red-800">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-200 hover:bg-gray-50">
|
||||
<td class="py-3 px-4">2</td>
|
||||
<td class="py-3 px-4">Siti</td>
|
||||
<td class="py-3 px-4">siti@gmail.com</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button onclick="editUser(2)" class="text-blue-600 hover:text-blue-800">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button onclick="deleteUser(2)" class="text-red-600 hover:text-red-800">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-200 hover:bg-gray-50">
|
||||
<td class="py-3 px-4">3</td>
|
||||
<td class="py-3 px-4">Budi</td>
|
||||
<td class="py-3 px-4">budi@gmail.com</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button onclick="editUser(3)" class="text-blue-600 hover:text-blue-800">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button onclick="deleteUser(3)" class="text-red-600 hover:text-red-800">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
// Menambahkan data pengguna dari API
|
||||
data.forEach((user, index) => {
|
||||
userTableBody.innerHTML += `
|
||||
<tr class="border-b border-gray-200 hover:bg-gray-50">
|
||||
<td class="py-3 px-4">${index + 4}</td>
|
||||
<td class="py-3 px-4">${user.name}</td>
|
||||
<td class="py-3 px-4">${index + 1}</td>
|
||||
<td class="py-3 px-4">${user.nama}</td>
|
||||
<td class="py-3 px-4">${user.email}</td>
|
||||
<td class="py-3 px-4">${user.tipe_pengguna}</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button onclick="editUser(${user.id})" class="text-blue-600 hover:text-blue-800">
|
||||
<i class="fas fa-edit"></i>
|
||||
|
@ -257,27 +221,20 @@ function loadUsers() {
|
|||
.catch(error => console.error("Error fetching data:", error));
|
||||
}
|
||||
|
||||
// Function untuk mengedit user
|
||||
function editUser(id) {
|
||||
window.location.href = `/User/${id}/edit`;
|
||||
}
|
||||
|
||||
// Event listener for creating a user
|
||||
document.getElementById('createUser').addEventListener('click', () => {
|
||||
const name = document.getElementById('userName').value;
|
||||
const nama = document.getElementById('userName').value;
|
||||
const email = document.getElementById('userEmail').value;
|
||||
const password = document.getElementById('userPassword').value;
|
||||
const tipe_pengguna = document.getElementById('userType').value;
|
||||
|
||||
fetch('/users/create', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ name, email, password }),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
loadUsers(); // Reload users after creation
|
||||
// Clear input fields
|
||||
document.getElementById('userName').value = '';
|
||||
document.getElementById('userEmail').value = '';
|
||||
document.getElementById('userPassword').value = '';
|
||||
});
|
||||
// Redirect ke route User.create
|
||||
window.location.href = "{{ route('User.create') }}";
|
||||
});
|
||||
|
||||
// Initial load
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
use App\Http\Controllers\HomeController;
|
||||
use App\Http\Controllers\LaporanController;
|
||||
use App\Http\Controllers\UserController;
|
||||
use App\Http\Controllers\AuthController;
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Web Routes
|
||||
|
@ -25,36 +26,38 @@
|
|||
*/
|
||||
|
||||
Route::get('/', [LoginController::class, 'index'])->name('login');
|
||||
Route::post('/login', [LoginController::class, 'authenticate'])->name('login.authenticate');
|
||||
Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
|
||||
|
||||
// Middleware group untuk routes yang memerlukan autentikasi
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::get('/dashboard', [SidebarController::class, 'index'])->name('dashboard');
|
||||
|
||||
|
||||
//untuk Uang Masuk dan keluar
|
||||
Route::get('/uang-masuk', [UangMasukController::class, 'index'])->name('uang-masuk.index');
|
||||
Route::post('/uang-masuk', [UangMasukController::class, 'store'])->name('uangmasuk.store');
|
||||
Route::get('/uang-keluar', [UangKeluarController::class, 'index'])->name('uang-keluar.index');
|
||||
Route::post('/uang-keluar', [UangKeluarController::class, 'store'])->name('uangkeluar.store');
|
||||
Route::get('/input-gaji', [InputGajiController::class, 'index'])->name('input-gaji.index');
|
||||
Route::post('/input-gaji', [InputGajiController::class, 'store'])->name('input-gaji.store');
|
||||
|
||||
//untuk Uang Gaji
|
||||
Route::get('/gaji', [GajiController::class, 'index'])->name('gaji.index');
|
||||
Route::delete('/gaji/{id}', [GajiController::class, 'destroy'])->name('gaji.destroy');
|
||||
Route::get('/gaji/{id}/edit', [GajiController::class, 'edit'])->name('gaji.edit');
|
||||
Route::put('/gaji/{id}', [GajiController::class, 'update'])->name('gaji.update');
|
||||
|
||||
// Tambahkan Data Karyawan
|
||||
Route::get('/data-karyawan', [DataKaryawanController::class, 'index'])->name('data-karyawan.index');
|
||||
Route::post('/data-karyawan', [DataKaryawanController::class, 'store'])->name('karyawan.store');
|
||||
Route::resource('modal-karyawan', ModalKaryawanController::class);
|
||||
|
||||
//untuk Laporan
|
||||
Route::get('/Laporan', [LaporanController::class, 'index'])->name('Laporan.index');
|
||||
Route::get('laporan/export-excel', [App\Http\Controllers\LaporanController::class, 'exportExcel'])->name('laporan.export-excel');
|
||||
Route::get('laporan/export-pdf', [App\Http\Controllers\LaporanController::class, 'exportPDF'])->name('laporan.export-pdf');
|
||||
Route::get('laporan/export-excel', [LaporanController::class, 'exportExcel'])->name('laporan.export-excel');
|
||||
Route::get('laporan/export-pdf', [LaporanController::class, 'exportPDF'])->name('laporan.export-pdf');
|
||||
Route::delete('/laporan/{id}', [LaporanController::class, 'destroy'])->name('laporan.destroy');
|
||||
|
||||
//untuk Home
|
||||
Route::get('/home', [HomeController::class, 'index'])->name('home');
|
||||
|
||||
//untuk User
|
||||
Route::get('/User', [UserController::class, 'index'])->name('User.index');
|
||||
Route::get('/User/create', [UserController::class, 'create'])->name('User.create');
|
||||
Route::post('/User', [UserController::class, 'store'])->name('User.store');
|
||||
Route::get('/User/{id}/edit', [UserController::class, 'edit'])->name('User.edit');
|
||||
Route::put('/User/{id}', [UserController::class, 'update'])->name('User.update');
|
||||
Route::delete('/User/{id}', [UserController::class, 'destroy'])->name('User.destroy');
|
||||
|
||||
// Routes untuk manajemen user
|
||||
Route::get('/users/data', [UserController::class, 'getData']);
|
||||
Route::post('/users/create', [UserController::class, 'create']);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue