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,281 @@
<script setup lang="ts">
import { Head, useForm } from '@inertiajs/vue3';
import { onMounted, nextTick } from 'vue';
import CasinoAdminLayout from '@/layouts/admin/CasinoAdminLayout.vue';
const props = defineProps<{
settings: {
site_name: string;
site_tagline: string;
primary_color: string;
logo_url: string;
favicon_url: string;
maintenance_mode: boolean;
registration_open: boolean;
min_deposit_usd: number;
max_deposit_usd: number;
min_withdrawal_usd: number;
max_withdrawal_usd: number;
max_bet_usd: number;
house_edge_percent: number;
footer_text: string;
support_email: string;
terms_url: string;
privacy_url: string;
currency_symbol: string;
};
}>();
const form = useForm({ ...props.settings });
function submit() {
form.post('/admin/settings/site', { preserveScroll: true });
}
onMounted(() => {
nextTick(() => { if ((window as any).lucide) (window as any).lucide.createIcons(); });
});
</script>
<template>
<CasinoAdminLayout>
<Head title="Admin Site Settings" />
<template #title>Site Einstellungen</template>
<div class="page-wrap">
<!-- Flash -->
<div v-if="($page.props as any).flash?.success" class="alert-success">
<i data-lucide="check-circle"></i>
{{ ($page.props as any).flash.success }}
</div>
<!-- General -->
<div class="card">
<div class="card-head">
<div>
<h2>Allgemein</h2>
<p class="card-subtitle">Name, Branding und Design.</p>
</div>
</div>
<div class="card-body">
<div class="form-grid">
<div class="field">
<label class="field-label">Site-Name</label>
<input type="text" v-model="form.site_name" class="field-input" maxlength="100">
<div class="field-error" v-if="form.errors.site_name">{{ form.errors.site_name }}</div>
</div>
<div class="field">
<label class="field-label">Slogan</label>
<input type="text" v-model="form.site_tagline" class="field-input" maxlength="200">
</div>
<div class="field">
<label class="field-label">Primärfarbe (Hex)</label>
<div class="color-row">
<input type="color" v-model="form.primary_color" class="color-picker">
<input type="text" v-model="form.primary_color" class="field-input" maxlength="7" placeholder="#df006a">
</div>
</div>
<div class="field">
<label class="field-label">Währungssymbol</label>
<input type="text" v-model="form.currency_symbol" class="field-input" maxlength="10" placeholder="BTX">
</div>
<div class="field full">
<label class="field-label">Logo-URL</label>
<input type="url" v-model="form.logo_url" class="field-input" placeholder="https://...">
</div>
<div class="field full">
<label class="field-label">Favicon-URL</label>
<input type="url" v-model="form.favicon_url" class="field-input" placeholder="https://...">
</div>
</div>
</div>
</div>
<!-- Status Toggles -->
<div class="card">
<div class="card-head">
<div>
<h2>Status</h2>
<p class="card-subtitle">Wartungsmodus und Registrierung.</p>
</div>
</div>
<div class="card-body">
<div class="toggle-list">
<div class="toggle-row">
<div class="toggle-info">
<div class="toggle-label">
<i data-lucide="wrench"></i>
Wartungsmodus
</div>
<div class="toggle-desc">Nur Admins haben Zugang zur Seite.</div>
</div>
<button class="toggle-btn" :class="{ active: form.maintenance_mode }" @click="form.maintenance_mode = !form.maintenance_mode">
<span class="toggle-knob"></span>
</button>
</div>
<div class="toggle-row">
<div class="toggle-info">
<div class="toggle-label">
<i data-lucide="user-plus"></i>
Registrierung offen
</div>
<div class="toggle-desc">Neue Nutzer können sich registrieren.</div>
</div>
<button class="toggle-btn" :class="{ active: form.registration_open }" @click="form.registration_open = !form.registration_open">
<span class="toggle-knob"></span>
</button>
</div>
</div>
</div>
</div>
<!-- Limits -->
<div class="card">
<div class="card-head">
<div>
<h2>Limits & House Edge</h2>
<p class="card-subtitle">Einzahlungs-, Auszahlungs- und Wettlimits sowie den Hausvorteil.</p>
</div>
</div>
<div class="card-body">
<div class="form-grid">
<div class="field">
<label class="field-label">Min. Einzahlung (USD)</label>
<input type="number" step="0.01" min="0" v-model.number="form.min_deposit_usd" class="field-input">
</div>
<div class="field">
<label class="field-label">Max. Einzahlung (USD)</label>
<input type="number" step="0.01" min="0" v-model.number="form.max_deposit_usd" class="field-input">
</div>
<div class="field">
<label class="field-label">Min. Auszahlung (USD)</label>
<input type="number" step="0.01" min="0" v-model.number="form.min_withdrawal_usd" class="field-input">
</div>
<div class="field">
<label class="field-label">Max. Auszahlung (USD)</label>
<input type="number" step="0.01" min="0" v-model.number="form.max_withdrawal_usd" class="field-input">
</div>
<div class="field">
<label class="field-label">Max. Wette (USD)</label>
<input type="number" step="0.01" min="0" v-model.number="form.max_bet_usd" class="field-input">
</div>
<div class="field">
<label class="field-label">House Edge (%)</label>
<input type="number" step="0.01" min="0" max="100" v-model.number="form.house_edge_percent" class="field-input">
</div>
</div>
</div>
</div>
<!-- Contact & Legal -->
<div class="card">
<div class="card-head">
<div>
<h2>Kontakt & Rechtliches</h2>
<p class="card-subtitle">Support-E-Mail, Fußzeilentext und Links zu AGB/Datenschutz.</p>
</div>
</div>
<div class="card-body">
<div class="form-grid">
<div class="field">
<label class="field-label">Support-E-Mail</label>
<input type="email" v-model="form.support_email" class="field-input" placeholder="support@example.com">
</div>
<div class="field">
<label class="field-label">AGB-URL</label>
<input type="text" v-model="form.terms_url" class="field-input" placeholder="/terms">
</div>
<div class="field">
<label class="field-label">Datenschutz-URL</label>
<input type="text" v-model="form.privacy_url" class="field-input" placeholder="/privacy">
</div>
<div class="field full">
<label class="field-label">Fußzeilentext</label>
<textarea v-model="form.footer_text" rows="3" class="field-input" maxlength="1000" placeholder="© 2024 BetiX Casino. Alle Rechte vorbehalten."></textarea>
</div>
</div>
</div>
</div>
<div class="save-bar">
<button class="btn-primary" @click="submit" :disabled="form.processing">
<i data-lucide="save"></i>
{{ form.processing ? 'Wird gespeichert...' : 'Alle Einstellungen speichern' }}
</button>
</div>
</div>
</CasinoAdminLayout>
</template>
<style scoped>
.page-wrap { max-width: 900px; margin: 0 auto; display: flex; flex-direction: column; gap: 20px; }
.alert-success {
background: rgba(0, 200, 100, 0.1); border: 1px solid rgba(0, 200, 100, 0.3);
color: #00c864; padding: 12px 16px; border-radius: 10px;
display: flex; align-items: center; gap: 10px; font-weight: 600;
}
.alert-success i { width: 18px; height: 18px; flex-shrink: 0; }
.card { background: #0f0f10; border: 1px solid #18181b; border-radius: 14px; overflow: hidden; }
.card-head { padding: 20px 24px; border-bottom: 1px solid #18181b; }
.card-head h2 { font-size: 16px; font-weight: 700; color: #fff; margin: 0 0 2px; }
.card-subtitle { color: #71717a; font-size: 12px; margin: 0; }
.card-body { padding: 20px 24px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.field.full { grid-column: 1 / -1; }
.field-label { display: block; font-size: 11px; font-weight: 700; color: #71717a; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
.field-input {
width: 100%; background: #18181b; border: 1px solid #27272a; border-radius: 8px;
color: #e4e4e7; padding: 9px 12px; font-size: 13px; font-family: inherit;
transition: border-color 0.15s; box-sizing: border-box;
}
.field-input:focus { outline: none; border-color: #df006a; }
textarea.field-input { resize: vertical; }
.field-error { color: #ff3e3e; font-size: 11px; margin-top: 4px; }
/* Color picker */
.color-row { display: flex; gap: 8px; align-items: center; }
.color-picker { width: 44px; height: 38px; padding: 2px; border: 1px solid #27272a; border-radius: 8px; background: #18181b; cursor: pointer; }
.color-row .field-input { flex: 1; }
/* Toggles */
.toggle-list { display: flex; flex-direction: column; gap: 0; }
.toggle-row {
display: flex; align-items: center; justify-content: space-between; gap: 20px;
padding: 14px 0; border-bottom: 1px solid #18181b;
}
.toggle-row:last-child { border-bottom: none; }
.toggle-info { display: flex; flex-direction: column; gap: 2px; }
.toggle-label { display: flex; align-items: center; gap: 8px; font-weight: 600; color: #e4e4e7; font-size: 14px; }
.toggle-label i { width: 16px; height: 16px; color: #71717a; }
.toggle-desc { color: #71717a; font-size: 12px; padding-left: 24px; }
.toggle-btn {
width: 48px; height: 26px; border-radius: 99px; background: #27272a; border: none; cursor: pointer;
position: relative; transition: background 0.2s; flex-shrink: 0;
}
.toggle-btn.active { background: #df006a; }
.toggle-knob {
position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
background: #fff; border-radius: 50%; transition: transform 0.2s;
}
.toggle-btn.active .toggle-knob { transform: translateX(22px); }
/* Save bar */
.save-bar { display: flex; justify-content: flex-end; padding: 4px 0; }
.btn-primary {
display: inline-flex; align-items: center; gap: 8px;
background: #df006a; border: none; color: #fff; padding: 11px 22px;
border-radius: 8px; font-weight: 700; font-size: 13px; cursor: pointer; transition: all 0.15s;
}
.btn-primary:hover { background: #b8005a; }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary i { width: 16px; height: 16px; }
@media (max-width: 640px) {
.form-grid { grid-template-columns: 1fr; }
.field.full { grid-column: 1; }
}
</style>