Initialer Laravel Commit für BetiX
This commit is contained in:
281
resources/js/pages/Admin/SiteSettings.vue
Normal file
281
resources/js/pages/Admin/SiteSettings.vue
Normal 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>
|
||||
Reference in New Issue
Block a user