156 lines
9.1 KiB
Vue
156 lines
9.1 KiB
Vue
<script setup lang="ts">
|
|
import { useForm, Head } from '@inertiajs/vue3';
|
|
import { ref } from 'vue';
|
|
import UserLayout from '@/layouts/admin/CasinoAdminLayout.vue';
|
|
|
|
defineProps<{
|
|
users: any;
|
|
}>();
|
|
|
|
const editingUser = ref<any>(null);
|
|
const form = useForm({
|
|
vip_level: 0,
|
|
balance: '0',
|
|
is_banned: false,
|
|
is_chat_banned: false,
|
|
ban_reason: '',
|
|
ban_ends_at: '', // optional end time for account ban
|
|
chat_ban_ends_at: '', // optional end time for chat ban
|
|
role: 'User',
|
|
});
|
|
|
|
const openEditModal = (user: any) => {
|
|
editingUser.value = user;
|
|
form.vip_level = user.vip_level;
|
|
form.balance = user.balance;
|
|
form.is_banned = user.is_banned || false;
|
|
form.is_chat_banned = user.is_chat_banned || false;
|
|
form.ban_reason = user.ban_reason || '';
|
|
form.ban_ends_at = '';
|
|
form.chat_ban_ends_at = '';
|
|
form.role = user.role || 'User';
|
|
};
|
|
|
|
const saveUser = () => {
|
|
if (!editingUser.value) return;
|
|
form.post(`/admin/users/${editingUser.value.id}`, {
|
|
preserveScroll: true,
|
|
onSuccess: () => {
|
|
editingUser.value = null;
|
|
}
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<UserLayout>
|
|
<Head title="Admin Dashboard" />
|
|
<div class="p-4 sm:p-6 lg:p-8">
|
|
<h1 class="text-2xl font-bold text-white mb-6">Admin Dashboard</h1>
|
|
|
|
<div class="bg-[#0f0f0f] border border-[#1f1f1f] rounded-xl shadow-lg">
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-sm text-left text-gray-400">
|
|
<thead class="text-xs text-gray-400 uppercase bg-[#141414]">
|
|
<tr>
|
|
<th scope="col" class="px-6 py-3">ID</th>
|
|
<th scope="col" class="px-6 py-3">User</th>
|
|
<th scope="col" class="px-6 py-3">Role</th>
|
|
<th scope="col" class="px-6 py-3">Balance</th>
|
|
<th scope="col" class="px-6 py-3">Status</th>
|
|
<th scope="col" class="px-6 py-3"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="user in users.data" :key="user.id" class="border-b border-[#1f1f1f] hover:bg-[#141414]">
|
|
<td class="px-6 py-4 font-bold text-white">{{ user.id }}</td>
|
|
<td class="px-6 py-4 font-bold text-white">{{ user.username }}</td>
|
|
<td class="px-6 py-4">
|
|
<span :class="{'text-red-500': user.role === 'Admin', 'text-blue-400': user.role === 'Staff'}">{{ user.role }}</span>
|
|
</td>
|
|
<td class="px-6 py-4">${{ user.balance }}</td>
|
|
<td class="px-6 py-4 flex gap-2">
|
|
<span v-if="user.is_banned" class="px-2 py-1 text-xs font-bold text-red-400 bg-red-900/50 rounded-full">BANNED</span>
|
|
<span v-if="user.is_chat_banned" class="px-2 py-1 text-xs font-bold text-orange-400 bg-orange-900/50 rounded-full">MUTED</span>
|
|
<span v-if="!user.is_banned && !user.is_chat_banned" class="px-2 py-1 text-xs font-bold text-green-400 bg-green-900/50 rounded-full">Active</span>
|
|
</td>
|
|
<td class="px-6 py-4 text-right">
|
|
<button @click="openEditModal(user)" class="font-medium text-blue-500 hover:underline">Edit</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Modal -->
|
|
<div v-if="editingUser" class="fixed inset-0 bg-black/80 z-50 flex items-center justify-center backdrop-blur-sm" @click.self="editingUser = null">
|
|
<div class="bg-[#111] border border-[#333] rounded-xl p-6 w-full max-w-md shadow-2xl">
|
|
<h2 class="text-lg font-bold mb-4 text-white">Edit {{ editingUser.username }}</h2>
|
|
<form @submit.prevent="saveUser" class="space-y-4">
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">VIP Level</label>
|
|
<input type="number" v-model="form.vip_level" class="w-full bg-[#0a0a0a] border border-[#333] rounded-lg p-3 text-white text-sm focus:border-blue-500 outline-none">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">Role</label>
|
|
<select v-model="form.role" class="w-full bg-[#0a0a0a] border border-[#333] rounded-lg p-3 text-white text-sm focus:border-blue-500 outline-none">
|
|
<option>User</option>
|
|
<option>Staff</option>
|
|
<option>Admin</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">Balance</label>
|
|
<input type="text" v-model="form.balance" class="w-full bg-[#0a0a0a] border border-[#333] rounded-lg p-3 text-white text-sm focus:border-blue-500 outline-none">
|
|
</div>
|
|
|
|
<div class="border-t border-[#222] pt-4 mt-4">
|
|
<h3 class="text-sm font-bold text-red-500 uppercase mb-3">Restrictions</h3>
|
|
|
|
<div class="space-y-3">
|
|
<label class="flex items-center p-3 bg-[#1a0505] border border-red-900/30 rounded-lg cursor-pointer hover:bg-[#2a0a0a] transition">
|
|
<input type="checkbox" v-model="form.is_banned" class="w-4 h-4 text-red-600 bg-gray-700 border-gray-600 rounded focus:ring-red-500">
|
|
<span class="ml-3 text-sm font-bold text-red-400">Account Ban (Full Lock)</span>
|
|
</label>
|
|
|
|
<label class="flex items-center p-3 bg-[#1a1005] border border-orange-900/30 rounded-lg cursor-pointer hover:bg-[#2a1a0a] transition">
|
|
<input type="checkbox" v-model="form.is_chat_banned" class="w-4 h-4 text-orange-600 bg-gray-700 border-gray-600 rounded focus:ring-orange-500">
|
|
<span class="ml-3 text-sm font-bold text-orange-400">Chat Ban (Mute)</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div v-if="form.is_banned || form.is_chat_banned" class="mt-4 space-y-4">
|
|
<div>
|
|
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">Reason</label>
|
|
<input type="text" v-model="form.ban_reason" placeholder="Why?" class="w-full bg-[#0a0a0a] border border-[#333] rounded-lg p-3 text-white text-sm focus:border-red-500 outline-none">
|
|
</div>
|
|
|
|
<div v-if="form.is_banned">
|
|
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">Account Ban ends at (optional)</label>
|
|
<input type="datetime-local" v-model="form.ban_ends_at" class="w-full bg-[#0a0a0a] border border-[#333] rounded-lg p-3 text-white text-sm focus:border-red-500 outline-none">
|
|
<p class="mt-1 text-[11px] text-gray-500">Leave empty for permanent ban. Uses server timezone.</p>
|
|
</div>
|
|
|
|
<div v-if="form.is_chat_banned">
|
|
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">Chat Ban ends at (optional)</label>
|
|
<input type="datetime-local" v-model="form.chat_ban_ends_at" class="w-full bg-[#0a0a0a] border border-[#333] rounded-lg p-3 text-white text-sm focus:border-orange-500 outline-none">
|
|
<p class="mt-1 text-[11px] text-gray-500">Leave empty for permanent mute. Uses server timezone.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end gap-3 pt-4">
|
|
<button type="button" @click="editingUser = null" class="px-4 py-2 text-sm font-bold text-gray-400 hover:text-white transition">Cancel</button>
|
|
<button type="submit" :disabled="form.processing" class="px-6 py-2 text-sm font-bold text-white bg-blue-600 rounded-lg hover:bg-blue-500 transition shadow-lg shadow-blue-900/20">Save Changes</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</UserLayout>
|
|
</template>
|