Super Admin Panel

This commit is contained in:
Stephen Gesityan 2025-05-11 14:29:08 +07:00
parent b4d73f7d4d
commit d167f80959
16 changed files with 1514 additions and 2 deletions

View File

@ -63,7 +63,9 @@ protected function authenticated(Request $request, $user)
}
session()->flash('success', 'Login berhasil!');
if ($user->role === 'admin') {
if ($user->role === 'superadmin') {
return redirect('/superadmin');
} elseif ($user->role === 'admin') {
return redirect('/admin');
}
return redirect()->intended($this->redirectTo);

View File

@ -0,0 +1,80 @@
<?php
namespace App\Http\Controllers\superadmin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Venue;
class AdminManagementController extends Controller
{
/**
* Display a listing of the admins.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$query = User::where('role', 'admin');
// Filter by search term
if ($request->filled('search')) {
$search = $request->search;
$query->where(function($q) use ($search) {
$q->where('name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%");
});
}
// Filter by venue
if ($request->filled('venue_id')) {
$query->where('venue_id', $request->venue_id);
}
$admins = $query->paginate(10)->withQueryString();
$venues = Venue::orderBy('name')->get();
return view('superadmin.admin.index', compact('admins', 'venues'));
}
/**
* Show the form for creating a new admin.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$venues = Venue::orderBy('id')->get();
return view('superadmin.admin.create', compact('venues'));
}
/**
* Store a newly created admin in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8|confirmed',
'venue_id' => 'required|exists:venues,id',
'role' => 'required|in:admin,user',
]);
$admin = new User();
$admin->name = $request->name;
$admin->email = $request->email;
$admin->password = bcrypt($request->password);
$admin->role = $request->role;
$admin->venue_id = $request->venue_id;
$admin->email_verified_at = now(); // Admin langsung terverifikasi
$admin->save();
return redirect()->route('superadmin.admin.index')
->with('success', 'Admin berhasil ditambahkan!');
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Http\Controllers\superadmin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Venue;
use App\Models\Table;
class SuperAdminController extends Controller
{
/**
* Display the superadmin dashboard.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
// Menghitung jumlah admin, venue, user, venue aktif, dan meja
$adminCount = User::where('role', 'admin')->count();
$venueCount = Venue::count();
$userCount = User::where('role', 'user')->count();
// $activeVenueCount = Venue::where('status', 'active')->count();
$tableCount = Table::count();
return view('superadmin.dashboard', compact(
'adminCount',
'venueCount',
'userCount',
// 'activeVenueCount',
'tableCount'
));
}
}

View File

@ -0,0 +1,166 @@
<?php
namespace App\Http\Controllers\superadmin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Venue;
use Illuminate\Support\Facades\Storage;
class VenueManagementController extends Controller
{
/**
* Display a listing of the venues.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$venues = Venue::paginate(10);
return view('superadmin.venue.index', compact('venues'));
}
/**
* Show the form for creating a new venue.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('superadmin.venue.create');
}
/**
* Store a newly created venue in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'address' => 'required|string',
'description' => 'required|string',
'phone' => 'required|string|max:20',
'open_time' => 'required|date_format:H:i',
'close_time' => 'required|date_format:H:i',
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
// 'status' => 'required|in:active,inactive',
]);
// Handle file upload
$imagePath = null;
if ($request->hasFile('image')) {
// Get the file extension
$extension = $request->file('image')->getClientOriginalExtension();
// Generate a unique filename
$imageName = time() . '_' . uniqid() . '.' . $extension;
// Store the file in the public disk under venues directory
$imagePath = $request->file('image')->storeAs('venues', $imageName, 'public');
}
$venue = new Venue();
$venue->name = $request->name;
$venue->address = $request->address;
$venue->description = $request->description;
$venue->phone = $request->phone;
$venue->open_time = $request->open_time;
$venue->close_time = $request->close_time;
$venue->image = $imagePath;
// $venue->status = $request->status;
$venue->save();
return redirect()->route('superadmin.venue.index')
->with('success', 'Venue berhasil ditambahkan!');
}
/**
* Show the form for editing the specified venue.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$venue = Venue::findOrFail($id);
return view('superadmin.venue.edit', compact('venue'));
}
/**
* Update the specified venue in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required|string|max:255',
'address' => 'required|string',
'description' => 'required|string',
'phone' => 'required|string|max:20',
'open_time' => 'required|date_format:H:i',
'close_time' => 'required|date_format:H:i',
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
// 'status' => 'required|in:active,inactive',
]);
$venue = Venue::findOrFail($id);
// Handle file upload if a new image is provided
if ($request->hasFile('image')) {
// Delete old image if exists
if ($venue->image && Storage::disk('public')->exists($venue->image)) {
Storage::disk('public')->delete($venue->image);
}
// Get the file extension
$extension = $request->file('image')->getClientOriginalExtension();
// Generate a unique filename
$imageName = time() . '_' . uniqid() . '.' . $extension;
// Store the file in the public disk under venues directory
$imagePath = $request->file('image')->storeAs('venues', $imageName, 'public');
$venue->image = $imagePath;
}
$venue->name = $request->name;
$venue->address = $request->address;
$venue->description = $request->description;
$venue->phone = $request->phone;
$venue->open_time = $request->open_time;
$venue->close_time = $request->close_time;
// $venue->status = $request->status;
$venue->save();
return redirect()->route('superadmin.venue.index')
->with('success', 'Venue berhasil diperbarui!');
}
/**
* Remove the specified venue from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$venue = Venue::findOrFail($id);
// Delete the venue image if exists
if ($venue->image && Storage::disk('public')->exists($venue->image)) {
Storage::disk('public')->delete($venue->image);
}
$venue->delete();
return redirect()->route('superadmin.venue.index')
->with('success', 'Venue berhasil dihapus!');
}
}

View File

@ -65,5 +65,6 @@ class Kernel extends HttpKernel
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'is_admin' => \App\Http\Middleware\IsAdmin::class,
'is_superadmin' => \App\Http\Middleware\IsSuperAdmin::class,
];
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class IsSuperAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if (Auth::check() && Auth::user()->role === 'superadmin') {
return $next($request);
}
abort(403, 'Unauthorized action.');
}
}

View File

@ -21,6 +21,8 @@ class User extends Authenticatable implements MustVerifyEmail
'name',
'email',
'password',
'role',
'venue_id',
];
/**
@ -52,4 +54,12 @@ public function isAdmin()
{
return $this->role === 'admin';
}
/**
* Get the venue that the admin belongs to.
*/
public function venue()
{
return $this->belongsTo(Venue::class);
}
}

View File

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Super Admin Dashboard</title>
<!-- Tailwind CSS via CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- FontAwesome Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Alpine.js -->
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/3.12.0/cdn.min.js"></script>
</head>
<body class="bg-gray-100">
<div x-data="{ sidebarOpen: true }">
<!-- Sidebar -->
<aside :class="sidebarOpen ? 'translate-x-0' : '-translate-x-full'"
class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform bg-blue-800 text-white">
<div class="flex items-center justify-between p-4 border-b border-blue-700">
<h2 class="text-2xl font-bold">Venue System</h2>
<button @click="sidebarOpen = !sidebarOpen" class="lg:hidden">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-4">
<div class="mb-8">
<div class="flex items-center mb-4">
<div class="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center">
<i class="fas fa-user-shield"></i>
</div>
<div class="ml-3">
<p class="text-sm font-medium">Super Admin</p>
<p class="text-xs opacity-75">{{ auth()->user()->name ?? 'Admin' }}</p>
</div>
</div>
</div>
<nav>
<ul>
<li class="mb-2">
<a href="{{ route('superadmin.dashboard') }}"
class="flex items-center p-3 rounded-lg hover:bg-blue-700 {{ request()->routeIs('superadmin.dashboard') ? 'bg-blue-700' : '' }}">
<i class="fas fa-tachometer-alt w-5"></i>
<span class="ml-3">Dashboard</span>
</a>
</li>
<li class="mb-2">
<a href="{{ route('superadmin.admin.index') }}"
class="flex items-center p-3 rounded-lg hover:bg-blue-700 {{ request()->routeIs('superadmin.admin.*') ? 'bg-blue-700' : '' }}">
<i class="fas fa-users-cog w-5"></i>
<span class="ml-3">Manajemen Admin</span>
</a>
</li>
<li class="mb-2">
<a href="{{ route('superadmin.venue.index') }}"
class="flex items-center p-3 rounded-lg hover:bg-blue-700 {{ request()->routeIs('superadmin.venue.*') ? 'bg-blue-700' : '' }}">
<i class="fas fa-building w-5"></i>
<span class="ml-3">Manajemen Venue</span>
</a>
</li>
<li class="mb-2">
<a href="{{ route('logout') }}"
onclick="event.preventDefault(); document.getElementById('logout-form').submit();"
class="flex items-center p-3 rounded-lg hover:bg-blue-700">
<i class="fas fa-sign-out-alt w-5"></i>
<span class="ml-3">Logout</span>
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="hidden">
@csrf
</form>
</li>
</ul>
</nav>
</div>
</aside>
<!-- Content -->
<div :class="sidebarOpen ? 'lg:ml-64' : ''" class="transition-all duration-300">
<!-- Top bar -->
<header class="bg-white border-b border-gray-200 sticky top-0 z-30">
<div class="px-4 py-3 flex items-center justify-between">
<button @click="sidebarOpen = !sidebarOpen" class="text-gray-600 focus:outline-none">
<i class="fas fa-bars"></i>
</button>
<div class="flex items-center space-x-4">
<div class="relative" x-data="{ open: false }">
<button @click="open = !open" class="flex items-center text-gray-600 focus:outline-none">
<span class="mr-2">{{ auth()->user()->name ?? 'Admin' }}</span>
<i class="fas fa-chevron-down text-xs"></i>
</button>
<div x-show="open" @click.away="open = false"
class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50">
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Profile</a>
<a href="{{ route('logout') }}"
onclick="event.preventDefault(); document.getElementById('logout-form').submit();"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Logout</a>
</div>
</div>
</div>
</div>
</header>
<!-- Main content -->
<main class="p-6">
@yield('content')
</main>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,101 @@
@extends('layouts.super-admin')
@section('content')
<div class="mb-6">
<h1 class="text-3xl font-bold text-gray-800">Tambah Admin</h1>
<p class="text-gray-600">Tambahkan akun admin baru untuk venue</p>
</div>
<div class="bg-white rounded-lg shadow p-6">
<form action="{{ route('superadmin.admin.store') }}" method="POST">
@csrf
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Nama Admin -->
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">Nama Admin</label>
<input type="text" name="name" id="name" value="{{ old('name') }}"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('name') border-red-300 @enderror"
required>
@error('name')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Email -->
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input type="email" name="email" id="email" value="{{ old('email') }}"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('email') border-red-300 @enderror"
required>
@error('email')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Password -->
<div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
<input type="password" name="password" id="password"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('password') border-red-300 @enderror"
required>
@error('password')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Konfirmasi Password -->
<div>
<label for="password_confirmation" class="block text-sm font-medium text-gray-700 mb-1">Konfirmasi
Password</label>
<input type="password" name="password_confirmation" id="password_confirmation"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
required>
</div>
<!-- Venue -->
<div>
<label for="venue_id" class="block text-sm font-medium text-gray-700 mb-1">Venue</label>
<select name="venue_id" id="venue_id"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('venue_id') border-red-300 @enderror"
required>
<option value="">-- Pilih Venue --</option>
@foreach($venues as $venue)
<option value="{{ $venue->id }}" {{ old('venue_id') == $venue->id ? 'selected' : '' }}>
{{ $venue->name }}
</option>
@endforeach
</select>
@error('venue_id')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Role (defaultnya Admin, tapi bisa diganti) -->
<div>
<label for="role" class="block text-sm font-medium text-gray-700 mb-1">Role</label>
<select name="role" id="role"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('role') border-red-300 @enderror"
required>
<option value="admin" {{ old('role') == 'admin' ? 'selected' : '' }}>Admin</option>
<option value="user" {{ old('role') == 'user' ? 'selected' : '' }}>User</option>
</select>
@error('role')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
</div>
<div class="mt-6 flex items-center justify-end">
<a href="{{ route('superadmin.admin.index') }}"
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Batal
</a>
<button type="submit"
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Simpan
</button>
</div>
</form>
</div>
@endsection

View File

@ -0,0 +1,100 @@
@extends('layouts.super-admin')
@section('content')
<div class="mb-6">
<h1 class="text-3xl font-bold text-gray-800">Edit Admin</h1>
<p class="text-gray-600">Ubah data dan role admin</p>
</div>
<div class="bg-white rounded-lg shadow p-6">
<form action="{{ route('superadmin.admin.update', $admin->id) }}" method="POST">
@csrf
@method('PUT')
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Nama Admin (read-only, tidak bisa diubah) -->
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">Nama Admin</label>
<input type="text" name="name" id="name" value="{{ old('name', $admin->name) }}"
class="block w-full rounded-md border-gray-300 bg-gray-100 shadow-sm @error('name') border-red-300 @enderror"
readonly>
@error('name')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Email (read-only, tidak bisa diubah) -->
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input type="email" name="email" id="email" value="{{ old('email', $admin->email) }}"
class="block w-full rounded-md border-gray-300 bg-gray-100 shadow-sm @error('email') border-red-300 @enderror"
readonly>
@error('email')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Password (opsional) -->
<div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password (Opsional)</label>
<input type="password" name="password" id="password"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('password') border-red-300 @enderror">
<p class="mt-1 text-xs text-gray-500">Kosongkan jika tidak ingin mengubah password</p>
@error('password')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Konfirmasi Password (opsional) -->
<div>
<label for="password_confirmation" class="block text-sm font-medium text-gray-700 mb-1">Konfirmasi Password</label>
<input type="password" name="password_confirmation" id="password_confirmation"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
</div>
<!-- Venue -->
<div>
<label for="venue_id" class="block text-sm font-medium text-gray-700 mb-1">Venue</label>
<select name="venue_id" id="venue_id"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('venue_id') border-red-300 @enderror"
required>
<option value="">-- Pilih Venue --</option>
@foreach($venues as $venue)
<option value="{{ $venue->id }}" {{ old('venue_id', $admin->venue_id) == $venue->id ? 'selected' : '' }}>
{{ $venue->name }}
</option>
@endforeach
</select>
@error('venue_id')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Role -->
<div>
<label for="role" class="block text-sm font-medium text-gray-700 mb-1">Role</label>
<select name="role" id="role"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 @error('role') border-red-300 @enderror"
required>
<option value="admin" {{ old('role', $admin->role) == 'admin' ? 'selected' : '' }}>Admin</option>
<option value="user" {{ old('role', $admin->role) == 'user' ? 'selected' : '' }}>User</option>
</select>
@error('role')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
</div>
<div class="mt-6 flex items-center justify-end">
<a href="{{ route('superadmin.admin.index') }}"
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Batal
</a>
<button type="submit"
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Simpan Perubahan
</button>
</div>
</form>
</div>
@endsection

View File

@ -0,0 +1,222 @@
@extends('layouts.super-admin')
@section('content')
<div class="mb-6 flex justify-between items-center">
<div>
<h1 class="text-3xl font-bold text-gray-800">Manajemen Admin</h1>
<p class="text-gray-600">Kelola admin untuk setiap venue</p>
</div>
<a href="{{ route('superadmin.admin.create') }}"
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center">
<i class="fas fa-plus mr-2"></i>
Tambah Admin
</a>
</div>
@if(session('success'))
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-6" role="alert">
<p>{{ session('success') }}</p>
</div>
@endif
<!-- Filter and Search -->
<div class="bg-white rounded-lg shadow mb-6 p-4">
<form action="{{ route('superadmin.admin.index') }}" method="GET">
<div class="flex flex-col md:flex-row gap-4">
<div class="flex-grow">
<label for="search" class="block text-sm font-medium text-gray-700 mb-1">Cari</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-search text-gray-400"></i>
</div>
<input type="text" id="search" name="search" value="{{ request('search') }}"
class="pl-10 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
placeholder="Cari nama atau email">
</div>
</div>
<div class="md:w-64">
<label for="venue_filter" class="block text-sm font-medium text-gray-700 mb-1">Filter Venue</label>
<select id="venue_filter" name="venue_id"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
<option value="">Semua Venue</option>
@foreach($venues as $venue)
<option value="{{ $venue->id }}" {{ request('venue_id') == $venue->id ? 'selected' : '' }}>
{{ $venue->name }}
</option>
@endforeach
</select>
</div>
<div class="self-end">
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 text-sm">
Cari
</button>
<a href="{{ route('superadmin.admin.index') }}"
class="px-4 py-2 border border-gray-300 rounded-md bg-white hover:bg-gray-50 text-sm ml-2">
Reset Filter
</a>
</div>
</div>
</form>
</div>
<!-- Admin Table -->
<div class="bg-white rounded-lg shadow overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Nama
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Email
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Venue
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Status
</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Terdaftar
</th>
<th scope="col"
class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
Aksi
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse($admins as $admin)
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div
class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600">
<i class="fas fa-user"></i>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">{{ $admin->name }}</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">{{ $admin->email }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">
@if($admin->venue)
{{ $admin->venue->name }}
@else
<span class="text-gray-400">Tidak ada venue</span>
@endif
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ $admin->email_verified_at ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800' }}">
{{ $admin->email_verified_at ? 'Terverifikasi' : 'Belum Verifikasi' }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{{ $admin->created_at->format('d M Y') }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<a href="{{ route('superadmin.admin.edit', $admin->id) }}"
class="text-blue-600 hover:text-blue-800 mr-3">
<i class="fas fa-edit"></i>
</a>
<button type="button" data-admin-id="{{ $admin->id }}" data-admin-name="{{ $admin->name }}"
class="text-red-600 hover:text-red-800 delete-admin-btn">
<i class="fas fa-trash-alt"></i>
</button>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-4 text-center text-gray-500">
Tidak ada data admin ditemukan
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- Pagination -->
<div class="px-6 py-4 border-t border-gray-200">
{{ $admins->links() }}
</div>
</div>
<!-- Delete Admin Confirmation Modal -->
<div id="deleteAdminModal" tabindex="-1" aria-hidden="true"
class="fixed top-0 left-0 right-0 z-50 hidden w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-modal md:h-full">
<div class="relative w-full h-full max-w-md md:h-auto">
<div class="relative bg-white rounded-lg shadow">
<div class="flex items-center justify-between p-4 border-b">
<h3 class="text-xl font-semibold text-gray-900">
Konfirmasi Hapus
</h3>
<button type="button"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center"
data-modal-hide="deleteAdminModal">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-6 text-center">
<i class="fas fa-exclamation-triangle text-5xl text-yellow-400 mb-4"></i>
<h3 class="mb-5 text-lg font-normal text-gray-500">Apakah Anda yakin ingin menghapus admin <span
id="admin-name-to-delete" class="font-medium"></span>?</h3>
<form id="deleteAdminForm" method="POST" action="">
@csrf
@method('DELETE')
<button type="submit"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center mr-2">
Ya, saya yakin
</button>
<button type="button" data-modal-hide="deleteAdminModal"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10">
Batal
</button>
</form>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Handle delete admin button clicks
const deleteButtons = document.querySelectorAll('.delete-admin-btn');
deleteButtons.forEach(button => {
button.addEventListener('click', function () {
const adminId = this.getAttribute('data-admin-id');
const adminName = this.getAttribute('data-admin-name');
const form = document.getElementById('deleteAdminForm');
form.action = "{{ route('superadmin.admin.destroy', '') }}/" + adminId;
// Set the admin name in the confirmation message
document.getElementById('admin-name-to-delete').textContent = adminName;
// Show the delete confirmation modal
const modal = document.getElementById('deleteAdminModal');
modal.classList.remove('hidden');
});
});
// Modal hide functionality
const modalHideButtons = document.querySelectorAll('[data-modal-hide]');
modalHideButtons.forEach(button => {
button.addEventListener('click', function () {
const modalId = this.getAttribute('data-modal-hide');
document.getElementById(modalId).classList.add('hidden');
});
});
});
</script>
@endsection

View File

@ -0,0 +1,120 @@
@extends('layouts.super-admin')
@section('content')
<div class="mb-6">
<h1 class="text-3xl font-bold text-gray-800">Dashboard Super Admin</h1>
<p class="text-gray-600">Selamat datang di panel kontrol Super Admin</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h2 class="text-xl font-semibold text-gray-800">
<i class="fas fa-users-cog mr-2 text-blue-600"></i>Admin
</h2>
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-3 py-1 rounded-full">
Total: {{ $adminCount ?? 0 }}
</span>
</div>
<p class="text-gray-600 mb-4">Kelola semua admin venue dalam sistem</p>
<a href="{{ route('superadmin.admin.index') }}"
class="inline-flex items-center text-blue-600 hover:text-blue-800">
Lihat Detail
<i class="fas fa-arrow-right ml-2"></i>
</a>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h2 class="text-xl font-semibold text-gray-800">
<i class="fas fa-building mr-2 text-green-600"></i>Venue
</h2>
<span class="bg-green-100 text-green-800 text-xs font-medium px-3 py-1 rounded-full">
Total: {{ $venueCount ?? 0 }}
</span>
</div>
<p class="text-gray-600 mb-4">Kelola semua venue dalam sistem</p>
<a href="{{ route('superadmin.venue.index') }}"
class="inline-flex items-center text-green-600 hover:text-green-800">
Lihat Detail
<i class="fas fa-arrow-right ml-2"></i>
</a>
</div>
</div>
<!-- Recent Activity Section -->
<div class="bg-white rounded-lg shadow overflow-hidden mb-6">
<div class="border-b border-gray-200 px-6 py-4">
<h3 class="text-lg font-semibold text-gray-800">Aktivitas Terbaru</h3>
</div>
<div class="p-6">
<div class="space-y-4">
<!-- Sample activity items - in production, these would come from database -->
<div class="flex items-center">
<div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600">
<i class="fas fa-user-plus"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-900">Admin baru ditambahkan</p>
<p class="text-xs text-gray-500">2 jam yang lalu</p>
</div>
</div>
<div class="flex items-center">
<div class="w-10 h-10 rounded-full bg-green-100 flex items-center justify-center text-green-600">
<i class="fas fa-building"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-900">Venue baru ditambahkan</p>
<p class="text-xs text-gray-500">1 hari yang lalu</p>
</div>
</div>
<div class="flex items-center">
<div class="w-10 h-10 rounded-full bg-yellow-100 flex items-center justify-center text-yellow-600">
<i class="fas fa-edit"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-900">Venue diperbarui</p>
<p class="text-xs text-gray-500">2 hari yang lalu</p>
</div>
</div>
</div>
</div>
</div>
<!-- Quick Stats -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="rounded-full bg-blue-100 p-3">
<i class="fas fa-users text-blue-600 text-xl"></i>
</div>
<div class="ml-4">
<h4 class="text-gray-500 text-sm">Total Pengguna</h4>
<p class="text-2xl font-bold text-gray-800">{{ $userCount ?? 0 }}</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="rounded-full bg-green-100 p-3">
<i class="fas fa-check-circle text-green-600 text-xl"></i>
</div>
<div class="ml-4">
<h4 class="text-gray-500 text-sm">Venue Aktif</h4>
<p class="text-2xl font-bold text-gray-800">{{ $activeVenueCount ?? 0 }}</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="rounded-full bg-purple-100 p-3">
<i class="fas fa-table text-purple-600 text-xl"></i>
</div>
<div class="ml-4">
<h4 class="text-gray-500 text-sm">Total Meja</h4>
<p class="text-2xl font-bold text-gray-800">{{ $tableCount ?? 0 }}</p>
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,142 @@
@extends('layouts.super-admin')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Tambah Venue Baru') }}</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 method="POST" action="{{ route('superadmin.venue.store') }}" enctype="multipart/form-data">
@csrf
<div class="form-group row mb-3">
<label for="name"
class="col-md-4 col-form-label text-md-right">{{ __('Nama Venue') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror"
name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="address"
class="col-md-4 col-form-label text-md-right">{{ __('Alamat') }}</label>
<div class="col-md-6">
<textarea id="address" class="form-control @error('address') is-invalid @enderror"
name="address" required>{{ old('address') }}</textarea>
@error('address')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="phone"
class="col-md-4 col-form-label text-md-right">{{ __('Nomor Telepon') }}</label>
<div class="col-md-6">
<input id="phone" type="text" class="form-control @error('phone') is-invalid @enderror"
name="phone" value="{{ old('phone') }}" required>
@error('phone')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="description"
class="col-md-4 col-form-label text-md-right">{{ __('Deskripsi') }}</label>
<div class="col-md-6">
<textarea id="description"
class="form-control @error('description') is-invalid @enderror" name="description"
rows="4" required>{{ old('description') }}</textarea>
@error('description')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="open_time"
class="col-md-4 col-form-label text-md-right">{{ __('Jam Buka') }}</label>
<div class="col-md-6">
<input id="open_time" type="time"
class="form-control @error('open_time') is-invalid @enderror" name="open_time"
value="{{ old('open_time') }}" required>
@error('open_time')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="close_time"
class="col-md-4 col-form-label text-md-right">{{ __('Jam Tutup') }}</label>
<div class="col-md-6">
<input id="close_time" type="time"
class="form-control @error('close_time') is-invalid @enderror" name="close_time"
value="{{ old('close_time') }}" required>
@error('close_time')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="image"
class="col-md-4 col-form-label text-md-right">{{ __('Gambar Venue') }}</label>
<div class="col-md-6">
<input id="image" type="file" class="form-control @error('image') is-invalid @enderror"
name="image" accept="image/*" required>
<small class="form-text text-muted">Format: JPG, PNG, GIF. Ukuran maksimal: 2MB</small>
@error('image')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Simpan') }}
</button>
<a href="{{ route('superadmin.venue.index') }}" class="btn btn-secondary">
{{ __('Batal') }}
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,168 @@
@extends('layouts.super-admin')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Edit Venue') }}</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 method="POST" action="{{ route('superadmin.venue.update', $venue->id) }}"
enctype="multipart/form-data">
@csrf
@method('PUT')
<div class="form-group row mb-3">
<label for="name"
class="col-md-4 col-form-label text-md-right">{{ __('Nama Venue') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror"
name="name" value="{{ old('name', $venue->name) }}" required autocomplete="name"
autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="address"
class="col-md-4 col-form-label text-md-right">{{ __('Alamat') }}</label>
<div class="col-md-6">
<textarea id="address" class="form-control @error('address') is-invalid @enderror"
name="address" required>{{ old('address', $venue->address) }}</textarea>
@error('address')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="phone"
class="col-md-4 col-form-label text-md-right">{{ __('Nomor Telepon') }}</label>
<div class="col-md-6">
<input id="phone" type="text" class="form-control @error('phone') is-invalid @enderror"
name="phone" value="{{ old('phone', $venue->phone) }}" required>
@error('phone')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="description"
class="col-md-4 col-form-label text-md-right">{{ __('Deskripsi') }}</label>
<div class="col-md-6">
<textarea id="description"
class="form-control @error('description') is-invalid @enderror" name="description"
rows="4" required>{{ old('description', $venue->description) }}</textarea>
@error('description')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="open_time"
class="col-md-4 col-form-label text-md-right">{{ __('Jam Buka') }}</label>
<div class="col-md-6">
<input id="open_time" type="time"
class="form-control @error('open_time') is-invalid @enderror" name="open_time"
value="{{ old('open_time', $venue->open_time_formatted) }}" required>
@error('open_time')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="close_time"
class="col-md-4 col-form-label text-md-right">{{ __('Jam Tutup') }}</label>
<div class="col-md-6">
<input id="close_time" type="time"
class="form-control @error('close_time') is-invalid @enderror" name="close_time"
value="{{ old('close_time', $venue->close_time_formatted) }}" required>
@error('close_time')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="image"
class="col-md-4 col-form-label text-md-right">{{ __('Gambar Venue') }}</label>
<div class="col-md-6">
@if($venue->image)
<div class="mb-2">
<img src="{{ $venue->image_url }}" alt="{{ $venue->name }}" class="img-thumbnail"
style="max-height: 150px;">
</div>
@endif
<input id="image" type="file" class="form-control @error('image') is-invalid @enderror"
name="image" accept="image/*">
<small class="form-text text-muted">Format: JPG, PNG, GIF. Ukuran maksimal: 2MB. Biarkan
kosong jika tidak ingin mengubah gambar.</small>
@error('image')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-3">
<label for="status" class="col-md-4 col-form-label text-md-right">{{ __('Status') }}</label>
<div class="col-md-6">
<select id="status" class="form-control @error('status') is-invalid @enderror"
name="status" required>
<option value="active" {{ old('status', $venue->status) == 'active' ? 'selected' : '' }}>Aktif</option>
<option value="inactive" {{ old('status', $venue->status) == 'inactive' ? 'selected' : '' }}>Tidak Aktif</option>
</select>
@error('status')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Perbarui') }}
</button>
<a href="{{ route('superadmin.venue.index') }}" class="btn btn-secondary">
{{ __('Batal') }}
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,202 @@
@extends('layouts.super-admin')
@section('content')
<div class="mb-6 flex justify-between items-center">
<div>
<h1 class="text-3xl font-bold text-gray-800">Manajemen Venue</h1>
<p class="text-gray-600">Kelola semua venue dalam sistem</p>
</div>
<a href="{{ route('superadmin.venue.create') }}"
class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 flex items-center">
<i class="fas fa-plus mr-2"></i>
Tambah Venue
</a>
</div>
<!-- Flash Messages -->
@if(session('success'))
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-6" role="alert">
<p>{{ session('success') }}</p>
</div>
@endif
@if(session('error'))
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-6" role="alert">
<p>{{ session('error') }}</p>
</div>
@endif
<!-- Filter and Search -->
<div class="bg-white rounded-lg shadow mb-6 p-4">
<form action="{{ route('superadmin.venue.index') }}" method="GET">
<div class="flex flex-col md:flex-row gap-4">
<div class="flex-grow">
<label for="search" class="block text-sm font-medium text-gray-700 mb-1">Cari</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-search text-gray-400"></i>
</div>
<input type="text" id="search" name="search" value="{{ request('search') }}"
class="pl-10 block w-full rounded-md border-gray-300 shadow-sm focus:border-green-500 focus:ring-green-500"
placeholder="Cari nama venue atau lokasi">
</div>
</div>
<div>
<label for="status" class="block text-sm font-medium text-gray-700 mb-1">Status</label>
<select id="status" name="status"
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-green-500 focus:ring-green-500">
<option value="">Semua Status</option>
<option value="active" {{ request('status') == 'active' ? 'selected' : '' }}>Aktif</option>
<option value="inactive" {{ request('status') == 'inactive' ? 'selected' : '' }}>Tidak Aktif</option>
</select>
</div>
<div class="self-end">
<button type="submit" class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 text-sm">
Filter
</button>
<a href="{{ route('superadmin.venue.index') }}"
class="px-4 py-2 border border-gray-300 rounded-md bg-white hover:bg-gray-50 text-sm ml-2">
Reset
</a>
</div>
</div>
</form>
</div>
<!-- Venue Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@forelse($venues as $venue)
<div class="bg-white rounded-lg shadow overflow-hidden">
<div class="relative">
<img src="{{ asset('storage/' . ($venue->image ?? 'images/venue-placeholder.jpg')) }}"
alt="{{ $venue->name }}" class="w-full h-48 object-cover">
<div class="absolute top-3 right-3 flex gap-2">
<a href="{{ route('superadmin.venue.edit', $venue->id) }}"
class="p-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
<i class="fas fa-edit"></i>
</a>
<button type="button" onclick="confirmDelete({{ $venue->id }})"
class="p-2 bg-red-600 text-white rounded-lg hover:bg-red-700">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
<div class="p-5">
<h3 class="text-xl font-semibold text-gray-900 mb-2">{{ $venue->name }}</h3>
<div class="flex items-center mb-2">
<i class="fas fa-map text-gray-500 mr-2"></i>
<span class="text-gray-600 truncate">{{ $venue->address }}</span>
</div>
<div class="flex items-center mb-2">
<i class="fas fa-phone text-gray-500 mr-2"></i>
<span class="text-gray-600">{{ $venue->phone }}</span>
</div>
<div class="flex items-center mb-4">
<i
class="fas fa-check-circle {{ $venue->status == 'active' ? 'text-green-500' : 'text-red-500' }} mr-2"></i>
<span class="text-gray-600">{{ $venue->status == 'active' ? 'Aktif' : 'Tidak Aktif' }}</span>
</div>
<div class="border-t pt-4">
<div class="flex justify-between items-center">
<div class="text-sm text-gray-500">
<span class="font-medium">{{ $venue->created_at->format('d M Y') }}</span>
</div>
<a href="{{ route('superadmin.venue.edit', $venue->id) }}"
class="text-green-600 hover:text-green-800 flex items-center text-sm">
Detail
<i class="fas fa-arrow-right ml-1"></i>
</a>
</div>
</div>
</div>
</div>
@empty
<div class="col-span-3 bg-white rounded-lg shadow p-6 text-center">
<i class="fas fa-building text-gray-300 text-5xl mb-4"></i>
<h3 class="text-lg font-medium text-gray-900 mb-1">Belum ada venue</h3>
<p class="text-gray-500 mb-4">Mulai tambahkan venue baru untuk mengelola bisnis Anda</p>
<a href="{{ route('superadmin.venue.create') }}"
class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 inline-flex items-center">
<i class="fas fa-plus mr-2"></i>
Tambah Venue
</a>
</div>
@endforelse
</div>
<!-- Pagination -->
@if($venues->hasPages())
<div class="mt-6">
{{ $venues->links() }}
</div>
@endif
<!-- Delete Venue Confirmation Modal -->
<div id="deleteVenueModal" tabindex="-1" aria-hidden="true"
class="fixed top-0 left-0 right-0 z-50 hidden w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-modal md:h-full">
<div class="relative w-full h-full max-w-md md:h-auto">
<div class="relative bg-white rounded-lg shadow">
<div class="flex items-center justify-between p-4 border-b">
<h3 class="text-xl font-semibold text-gray-900">
Konfirmasi Hapus
</h3>
<button type="button" onclick="closeDeleteModal()"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-6 text-center">
<i class="fas fa-exclamation-triangle text-5xl text-yellow-400 mb-4"></i>
<h3 class="mb-5 text-lg font-normal text-gray-500">Apakah Anda yakin ingin menghapus venue ini? Semua
data terkait dengan venue ini akan ikut terhapus.</h3>
<form id="deleteVenueForm" method="POST" action="">
@csrf
@method('DELETE')
<button type="submit"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center mr-2">
Ya, saya yakin
</button>
<button type="button" onclick="closeDeleteModal()"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10">
Batal
</button>
</form>
</div>
</div>
</div>
</div>
<script>
function confirmDelete(venueId) {
const form = document.getElementById('deleteVenueForm');
form.action = "{{ route('superadmin.venue.destroy', '') }}/" + venueId;
// Show modal
const modal = document.getElementById('deleteVenueModal');
modal.classList.remove('hidden');
}
function closeDeleteModal() {
const modal = document.getElementById('deleteVenueModal');
modal.classList.add('hidden');
}
document.addEventListener('DOMContentLoaded', function () {
// Escape key closes modal
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
closeDeleteModal();
}
});
// Click outside modal closes it
window.onclick = function (event) {
const modal = document.getElementById('deleteVenueModal');
if (event.target === modal) {
closeDeleteModal();
}
}
});
</script>
@endsection

View File

@ -9,6 +9,9 @@
use App\Http\Controllers\admin\TableController;
use App\Http\Controllers\admin\AdminController;
use App\Http\Controllers\Auth\VerificationController;
use App\Http\Controllers\superadmin\SuperAdminController;
use App\Http\Controllers\superadmin\AdminManagementController;
use App\Http\Controllers\superadmin\VenueManagementController;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;
@ -75,3 +78,24 @@
Route::put('/tables/{id}', [TableController::class, 'update'])->name('admin.tables.update');
Route::delete('/tables/{id}', [TableController::class, 'destroy'])->name('admin.tables.destroy');
});
// Superadmin routes
Route::middleware(['auth', 'verified', 'is_superadmin'])->prefix('superadmin')->group(function () {
Route::get('/', [App\Http\Controllers\superadmin\SuperAdminController::class, 'index'])->name('superadmin.dashboard');
// Tambahkan route untuk manajemen Admin
Route::get('/admin', [AdminManagementController::class, 'index'])->name('superadmin.admin.index');
Route::get('/admin/create', [AdminManagementController::class, 'create'])->name('superadmin.admin.create');
Route::post('/admin', [AdminManagementController::class, 'store'])->name('superadmin.admin.store');
Route::get('/admin/{id}/edit', [AdminManagementController::class, 'edit'])->name('superadmin.admin.edit');
Route::put('/admin/{id}', [AdminManagementController::class, 'update'])->name('superadmin.admin.update');
Route::delete('/admin/{id}', [AdminManagementController::class, 'destroy'])->name('superadmin.admin.destroy');
// Tambahkan route untuk manajemen Venue
Route::get('/venue', [VenueManagementController::class, 'index'])->name('superadmin.venue.index');
Route::get('/venue/create', [VenueManagementController::class, 'create'])->name('superadmin.venue.create');
Route::post('/venue', [VenueManagementController::class, 'store'])->name('superadmin.venue.store');
Route::get('/venue/{id}/edit', [VenueManagementController::class, 'edit'])->name('superadmin.venue.edit');
Route::put('/venue/{id}', [VenueManagementController::class, 'update'])->name('superadmin.venue.update');
Route::delete('/venue/{id}', [VenueManagementController::class, 'destroy'])->name('superadmin.venue.destroy');
});