Initialer Laravel Commit für BetiX
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

This commit is contained in:
2026-04-04 18:01:50 +02:00
commit 0280278978
374 changed files with 65210 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
<script setup lang="ts">
import { Head, Link, router } from '@inertiajs/vue3';
import { ref } from 'vue';
import CasinoAdminLayout from '@/layouts/admin/CasinoAdminLayout.vue';
const props = defineProps<{
users: any;
roles: string[];
filters: { search: string, role: string };
}>();
const search = ref(props.filters?.search || '');
const filterRole = ref(props.filters?.role || '');
const searchUsers = () => {
router.get(route('admin.users.index'), {
search: search.value,
role: filterRole.value
}, {
preserveState: true,
replace: true
});
};
</script>
<template>
<CasinoAdminLayout>
<Head title="Admin Users" />
<template #title>
User Management
</template>
<template #actions>
<button class="btn-primary">
<i data-lucide="user-plus"></i> Add User
</button>
</template>
<div class="filters-bar">
<div class="search-input">
<i data-lucide="search"></i>
<input type="text" v-model="search" placeholder="Search by ID, Username, Email..." @keyup.enter="searchUsers" />
</div>
<select v-model="filterRole" @change="searchUsers" class="filter-select">
<option value="">All Roles</option>
<option v-for="r in roles" :key="r" :value="r">{{ r }}</option>
</select>
</div>
<div class="table-container">
<table class="admin-table">
<thead>
<tr>
<th>ID</th>
<th>User</th>
<th>Email</th>
<th>Role</th>
<th>Balance</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users.data" :key="user.id">
<td class="font-mono text-muted">{{ user.id }}</td>
<td class="font-bold text-white flex items-center gap-3">
<div class="avatar">{{ user.username.charAt(0).toUpperCase() }}</div>
{{ user.username }}
</td>
<td class="text-muted">{{ user.email }}</td>
<td>
<span class="badge" :class="{'bg-red': user.role === 'Admin', 'bg-blue': user.role === 'Moderator', 'bg-gray': user.role === 'User'}">
{{ user.role }}
</span>
</td>
<td class="font-mono text-white">${{ user.balance }}</td>
<td>
<span v-if="user.is_banned" class="badge bg-red-dim text-red">BANNED</span>
<span v-else-if="user.is_chat_banned" class="badge bg-orange-dim text-orange">MUTED</span>
<span v-else class="badge bg-green-dim text-green">ACTIVE</span>
</td>
<td>
<div class="flex items-center gap-2">
<Link :href="`/admin/users/${user.id}`" class="btn-icon" title="View Profile">
<i data-lucide="eye"></i>
</Link>
<Link :href="`/admin/users/${user.id}?tab=finances`" class="btn-icon text-green-400" title="Manage Finances">
<i data-lucide="wallet"></i>
</Link>
<button class="btn-icon text-red-400" title="Ban User" v-if="!user.is_banned">
<i data-lucide="ban"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
<div class="pagination" v-if="users.last_page > 1">
<!-- Pagination logic here -->
<span class="text-muted">Page {{ users.current_page }} of {{ users.last_page }}</span>
</div>
</div>
</CasinoAdminLayout>
</template>
<style scoped>
.btn-primary { background: #ff007a; color: white; border: none; padding: 10px 16px; border-radius: 8px; font-weight: 700; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; transition: 0.2s; }
.btn-primary:hover { background: #e6006e; }
.filters-bar { display: flex; gap: 16px; margin-bottom: 24px; }
.search-input { position: relative; flex: 1; max-width: 400px; }
.search-input i { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: #a1a1aa; width: 18px; height: 18px; }
.search-input input { width: 100%; background: #111113; border: 1px solid #1f1f22; border-radius: 10px; padding: 12px 12px 12px 40px; color: #fff; font-size: 14px; outline: none; }
.search-input input:focus { border-color: #3f3f46; }
.filter-select { background: #111113; border: 1px solid #1f1f22; border-radius: 10px; padding: 12px 16px; color: #fff; font-size: 14px; outline: none; min-width: 150px; }
.table-container { background: #111113; border: 1px solid #1f1f22; border-radius: 16px; overflow: hidden; }
.admin-table { width: 100%; border-collapse: collapse; text-align: left; }
.admin-table th { background: #0c0c0e; padding: 16px; font-size: 12px; font-weight: 700; color: #a1a1aa; text-transform: uppercase; border-bottom: 1px solid #1f1f22; }
.admin-table td { padding: 16px; border-bottom: 1px solid #1f1f22; font-size: 14px; color: #e4e4e7; }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table tr:hover td { background: #18181b; }
.avatar { width: 32px; height: 32px; background: #27272a; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 800; color: #fff; }
.badge { padding: 4px 8px; border-radius: 6px; font-size: 11px; font-weight: 800; text-transform: uppercase; }
.bg-red { background: #ef4444; color: #fff; }
.bg-blue { background: #3b82f6; color: #fff; }
.bg-gray { background: #27272a; color: #a1a1aa; }
.bg-red-dim { background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.2); }
.bg-orange-dim { background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.2); }
.bg-green-dim { background: rgba(16, 185, 129, 0.1); border: 1px solid rgba(16, 185, 129, 0.2); }
.text-red { color: #ef4444; }
.text-orange { color: #f59e0b; }
.text-green { color: #10b981; }
.text-muted { color: #a1a1aa; }
.btn-icon { display: inline-flex; background: transparent; border: none; color: #a1a1aa; cursor: pointer; padding: 8px; border-radius: 8px; transition: 0.2s; text-decoration: none; }
.btn-icon:hover { background: #27272a; color: #fff; }
.pagination { padding: 16px; border-top: 1px solid #1f1f22; display: flex; justify-content: center; }
</style>