Initial import: Carteasy Shop (Dev-Stand)

This commit is contained in:
Thomas Bartelt
2026-04-20 01:03:43 +02:00
commit d504f8a05d
3845 changed files with 761050 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

@@ -0,0 +1,10 @@
{* Form Actions: Save & Cancel *}
<div class="admin2000-form-actions">
<button type="submit" class="admin2000-btn admin2000-btn-primary">
💾 Speichern
</button>
<a href="./index.php?admin_modul=admin2000&section=stammdaten&page=kunden" class="admin2000-btn admin2000-btn-secondary">
Abbrechen
</a>
</div>
@@ -0,0 +1,101 @@
{* Section: Adressen *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Adressen</div>
{if $customer_addresses}
<div class="admin2000-address-grid">
{foreach from=$customer_addresses item=address}
<div class="admin2000-address-card">
<div class="admin2000-address-card-header">
Adresse
{if $address.id == $customer_data.default_address}
<span class="admin2000-badge-primary">Standard</span>
{/if}
</div>
<div class="admin2000-address-card-body">
{* Honorific (0=Herr, 1=Frau, 2=Firma) *}
{if $address.honorific == 0}
<div class="admin2000-address-honorific">Herr</div>
{elseif $address.honorific == 1}
<div class="admin2000-address-honorific">Frau</div>
{elseif $address.honorific == 2}
<div class="admin2000-address-honorific">Firma</div>
{/if}
{if $address.company != ''}
<div class="admin2000-address-company">{$address.company|escape:'html'}</div>
{/if}
<div class="admin2000-address-name">
{$address.firstname|escape:'html'} {$address.surname|escape:'html'}
</div>
<div class="admin2000-address-street">
{$address.street|escape:'html'} {$address.house_number|escape:'html'}
</div>
<div class="admin2000-address-city">
{$address.zip_code|escape:'html'} {$address.city|escape:'html'}
</div>
{if $address.country_name}
<div class="admin2000-address-country">{$address.country_name|escape:'html'}</div>
{/if}
</div>
<div class="admin2000-address-card-actions">
{if $address.id != $customer_data.default_address}
<button type="button" class="admin2000-btn-small admin2000-btn-secondary set-standard-address" data-address-id="{$address.id}">
Standard setzen
</button>
{/if}
<a href="./index.php?admin_modul=admin_customer_actions&action=edit_customer_address&address_id={$address.id}" class="admin2000-btn-small admin2000-btn-primary">
Bearbeiten
</a>
<button type="button" class="admin2000-btn-small admin2000-btn-danger delete-address" data-address-id="{$address.id}">
Löschen
</button>
</div>
</div>
{/foreach}
{* Add New Address Card *}
<div class="admin2000-address-card admin2000-address-card-add">
<a href="./index.php?admin_modul=admin_customer_actions&action=new_customer_address&customer_id={$customer_id}" class="admin2000-address-add-link">
<div class="admin2000-address-add-icon">+</div>
<div class="admin2000-address-add-text">Neue Adresse hinzufügen</div>
</a>
</div>
</div>
{else}
<div class="admin2000-empty-state">
<p>Keine Adressen vorhanden</p>
<a href="./index.php?admin_modul=admin_customer_actions&action=new_customer_address&customer_id={$customer_id}" class="admin2000-btn admin2000-btn-primary">
Erste Adresse hinzufügen
</a>
</div>
{/if}
</div>
<script>
$(document).ready(function() {
// Delete address confirmation
$('.delete-address').click(function() {
var addressId = $(this).data('address-id');
if (confirm('Adresse wirklich löschen?')) {
// TODO: AJAX delete call
window.location.href = './index.php?admin_modul=admin_customer_actions&action=delete_customer_address&address_id=' + addressId + '&customer_id={$customer_id}';
}
});
// Set standard address
$('.set-standard-address').click(function() {
var addressId = $(this).data('address-id');
// TODO: AJAX call to set standard
window.location.href = './index.php?admin_modul=admin_customer_actions&action=set_standard_address&address_id=' + addressId + '&customer_id={$customer_id}';
});
});
</script>
@@ -0,0 +1,36 @@
{* Section: Firmendaten *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Firmendaten</div>
{* Row 1: Firma (full width) *}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Firma</label>
<input type="text" class="admin2000-form-input" name="customer_field[company]" value="{$customer_data.company|escape:'html'}" autocomplete="off">
</div>
{* Row 2: Steuernummer + Ust-ID *}
<div class="admin2000-form-row admin2000-form-row-2">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Steuernummer</label>
<input type="text" class="admin2000-form-input" name="customer_field[tax_number]" value="{$customer_data.tax_number|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Ust-ID</label>
<input type="text" class="admin2000-form-input" name="customer_field[tax_id]" value="{$customer_data.tax_id|escape:'html'}" autocomplete="off">
</div>
</div>
{* Row 3: EU-Geschäfte *}
{if isset($select_values.eu_business)}
<div class="admin2000-form-group">
<label class="admin2000-form-label">EU-Geschäfte</label>
<select class="admin2000-form-select" name="customer_field[eu_business]">
{foreach from=$select_values.eu_business item=label key=value}
<option value="{$value}" {if $customer_data.eu_business == $value}selected{/if}>{$label}</option>
{/foreach}
</select>
</div>
{/if}
</div>
@@ -0,0 +1,34 @@
{* Header: Breadcrumb + Titel + Messages *}
<div class="admin2000-editor-header">
<div class="admin2000-breadcrumb">
<a href="./index.php?admin_modul=admin2000&section=stammdaten&page=kunden">Kunden</a>
<span class="admin2000-breadcrumb-separator">›</span>
<span class="admin2000-breadcrumb-current">
{if $customer_data.company}
{$customer_data.company}
{else}
{$customer_data.firstname} {$customer_data.surname}
{/if}
</span>
</div>
<h1 class="admin2000-editor-title">
Kunde bearbeiten
<span class="admin2000-editor-id">#{$customer_id}</span>
</h1>
</div>
{* Success Message *}
{if $save_success}
<div class="admin2000-success-box">
<strong>✅ Erfolgreich gespeichert!</strong> Die Kundendaten wurden aktualisiert.
</div>
{/if}
{* Error Message *}
{if isset($error)}
<div class="admin2000-error-box">
<strong>⚠️ Fehler:</strong> {$error}
</div>
{/if}
@@ -0,0 +1,60 @@
{* Section: Kontaktdaten *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Kontaktdaten</div>
{* Row 1: Anrede + Vorname + Nachname *}
<div class="admin2000-form-row admin2000-form-row-3">
{if isset($select_values.honorific)}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Anrede</label>
<select class="admin2000-form-select" name="customer_field[honorific]" autocomplete="off">
{foreach from=$select_values.honorific item=label key=value}
<option value="{$value}" {if $customer_data.honorific == $value}selected{/if}>{$label}</option>
{/foreach}
</select>
</div>
{/if}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Vorname *</label>
<input type="text" class="admin2000-form-input" name="customer_field[firstname]" value="{$customer_data.firstname|escape:'html'}" autocomplete="off" required>
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Nachname *</label>
<input type="text" class="admin2000-form-input" name="customer_field[surname]" value="{$customer_data.surname|escape:'html'}" autocomplete="off" required>
</div>
</div>
{* Row 2: Telefon + Handy + Fax *}
<div class="admin2000-form-row admin2000-form-row-3">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Telefon</label>
<input type="text" class="admin2000-form-input" name="customer_field[phone]" value="{$customer_data.phone|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Handy</label>
<input type="text" class="admin2000-form-input" name="customer_field[mobile]" value="{$customer_data.mobile|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Fax</label>
<input type="text" class="admin2000-form-input" name="customer_field[fax]" value="{$customer_data.fax|escape:'html'}" autocomplete="off">
</div>
</div>
{* Row 3: E-Mail + Homepage (60/40 Split) *}
<div class="admin2000-form-row admin2000-form-row-mixed-3-2">
<div class="admin2000-form-group">
<label class="admin2000-form-label">E-Mail *</label>
<input type="email" class="admin2000-form-input" name="customer_field[email]" value="{$customer_data.email|escape:'html'}" autocomplete="off" required>
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Homepage</label>
<input type="url" class="admin2000-form-input" name="customer_field[website]" value="{$customer_data.website|escape:'html'}" autocomplete="off">
</div>
</div>
</div>
@@ -0,0 +1,44 @@
{* Section: Passwort *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Passwort</div>
{* Row 1: Password Action Dropdown *}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Aktion {if $customer_data.pass == ''}<span style="color:#999;font-size:12px;font-weight:normal;"> (Kunde hat kein Passwort)</span>{/if}</label>
<select id="password_action" class="admin2000-form-select" name="customer_password_action">
<option value="0">-</option>
<option value="1">Neues Passwort mit Benachrichtigung</option>
<option value="2">Neues Passwort manuell vergeben</option>
</select>
</div>
{* Row 2: Manual Password Fields (hidden by default) *}
<div id="show_passwords" style="display:none;">
<div class="admin2000-form-row admin2000-form-row-2">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Passwort</label>
<input type="password" class="admin2000-form-input" name="customer_field[pass1]" value="" autocomplete="new-password">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Passwort wiederholen</label>
<input type="password" class="admin2000-form-input" name="customer_field[pass2]" value="" autocomplete="new-password">
</div>
</div>
<div id="password_match_spring"></div>
</div>
<script>
$(document).ready(function() {
// Show/hide password fields based on action
$('#password_action').change(function() {
if ($(this).val() == '2') {
$('#show_passwords').slideDown();
} else {
$('#show_passwords').slideUp();
}
});
});
</script>
</div>
@@ -0,0 +1,58 @@
{* Section: Rechnungen / Bestellungen *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Bestellungen / Rechnungen</div>
{if $orders}
<div class="admin2000-orders-table-wrapper">
<table class="admin2000-table admin2000-orders-table">
<thead>
<tr>
<th>Bestellnummer</th>
<th>Bestelldatum</th>
<th>Bezahlstatus</th>
<th>Bestellwert</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{foreach from=$orders item=order}
<tr>
<td>
<strong>
{$order.order_number|escape:'html'}
{if $order.order_revision}-{$order.order_revision|escape:'html'}{/if}
</strong>
</td>
<td>{$order.order_date|escape:'html'}</td>
<td>
<span class="admin2000-badge-status admin2000-badge-{$order.invoice_status_text|lower|replace:' ':'-'}">
{$order.invoice_status_text|escape:'html'}
</span>
</td>
<td>
<strong>{$order.order_total|escape:'html'}</strong>
</td>
<td>
<a href="./index.php?admin_modul=admin_order_editor&action=edit&id={$order.id}" class="admin2000-btn-small admin2000-btn-primary">
Bearbeiten
</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<div class="admin2000-orders-summary">
<strong>Gesamt:</strong> {$orders|@count} Bestellung{if $orders|@count != 1}en{/if}
</div>
{else}
<div class="admin2000-empty-state">
<p>Keine Bestellungen vorhanden</p>
<small style="color: #6c757d;">Dieser Kunde hat noch keine Bestellungen aufgegeben.</small>
</div>
{/if}
</div>
@@ -0,0 +1,56 @@
{* Section: Stammdaten *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Stammdaten</div>
{* Row 1: Kundennummer + Freigabe *}
<div class="admin2000-form-row admin2000-form-row-2">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Kundennummer</label>
<input type="text" class="admin2000-form-input" name="customer_field[number]" value="{$customer_data.number|escape:'html'}">
</div>
{if isset($select_values.locked)}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Freigabe</label>
<select class="admin2000-form-select" name="customer_field[locked]">
{foreach from=$select_values.locked item=label key=value}
<option value="{$value}" {if $customer_data.locked == $value}selected{/if}>{$label}</option>
{/foreach}
</select>
</div>
{/if}
</div>
{* Row 2: Kundengruppe + Rolle *}
<div class="admin2000-form-row admin2000-form-row-2">
{if isset($select_values.group_id)}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Kundengruppe</label>
<select class="admin2000-form-select" name="customer_field[group_id]">
{foreach from=$select_values.group_id item=label key=value}
<option value="{$value}" {if $customer_data.group_id == $value}selected{/if}>{$label}</option>
{/foreach}
</select>
</div>
{/if}
{if isset($select_values.admin_role_id)}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Rolle (Admin-Berechtigung)</label>
<select class="admin2000-form-select" name="customer_field[admin_role_id]">
<option value="">Keine Admin-Rechte</option>
{foreach from=$select_values.admin_role_id item=label key=value}
<option value="{$value}" {if $customer_data.admin_role_id == $value}selected{/if}>{$label}</option>
{/foreach}
</select>
</div>
{/if}
</div>
{* Row 3: Geburtsdatum (single field) *}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Geburtsdatum</label>
<input type="date" class="admin2000-form-input" name="customer_field[burth_date]" value="{if $customer_data.burth_date != '0000-00-00' && $customer_data.burth_date != ''}{$customer_data.burth_date|escape:'html'}{/if}">
</div>
</div>
@@ -0,0 +1,14 @@
{* Section: Steuer - Note: tax_number, tax_id, eu_business sind jetzt in firmendaten.tpl *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Steuereinstellungen</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Steuer anzeigen</label>
<select class="admin2000-form-select" name="customer_field[show_tax]">
<option value="1" {if $customer_data.show_tax == 1}selected{/if}>Ja (Preise inkl. MwSt.)</option>
<option value="0" {if $customer_data.show_tax == 0}selected{/if}>Nein (Nettopreise)</option>
</select>
<small style="display:block;margin-top:5px;color:#6c757d;">Beeinflusst die Preisanzeige für diesen Kunden</small>
</div>
</div>
@@ -0,0 +1,159 @@
{* Section: Zusatzfelder - Bankverbindung, Zahlungsmethoden, Weitere Daten *}
{* ============================================
SECTION 1: Bankverbindung
============================================ *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Bankverbindung</div>
{* Row 1: Kontoinhaber + Kontonummer + Geldinstitut *}
<div class="admin2000-form-row admin2000-form-row-3">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Kontoinhaber</label>
<input type="text" class="admin2000-form-input" name="customer_field[account_holder]" value="{$customer_data.account_holder|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Kontonummer</label>
<input type="text" class="admin2000-form-input" name="customer_field[account_number]" value="{$customer_data.account_number|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Geldinstitut</label>
<input type="text" class="admin2000-form-input" name="customer_field[bank]" value="{$customer_data.bank|escape:'html'}" autocomplete="off">
</div>
</div>
{* Row 2: BLZ + IBAN + SWIFT/BIC *}
<div class="admin2000-form-row admin2000-form-row-3">
<div class="admin2000-form-group">
<label class="admin2000-form-label">BLZ</label>
<input type="text" class="admin2000-form-input" name="customer_field[bank_number]" value="{$customer_data.bank_number|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">IBAN</label>
<input type="text" class="admin2000-form-input" name="customer_field[iban]" value="{$customer_data.iban|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">SWIFT/BIC</label>
<input type="text" class="admin2000-form-input" name="customer_field[swift_bic]" value="{$customer_data.swift_bic|escape:'html'}" autocomplete="off">
</div>
</div>
</div>
{* ============================================
SECTION 2: Zahlungsmethoden
============================================ *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Zahlungsmethoden</div>
<p style="margin-bottom: 20px; color: #6c757d; font-size: 14px;">
Hinweis: Damit der Kunde die Zahlungsart 'Bankeinzug bzw. Rechnung' wählen kann, muss für die Kundengruppe und die Lieferzone auch diese freigeschaltet sein!
</p>
{* Row 1: Bankeinzug + Rechnung + Skonto *}
<div class="admin2000-form-row admin2000-form-row-3">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Bankeinzug</label>
<select class="admin2000-form-select" name="customer_field[direct_debit_active]">
<option value="1" {if $customer_data.direct_debit_active == 1}selected{/if}>freigegeben</option>
<option value="0" {if $customer_data.direct_debit_active == 0}selected{/if}>gesperrt</option>
</select>
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Rechnung</label>
<select class="admin2000-form-select" name="customer_field[rechnung_active]">
<option value="1" {if $customer_data.rechnung_active == 1}selected{/if}>freigegeben</option>
<option value="0" {if $customer_data.rechnung_active == 0}selected{/if}>gesperrt</option>
</select>
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Skonto %</label>
<select class="admin2000-form-select" name="customer_field[skonto]">
<option value="0" {if $customer_data.skonto == 0}selected{/if}>-</option>
<option value="1" {if $customer_data.skonto == 1}selected{/if}>1</option>
<option value="2" {if $customer_data.skonto == 2}selected{/if}>2</option>
<option value="3" {if $customer_data.skonto == 3}selected{/if}>3</option>
<option value="4" {if $customer_data.skonto == 4}selected{/if}>4</option>
<option value="5" {if $customer_data.skonto == 5}selected{/if}>5</option>
<option value="6" {if $customer_data.skonto == 6}selected{/if}>6</option>
<option value="7" {if $customer_data.skonto == 7}selected{/if}>7</option>
<option value="8" {if $customer_data.skonto == 8}selected{/if}>8</option>
<option value="9" {if $customer_data.skonto == 9}selected{/if}>9</option>
<option value="10" {if $customer_data.skonto == 10}selected{/if}>10</option>
</select>
</div>
</div>
</div>
{* ============================================
SECTION 3: Weitere Kundendaten
============================================ *}
<div class="admin2000-form-section">
<div class="admin2000-form-section-title">Weitere Kundendaten</div>
{* Row 1: Freitextfeld 1-3 *}
<div class="admin2000-form-row admin2000-form-row-3">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Freitextfeld 1</label>
<input type="text" class="admin2000-form-input" name="customer_field[freetextfield1]" value="{$customer_data.freetextfield1|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Freitextfeld 2</label>
<input type="text" class="admin2000-form-input" name="customer_field[freetextfield2]" value="{$customer_data.freetextfield2|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Freitextfeld 3</label>
<input type="text" class="admin2000-form-input" name="customer_field[freetextfield3]" value="{$customer_data.freetextfield3|escape:'html'}" autocomplete="off">
</div>
</div>
{* Row 2: Freitextfeld 4-6 *}
<div class="admin2000-form-row admin2000-form-row-3">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Freitextfeld 4</label>
<input type="text" class="admin2000-form-input" name="customer_field[freetextfield4]" value="{$customer_data.freetextfield4|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Freitextfeld 5</label>
<input type="text" class="admin2000-form-input" name="customer_field[freetextfield5]" value="{$customer_data.freetextfield5|escape:'html'}" autocomplete="off">
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Freitextfeld 6</label>
<input type="text" class="admin2000-form-input" name="customer_field[freetextfield6]" value="{$customer_data.freetextfield6|escape:'html'}" autocomplete="off">
</div>
</div>
{* Row 3: Artikel Export + Newsletter *}
<div class="admin2000-form-row admin2000-form-row-2">
<div class="admin2000-form-group">
<label class="admin2000-form-label">Artikel Export</label>
<select class="admin2000-form-select" name="customer_field[has_item_export]">
<option value="0" {if $customer_data.has_item_export == 0}selected{/if}>Nein</option>
<option value="1" {if $customer_data.has_item_export == 1}selected{/if}>Ja</option>
</select>
</div>
<div class="admin2000-form-group">
<label class="admin2000-form-label">Newsletter</label>
<select class="admin2000-form-select" name="customer_field[newsletter_sub]">
<option value="0" {if $customer_data.newsletter_sub == 0}selected{/if}>Nein</option>
<option value="1" {if $customer_data.newsletter_sub == 1}selected{/if}>Ja</option>
</select>
</div>
</div>
{* Row 4: Notiz (full width) *}
<div class="admin2000-form-group">
<label class="admin2000-form-label">Notiz</label>
<textarea class="admin2000-form-textarea" name="customer_field[info]" rows="6">{$customer_data.info|escape:'html'}</textarea>
</div>
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

@@ -0,0 +1,262 @@
{* ============================================
ADMIN2000 - Kunden-Verwaltung
Moderne Darstellung der Kundenliste
============================================ *}
<div class="admin2000-card">
<div class="admin2000-list-header">
<h2 class="admin2000-card-title">👥 {$table_data.title}</h2>
{* Toolbar *}
<div class="admin2000-toolbar">
{* Search *}
{if isset($table_data.toolbar.search) && $table_data.toolbar.search}
<form class="admin2000-search-form">
<input type="text" class="admin2000-search-input admin2000-search" placeholder="Kunden suchen..." />
</form>
{/if}
{* New Customer Button *}
{if isset($table_data.toolbar.new) && $table_data.toolbar.new}
<a href="{$table_data.toolbar.new}" class="admin2000-btn admin2000-btn-success">
+ Neuer Kunde
</a>
{/if}
</div>
</div>
{* Filter Section *}
{if isset($table_data.list_filter) && $table_data.list_filter}
<div class="admin2000-filter-section">
<strong class="admin2000-filter-title">🔍 Filter:</strong>
<div class="admin2000-filter-grid">
{foreach from=$table_data.list_filter item=filter}
<div class="admin2000-filter-item">
<label class="admin2000-filter-label">{$filter.name}:</label>
<select class="admin2000-filter-element" data-field="{$filter.db_field}">
<option value="">Alle</option>
{foreach from=$filter.values item=filter_val key=key}
<option value="{$key}">{$filter_val}</option>
{/foreach}
</select>
</div>
{/foreach}
</div>
</div>
<button class="admin2000-filter-toggle">
🔍 Filter anzeigen/ausblenden
</button>
{/if}
{* Stats Row - Real customer statistics *}
<div class="admin2000-stats-row">
<div class="admin2000-stat-card admin2000-stat-primary">
<div class="admin2000-stat-label">Gesamt Kunden</div>
<div class="admin2000-stat-value">{$customer_stats.total|default:0}</div>
</div>
<div class="admin2000-stat-card admin2000-stat-success">
<div class="admin2000-stat-label">Aktiv / Gesperrt</div>
<div class="admin2000-stat-value">
{$customer_stats.active|default:0} / {$customer_stats.locked|default:0}
</div>
</div>
<div class="admin2000-stat-card admin2000-stat-info">
<div class="admin2000-stat-label">Neu (30 Tage)</div>
<div class="admin2000-stat-value">{$customer_stats.new_30days|default:0}</div>
</div>
</div>
{* Table *}
<div class="admin2000-table-wrapper">
<table class="admin2000-table admin2000-customer-table">
<thead>
<tr>
{foreach from=$table_data.list_fields item=field}
<th class="{if $field.sortable == 1}admin2000-sortable{/if}" data-field="{$field.db_field}">
<a href="#" class="admin2000-sort-link" data-field="{$field.db_field}">
{$field.name}
{if $field.sortable == 1}
<span class="admin2000-sort-arrow">⇅</span>
{/if}
</a>
</th>
{/foreach}
<th class="admin2000-table-actions">Aktionen</th>
</tr>
</thead>
<tbody class="admin2000-table-body">
{* Content loaded via AJAX *}
<tr>
<td colspan="100" class="admin2000-loading-cell">
<div class="admin2000-loading">Lade Daten...</div>
</td>
</tr>
</tbody>
</table>
</div>
{* Pagination *}
<div class="admin2000-pagination">
<div class="admin2000-items-per-page">
<span class="admin2000-pagination-label">Einträge pro Seite:</span>
<a href="#" class="admin2000-limit-btn active" data-limit="20">20</a>
<a href="#" class="admin2000-limit-btn" data-limit="50">50</a>
<a href="#" class="admin2000-limit-btn" data-limit="100">100</a>
<a href="#" class="admin2000-limit-btn" data-limit="200">200</a>
</div>
<div class="admin2000-pagination-info">
Seite <span class="admin2000-current-page">1</span> von <span class="admin2000-total-pages">1</span>
</div>
<div class="admin2000-pagination-controls">
<a href="#" class="admin2000-pagination-btn admin2000-prev-page" data-page="prev">← Zurück</a>
<a href="#" class="admin2000-pagination-btn admin2000-next-page" data-page="next">Weiter →</a>
</div>
</div>
</div>
{* JavaScript for customer list *}
<script>
$(document).ready(function() {
// Settings
var settings = {
max_list_items: 20,
actual_page: 1,
sort_item: 'number',
sort_direction: 'down',
search_string: '',
list_filter: {}
};
// Load table data
function loadTableData() {
var params = $.param({
admin_modul: 'admin2000',
section: 'stammdaten',
page: 'kunden',
action: 'get_list_items',
max_list_items: settings.max_list_items,
actual_page: settings.actual_page,
sort_item: settings.sort_item,
sort_direction: settings.sort_direction,
search_string: settings.search_string,
list_filter: settings.list_filter
});
var url = 'index.php?' + params;
console.log('🔄 Loading data from:', url);
$('.admin2000-table-body').html('<tr><td colspan="100" class="admin2000-loading-cell"><div class="admin2000-loading">Lade Daten...</div></td></tr>');
$.get(url, function(data) {
console.log('✅ Data received:', data.substring(0, 200));
$('.admin2000-table-body').html(data);
updatePagination();
}).fail(function(xhr, status, error) {
console.error('❌ AJAX Error:', status, error);
$('.admin2000-table-body').html('<tr><td colspan="100" class="admin2000-error-cell"><strong>Fehler beim Laden der Daten</strong><br>' + error + '</td></tr>');
});
}
// Update pagination
function updatePagination() {
var paginationData = $('.admin2000-pagination-data');
if (paginationData.length) {
var page = paginationData.data('page');
var pages = paginationData.data('pages');
// Update pagination info (total count stays from backend PHP)
$('.admin2000-current-page').text(page);
$('.admin2000-total-pages').text(pages);
// Update settings
settings.actual_page = page;
}
}
// Sort handler
$('.admin2000-sort-link').click(function(e) {
e.preventDefault();
var field = $(this).data('field');
if (settings.sort_item === field) {
settings.sort_direction = (settings.sort_direction === 'up') ? 'down' : 'up';
} else {
settings.sort_item = field;
settings.sort_direction = 'down';
}
settings.actual_page = 1;
loadTableData();
});
// Search handler (jQuery 3.x - we can use .on() now!)
var searchTimeout;
$('.admin2000-search').on('keyup', function() {
clearTimeout(searchTimeout);
var searchValue = $(this).val();
searchTimeout = setTimeout(function() {
settings.search_string = searchValue;
settings.actual_page = 1;
loadTableData();
}, 500);
});
// Filter handler
$('.admin2000-filter-element').change(function() {
var field = $(this).data('field');
var value = $(this).val();
if (value) {
settings.list_filter[field] = value;
} else {
delete settings.list_filter[field];
}
settings.actual_page = 1;
loadTableData();
});
// Filter toggle
$('.admin2000-filter-toggle').click(function() {
$('.admin2000-filter-section').slideToggle();
});
// Items per page
$('.admin2000-limit-btn').click(function(e) {
e.preventDefault();
$('.admin2000-limit-btn').removeClass('active');
$(this).addClass('active');
settings.max_list_items = $(this).data('limit');
settings.actual_page = 1;
loadTableData();
});
// Pagination
$('.admin2000-prev-page').click(function(e) {
e.preventDefault();
if (settings.actual_page > 1) {
settings.actual_page--;
loadTableData();
}
});
$('.admin2000-next-page').click(function(e) {
e.preventDefault();
var paginationData = $('.admin2000-pagination-data');
var totalPages = paginationData.length ? paginationData.data('pages') : 1;
if (settings.actual_page < totalPages) {
settings.actual_page++;
loadTableData();
}
});
// Initial load
loadTableData();
});
</script>
@@ -0,0 +1,91 @@
{* ============================================
ADMIN2000 - Kunden Editor (Main)
Modulare Struktur mit Subtemplates
============================================ *}
<div class="admin2000-editor-container">
{* Header: Breadcrumb + Messages *}
{include file="admin2000/k-editor/header.tpl"}
{* Tab Navigation *}
<div class="admin2000-tabs-nav">
<button type="button" class="admin2000-tab-button active" data-tab="stammdaten">Stammdaten</button>
<button type="button" class="admin2000-tab-button" data-tab="firmendaten">Firmendaten</button>
<button type="button" class="admin2000-tab-button" data-tab="adressen">Adressen</button>
<button type="button" class="admin2000-tab-button" data-tab="zusatzfelder">Zusatzfelder</button>
<button type="button" class="admin2000-tab-button" data-tab="rechnungen">Rechnungen</button>
</div>
{* Main Form *}
<form id="admin2000-customer-form" method="post" action="./index.php?admin_modul=admin2000&section=stammdaten&page=kunden_editor&id={$customer_id}" class="admin2000-form">
{* Hidden Fields *}
<input type="hidden" name="customer_id" value="{$customer_id}">
<input type="hidden" name="action" value="save">
{* TAB 1: Stammdaten *}
<div class="admin2000-tab-content active" data-tab-content="stammdaten">
{include file="admin2000/k-editor/stammdaten.tpl"}
{include file="admin2000/k-editor/kontaktdaten.tpl"}
{include file="admin2000/k-editor/passwort.tpl"}
{include file="admin2000/k-editor/steuer.tpl"}
</div>
{* TAB 2: Firmendaten *}
<div class="admin2000-tab-content" data-tab-content="firmendaten">
{include file="admin2000/k-editor/firmendaten.tpl"}
</div>
{* TAB 4: Zusatzfelder *}
<div class="admin2000-tab-content" data-tab-content="zusatzfelder">
{include file="admin2000/k-editor/zusatzfelder.tpl"}
</div>
</form>
{* TAB 3: Adressen (outside form) *}
<div class="admin2000-tab-content" data-tab-content="adressen">
{include file="admin2000/k-editor/adressen.tpl"}
</div>
{* TAB 5: Rechnungen (outside form) *}
<div class="admin2000-tab-content" data-tab-content="rechnungen">
{include file="admin2000/k-editor/rechnungen.tpl"}
</div>
{* Sticky Save/Cancel Actions - Overall unten *}
<div class="admin2000-form-actions-sticky">
<div style="display: flex; gap: 15px;">
<button type="submit" form="admin2000-customer-form" class="admin2000-btn admin2000-btn-primary">
💾 Speichern
</button>
<a href="./index.php?admin_modul=admin2000&section=stammdaten&page=kunden" class="admin2000-btn admin2000-btn-secondary">
Abbrechen
</a>
</div>
</div>
</div>
<script>
$(document).ready(function() {
console.log('🎨 Kunden-Editor geladen (modular mit Tabs)');
console.log('Customer ID:', {$customer_id});
// Tab Switching
$('.admin2000-tab-button').click(function() {
var tabName = $(this).data('tab');
// Remove active class from all buttons and contents
$('.admin2000-tab-button').removeClass('active');
$('.admin2000-tab-content').removeClass('active');
// Add active class to clicked button and corresponding content
$(this).addClass('active');
$('[data-tab-content="' + tabName + '"]').addClass('active');
console.log('Switched to tab:', tabName);
});
});
</script>