function view_dns_show(array $app, array $data): string { $domain = $data['domain']; $zone = $data['zone'] ?? null; $recordRows = ''; foreach (($zone['records'] ?? []) as $record) { $recordRows .= ' ' . app_h($record['rr_name'] ?? '') . ' ' . app_h($record['rr_type'] ?? '') . ' ' . app_h($record['rr_content'] ?? '') . ' ' . app_h((string)($record['rr_ttl'] ?? '')) . '
'; } if ($recordRows === '') { $recordRows = '
Keine DNS-Records vorhanden.
'; } return app_layout($app, [ 'title' => 'DNS', 'content' => '

DNS für ' . app_h($domain['domain_name']) . '

Zone synchronisieren und Records verwalten.

Zoneninfo

Origin
' . app_h($zone['soa_origin'] ?? (string)$domain['domain_name']) . '
Serial
' . app_h($zone['provider_serial'] ?? '') . '
Quelle
' . app_h($zone['source'] ?? '') . '
Letzter Sync
' . app_h($zone['last_synced_at'] ?? '') . '

Record anlegen

DNS-Records

' . $recordRows . '
Name Typ Content TTL
', ]); } function view_price_list_index(array $app, array $data): string { $prices = $data['prices'] ?? []; $resellers = $data['resellers'] ?? []; $resellerId = (int)($data['reseller_id'] ?? 0); $resellerOptions = ''; foreach ($resellers as $reseller) { $selected = $resellerId === (int)$reseller['id'] ? ' selected' : ''; $resellerOptions .= ''; } $rows = ''; foreach ($prices as $price) { $key = ($price['tld'] ?? '') . '|' . ($price['action_code'] ?? 'create'); $rows .= ' ' . app_h($price['tld'] ?? '') . ' ' . app_h($price['action_code'] ?? '') . ' '; } if ($rows === '') { $rows = '
Noch keine Preise vorhanden.
'; } return app_layout($app, [ 'title' => 'Preisliste', 'content' => '

Preisliste

Providerpreise und Reseller-Margen pro TLD verwalten.

' . ((($app['user']['role'] ?? '') === 'admin') ? '
' : '') . '
' . $rows . '
TLD Aktion Provider netto Markup Typ Markup Wert Reseller netto
', ]); } function view_billing_index(array $app, array $data): string { $resellers = $data['resellers'] ?? []; $runs = $data['runs'] ?? []; $selectedResellerId = (int)($data['selected_reseller_id'] ?? 0); $selectedYear = (int)($data['selected_year'] ?? date('Y')); $selectedMonth = (int)($data['selected_month'] ?? date('n')); $resellerOptions = ''; foreach ($resellers as $reseller) { $selected = $selectedResellerId === (int)$reseller['id'] ? ' selected' : ''; $resellerOptions .= ''; } $runRows = ''; foreach ($runs as $run) { $runRows .= ' ' . app_h($run['reseller_name']) . ' ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . ' ' . app_currency((float)$run['total_net']) . ' ' . app_currency((float)$run['total_gross']) . ' ' . app_h($run['status']) . ' Öffnen '; } if ($runRows === '') { $runRows = '
Keine Abrechnungsläufe gefunden.
'; } return app_layout($app, [ 'title' => 'Buchhaltung', 'content' => '

Buchhaltung

Abrechnungsläufe je Reseller verwalten.

Filtern

Abrechnungslauf erstellen

Abrechnungsläufe

' . $runRows . '
Reseller Monat Netto Brutto Status
', ]); } function view_billing_show(array $app, array $data): string { $run = $data['run']; $customers = $data['customers'] ?? []; $rows = ''; foreach ($customers as $customer) { $rows .= ' ' . app_h($customer['customer_name'] ?? 'Ohne Kunde') . ' ' . app_h((string)($customer['domain_count'] ?? 0)) . ' ' . app_currency((float)$customer['total_net']) . ' ' . app_currency((float)$customer['total_gross']) . ' Details '; } if ($rows === '') { $rows = '
Keine Kundenpositionen vorhanden.
'; } return app_layout($app, [ 'title' => 'Abrechnung', 'content' => '

' . app_h($run['reseller_name']) . '

Abrechnung ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . '

' . dashboard_stat_card('Netto', app_currency((float)$run['total_net']), 'Summe netto', icon_price()) . ' ' . dashboard_stat_card('MwSt', app_currency((float)$run['total_vat']), 'Steuer', icon_receipt()) . ' ' . dashboard_stat_card('Brutto', app_currency((float)$run['total_gross']), 'Summe brutto', icon_receipt()) . ' ' . dashboard_stat_card('Status', app_h($run['status']), 'Laufstatus', icon_status()) . '

Metadaten

Kundenpositionen

' . $rows . '
Kunde Domains Netto Brutto
', ]); } function view_billing_customer_show(array $app, array $data): string { $run = $data['run']; $positions = $data['positions'] ?? []; $customerName = $positions[0]['customer_name'] ?? 'Kunde'; $rows = ''; foreach ($positions as $position) { $rows .= ' ' . app_h($position['domain_name'] ?? '') . ' ' . app_h($position['line_type'] ?? '') . ' ' . app_h((string)($position['quantity'] ?? 0)) . ' ' . app_currency((float)($position['line_net'] ?? 0)) . ' ' . app_currency((float)($position['line_gross'] ?? 0)) . ' '; } if ($rows === '') { $rows = '
Keine Detailpositionen vorhanden.
'; } return app_layout($app, [ 'title' => 'Abrechnungsdetails', 'content' => '

' . app_h($customerName) . '

Details zur Abrechnung ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . '

Detailpositionen

' . $rows . '
Domain Typ Menge Netto Brutto
', ]); } function view_reseller_billing_index(array $app, array $data): string { $runs = $data['runs'] ?? []; $domains = $data['domains'] ?? []; $runRows = ''; foreach ($runs as $run) { $runRows .= ' ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . ' ' . app_currency((float)$run['total_net']) . ' ' . app_currency((float)$run['total_gross']) . ' ' . app_h($run['status']) . ' Öffnen '; } if ($runRows === '') { $runRows = '
Keine Abrechnungen vorhanden.
'; } $domainRows = ''; foreach ($domains as $domain) { $domainRows .= ' ' . app_h($domain['domain_name'] ?? '') . ' ' . app_h($domain['customer_name'] ?? '') . ' ' . app_currency((float)($domain['reseller_price_net'] ?? 0)) . ' ' . app_h($domain['local_status'] ?? '') . ' '; } if ($domainRows === '') { $domainRows = '
Keine Domains vorhanden.
'; } return app_layout($app, [ 'title' => 'Buchhaltung', 'content' => '

Buchhaltung

Deine Abrechnungen und aktueller Domainbestand.

Abrechnungen

' . $runRows . '
Monat Netto Brutto Status

Aktueller Bestand

' . $domainRows . '
Domain Kunde Preis netto Status
', ]); } function view_reseller_billing_show(array $app, array $data): string { return view_billing_show($app, $data); } function view_reseller_billing_customer_show(array $app, array $data): string { return view_billing_customer_show($app, $data); } function view_account_index(array $app, array $data = []): string { $user = $app['user']; $error = $data['error'] ?? ''; return app_layout($app, [ 'title' => 'Konto', 'content' => '

Konto

Passwort und Basisdaten.

Profil

Name
' . app_h($user['display_name'] ?? '') . '
E-Mail
' . app_h($user['email'] ?? '') . '
Rolle
' . app_h(role_label($app, $user['role'] ?? '')) . '

Passwort ändern

' . ($error ? '
' . app_h($error) . '
' : '') . '
', ]); } /* -------------------- Helpers -------------------- */ function dashboard_stat_card(string $label, string $value, string $meta, string $icon, bool $raw = false, string $overrideValue = ''): string { $valueHtml = $raw ? $overrideValue : app_h($value); return '
' . app_h($label) . '
' . $valueHtml . '
' . $icon . '
' . app_h($meta) . '
'; } function dashboard_customers_card(array $app, array $customers): string { $rows = ''; $isAdmin = ($app['user']['role'] ?? '') === 'admin'; foreach (array_slice($customers, 0, 6) as $customer) { $rows .= ' ' . app_h($customer['name'] ?? '') . ' ' . app_h($customer['email'] ?? '') . ' ' . ($isAdmin ? '' . app_h($customer['reseller_name'] ?? '') . '' : '') . ' '; } if ($rows === '') { $rows = '
Keine Kunden vorhanden.
'; } return '

Letzte Kunden

' . ($isAdmin ? '' : '') . '' . $rows . '
KundeReseller
'; } function dashboard_domains_card(array $app, array $domains): string { $rows = ''; $isAdmin = ($app['user']['role'] ?? '') === 'admin'; foreach (array_slice($domains, 0, 6) as $domain) { $rows .= ' ' . app_h($domain['domain_name'] ?? '') . ' ' . app_h($domain['provider_status'] ?? '') . ' ' . app_h($domain['customer_name'] ?? '') . ' ' . ($isAdmin ? '' . app_h($domain['reseller_name'] ?? '') . '' : '') . ' '; } if ($rows === '') { $rows = '
Keine Domains vorhanden.
'; } return '

Letzte Domains

' . ($isAdmin ? '' : '') . '' . $rows . '
DomainKundeReseller
'; } function billing_status_options(string $current): string { $items = ['open', 'reviewed', 'exported', 'closed']; $html = ''; foreach ($items as $item) { $selected = $current === $item ? ' selected' : ''; $html .= ''; } return $html; } function role_label(array $app, string $role): string { return $app['config']['roles'][$role] ?? ucfirst($role); } function select_options_assoc(array $items, string $current): string { $html = ''; foreach ($items as $value => $label) { $html .= ''; } return $html; } function select_options_simple(array $items, string $current): string { $assoc = []; foreach ($items as $item) { $assoc[(string)$item] = (string)$item; } return select_options_assoc($assoc, $current); } /* -------------------- Icons -------------------- */ function icon_wrap(string $path): string { return ''; } function icon_home(): string { return icon_wrap(''); } function icon_users(): string { return icon_wrap(''); } function icon_user_card(): string { return icon_wrap(''); } function icon_settings(): string { return icon_wrap(''); } function icon_status(): string { return icon_wrap(''); } function icon_search(): string { return icon_wrap(''); } function icon_menu(): string { return icon_wrap(''); } function icon_price(): string { return icon_wrap(''); } function icon_receipt(): string { return icon_wrap(''); } function icon_domain(): string { return icon_wrap(''); } function icon_contact(): string { return icon_wrap(''); }
Warning: http_response_code(): Cannot set response code - headers already sent (output started at /var/www/vhosts/domains.myhostpanel.de/httpdocs/views.php:1) in /var/www/vhosts/domains.myhostpanel.de/httpdocs/app.php on line 301

Fatal error: Uncaught Error: Call to undefined function app_layout() in /var/www/vhosts/domains.myhostpanel.de/httpdocs/app.php:305 Stack trace: #0 /var/www/vhosts/domains.myhostpanel.de/httpdocs/app.php(120): app_error_page() #1 /var/www/vhosts/domains.myhostpanel.de/httpdocs/index.php(17): app_handle_request() #2 {main} thrown in /var/www/vhosts/domains.myhostpanel.de/httpdocs/app.php on line 305