clupilot/app/resources/views/livewire/pages/settings/index.blade.php

198 lines
11 KiB
PHP

<?php
use App\Models\Site;
use Livewire\Attributes\Layout;
use Livewire\Volt\Component;
new #[Layout('layouts.app')] class extends Component {
public string $workspaceName = '';
public string $workspaceSlug = '';
public string $description = '';
public string $region = 'eu-central-1';
public string $timezone = 'Europe/Berlin';
public function mount(): void
{
$ws = auth()->user()?->currentWorkspace;
if ($ws) {
$this->workspaceName = $ws->name;
$this->workspaceSlug = $ws->slug;
$this->region = $ws->region ?? 'eu-central-1';
}
}
public bool $emailNotifications = true;
public bool $slackNotifications = false;
public bool $weeklyDigest = true;
public string $section = 'workspace';
public function setSection(string $s): void
{
$this->section = $s;
}
public function with(): array
{
return [
'sitesUsed' => Site::count(),
'sitesQuota' => 100,
'monthlyCost' => 249,
];
}
}; ?>
<div>
<div class="clu-topbar">
<x-clu.burger />
<div>
<h1 class="clu-page-title">Einstellungen</h1>
<div class="clu-page-sub">workspace · benachrichtigungen · billing · api</div>
</div>
<div class="spacer"></div>
</div>
<div class="clu-settings-grid">
{{-- Left nav --}}
<nav class="clu-settings-nav">
<a href="#" wire:click.prevent="setSection('workspace')" class="@if($section==='workspace') active @endif">Workspace</a>
<a href="#" wire:click.prevent="setSection('notifications')" class="@if($section==='notifications') active @endif">Benachrichtigungen</a>
<a href="#" wire:click.prevent="setSection('billing')" class="@if($section==='billing') active @endif">Billing</a>
<a href="#" wire:click.prevent="setSection('api')" class="@if($section==='api') active @endif">API</a>
<a href="#" wire:click.prevent="setSection('danger')" class="@if($section==='danger') active @endif" style="color:var(--color-danger);">Danger Zone</a>
</nav>
{{-- Right content --}}
<div class="flex flex-col gap-[14px]">
@if ($section === 'workspace')
<div class="clu-card">
<div class="clu-card-head"><h3>Workspace</h3><span class="meta">Slug nicht änderbar nach Anlage.</span></div>
<div class="clu-card-body" style="display:flex;flex-direction:column;gap:14px;">
<div class="clu-field-row">
<div class="flex flex-col gap-[6px]">
<label class="text-[11.5px] text-(--color-muted) font-semibold">Name</label>
<div class="clu-input"><input wire:model="workspaceName" type="text" /></div>
</div>
<div class="flex flex-col gap-[6px]">
<label class="text-[11.5px] text-(--color-muted) font-semibold">Slug</label>
<div class="clu-input with-suffix">
<input value="{{ $workspaceSlug }}" type="text" disabled />
<span class="clu-input-suffix">.clupilot.io</span>
</div>
</div>
</div>
<div class="flex flex-col gap-[6px]">
<label class="text-[11.5px] text-(--color-muted) font-semibold">Beschreibung</label>
<div class="clu-input"><input wire:model="description" type="text" /></div>
</div>
<div class="clu-field-row">
<div class="flex flex-col gap-[6px]">
<label class="text-[11.5px] text-(--color-muted) font-semibold">Region</label>
<select wire:model="region" class="clu-input" style="appearance:auto;">
<option value="eu-central-1">eu-central-1 (Frankfurt)</option>
<option value="eu-west-1">eu-west-1 (Ireland)</option>
<option value="us-east-1">us-east-1 (Virginia)</option>
</select>
</div>
<div class="flex flex-col gap-[6px]">
<label class="text-[11.5px] text-(--color-muted) font-semibold">Zeitzone</label>
<select wire:model="timezone" class="clu-input" style="appearance:auto;">
<option value="Europe/Berlin">Europe/Berlin</option>
<option value="Europe/Vienna">Europe/Vienna</option>
<option value="UTC">UTC</option>
</select>
</div>
</div>
<div class="flex gap-[8px] justify-end pt-[8px] border-t border-(--color-hairline)">
<button class="clu-ghost-btn" type="button">Verwerfen</button>
<button class="clu-btn-primary" style="height:36px;padding:0 16px;" type="button">Speichern</button>
</div>
</div>
</div>
@endif
@if ($section === 'notifications')
<div class="clu-card">
<div class="clu-card-head"><h3>Benachrichtigungen</h3></div>
<div class="clu-card-body" style="display:flex;flex-direction:column;gap:14px;">
<label class="clu-checkbox" style="justify-content:space-between;width:100%;">
<span>E-Mail Benachrichtigungen</span>
<input type="checkbox" wire:model.live="emailNotifications" />
<span class="box"><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5"><path d="M5 12l5 5L20 7"/></svg></span>
</label>
<label class="clu-checkbox" style="justify-content:space-between;width:100%;">
<span>Slack Webhooks</span>
<input type="checkbox" wire:model.live="slackNotifications" />
<span class="box"><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5"><path d="M5 12l5 5L20 7"/></svg></span>
</label>
<label class="clu-checkbox" style="justify-content:space-between;width:100%;">
<span>Wöchentlicher Digest</span>
<input type="checkbox" wire:model.live="weeklyDigest" />
<span class="box"><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5"><path d="M5 12l5 5L20 7"/></svg></span>
</label>
</div>
</div>
@endif
@if ($section === 'billing')
<div class="clu-card">
<div class="clu-card-head"><h3>Billing</h3><span class="meta">Plan + Quota</span></div>
<div class="clu-card-body" style="display:flex;flex-direction:column;gap:14px;">
<div class="flex items-center justify-between">
<div>
<div class="font-semibold">PRO Plan</div>
<div class="text-[12px] text-(--color-muted)">monatlich abgerechnet</div>
</div>
<span class="clu-pill accent">€{{ $monthlyCost }}/mo</span>
</div>
<div>
<div class="clu-stat-label">Sites Quota</div>
<div class="clu-plan-meter mt-2"><span style="width:{{ min(100, (int)round($sitesUsed/$sitesQuota*100)) }}%"></span></div>
<div class="clu-plan-stats"><span>{{ $sitesUsed }} / {{ $sitesQuota }}</span><span>{{ (int)round($sitesUsed/$sitesQuota*100) }}%</span></div>
</div>
<div class="flex justify-between items-center pt-[14px] border-t border-(--color-hairline)">
<span class="text-[12.5px] text-(--color-muted)">Zahlungsmethode: Visa **** 4242</span>
<button class="clu-ghost-btn" type="button">Ändern</button>
</div>
</div>
</div>
@endif
@if ($section === 'api')
<div class="clu-card">
<div class="clu-card-head"><h3>API Tokens</h3></div>
<div class="clu-card-body" style="display:flex;flex-direction:column;gap:12px;">
<div class="font-mono text-[12px] p-[12px] rounded-[9px]" style="background:rgba(255,255,255,0.5);border:1px solid var(--color-hairline);">
clu_pat_•••••••••••••••••••••••••••••• <button type="button" class="ml-2 text-(--color-accent) text-[11px]">kopieren</button>
</div>
<button class="clu-btn-primary" style="height:36px;padding:0 16px;align-self:flex-start;" type="button">Neuen Token erstellen</button>
</div>
</div>
@endif
@if ($section === 'danger')
<div class="clu-card clu-danger">
<div class="clu-card-head"><h3 style="color:var(--color-danger);">Danger Zone</h3></div>
<div class="clu-card-body" style="display:flex;flex-direction:column;gap:12px;">
<p class="text-[13px]">Workspace löschen entfernt alle Sites, Server-Verbindungen und Backups unwiderruflich.</p>
<button class="clu-ghost-btn"
style="color:var(--color-danger);border-color:rgba(219,59,59,0.3);align-self:flex-start;"
type="button"
wire:click="$dispatch('openModal', {
component: 'modals.confirm-delete',
arguments: {
title: 'Workspace wirklich löschen?',
message: 'Alle Sites, Server-Verbindungen, Backups und Logs werden unwiderruflich entfernt. Diese Aktion kann nicht rückgängig gemacht werden.',
confirmLabel: 'Workspace löschen',
confirmEvent: 'workspace-delete-confirmed'
}
})">
Workspace löschen…
</button>
</div>
</div>
@endif
</div>
</div>
</div>