OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

index.php

27 KB
<?php
$this->layout('layouts/main', [
    'page_title' => 'Adressbuch',
    'breadcrumbs' => [],
    'full_width' => true,
    'current_route' => 'contacts',
    'extra_css' => ['/assets/css/contacts.css?v=' . filemtime(dirname(__DIR__, 2) . '/public/assets/css/contacts.css')],
    'extra_js'  => ['/assets/js/contacts.js?v=' . filemtime(dirname(__DIR__, 2) . '/public/assets/js/contacts.js')],
]);

$companies   = $companies ?? [];
$contacts    = $contacts ?? [];
$search      = $search ?? '';
$canManage   = $can_manage ?? false;
$viewMode    = $view_mode ?? 'cards';
$page        = $page ?? 1;
$totalPages  = $total_pages ?? 1;
$totalComp   = $total_companies ?? count($companies);
$sort        = $sort ?? 'name';
$dir         = $dir ?? 'asc';
$csrfToken   = $this->csrf();
$view        = $this;

// Baut einen Link unter Beibehaltung von Suche und Sortierung
$pageUrl = function (int $p) use ($search, $sort, $dir): string {
    $params = ['page' => $p];
    if ($search !== '') {
        $params['q'] = $search;
    }
    if ($sort !== 'name') {
        $params['sort'] = $sort;
    }
    if ($dir !== 'asc') {
        $params['dir'] = $dir;
    }
    return '/contacts?' . http_build_query($params);
};
$sortOptions = ['name' => 'Name', 'contacts' => 'Anzahl Kontakte', 'created' => 'Neueste zuerst'];
?>

<div class="cb-fullwidth">
    <div class="content-header">
        <div>
            <h1><?= $this->te('Adressbuch') ?></h1>
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
                <li class="breadcrumb-item active"><?= $this->te('Adressbuch') ?></li>
            </ol>
        </div>
        <div class="content-header-actions">
            <div class="cb-view-toggle" id="cbViewToggle" role="group" aria-label="<?= $this->te('Ansicht wählen') ?>">
                <button type="button" class="cb-view-btn <?= $viewMode === 'cards' ? 'active' : '' ?>"
                        data-mode="cards" title="<?= $this->te('Kartenansicht') ?>" aria-label="<?= $this->te('Kartenansicht') ?>"
                        aria-pressed="<?= $viewMode === 'cards' ? 'true' : 'false' ?>">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16" aria-hidden="true" focusable="false">
                        <rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/>
                        <rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/>
                    </svg>
                </button>
                <button type="button" class="cb-view-btn <?= $viewMode === 'list' ? 'active' : '' ?>"
                        data-mode="list" title="<?= $this->te('Listenansicht') ?>" aria-label="<?= $this->te('Listenansicht') ?>"
                        aria-pressed="<?= $viewMode === 'list' ? 'true' : 'false' ?>">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16" aria-hidden="true" focusable="false">
                        <line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/>
                        <line x1="8" y1="18" x2="21" y2="18"/>
                        <line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/>
                        <line x1="3" y1="18" x2="3.01" y2="18"/>
                    </svg>
                </button>
            </div>

            <?php if ($canManage): ?>
                <button type="button" class="btn btn-default" data-modal-open="importModal" title="<?= $this->te('Kontakte importieren') ?>"><?= $this->te('Import') ?></button>
                <a href="/contacts/trash" class="btn btn-default" title="<?= $this->te('Papierkorb') ?>"><?= $this->te('Papierkorb') ?></a>
                <button type="button" class="btn btn-primary" data-modal-open="newCompanyModal">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18" aria-hidden="true" focusable="false"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
                    <?= $this->te('Neue Firma') ?>
                </button>
            <?php endif; ?>
        </div>
    </div>

    <!-- Suchleiste -->
    <div class="card card-outline card-primary" style="margin: 1.25rem 1rem;">
        <div class="filter-card-body">
            <form method="GET" action="/contacts" class="cb-search-form" role="search">
                <div class="cb-search-field">
                    <svg class="cb-search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15" aria-hidden="true" focusable="false"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
                    <label for="cb-search" class="sr-only"><?= $this->te('Firma oder Person suchen') ?></label>
                    <input id="cb-search" type="search" name="q" class="form-control cb-search-input" placeholder="<?= $this->te('Firma oder Person suchen…') ?>" value="<?= $view->e($search) ?>" autocomplete="off">
                </div>
                <button type="submit" class="btn btn-default"><?= $this->te('Suchen') ?></button>
                <?php if ($search !== ''): ?>
                    <a href="/contacts" class="btn btn-default">
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="13" height="13" aria-hidden="true" focusable="false"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                        <?= $this->te('Zurücksetzen') ?>
                    </a>
                <?php endif; ?>
                <span class="cb-sort-spacer"></span>
                <label for="cb-sort" class="sr-only"><?= $this->te('Sortieren nach') ?></label>
                <select id="cb-sort" name="sort" class="form-control cb-inline-select" data-autosubmit>
                    <?php foreach ($sortOptions as $val => $label): ?>
                        <option value="<?= $val ?>"<?= $sort === $val ? ' selected' : '' ?>><?= $label ?></option>
                    <?php endforeach; ?>
                </select>
                <select name="dir" class="form-control cb-inline-select" data-autosubmit aria-label="<?= $this->te('Reihenfolge') ?>">
                    <option value="asc"<?= $dir === 'asc' ? ' selected' : '' ?>><?= $this->te('Aufsteigend') ?></option>
                    <option value="desc"<?= $dir === 'desc' ? ' selected' : '' ?>><?= $this->te('Absteigend') ?></option>
                </select>
            </form>
        </div>
    </div>

    <!-- Suchergebnisse: Personen -->
    <?php if ($search !== '' && !empty($contacts)): ?>
    <div class="cb-content">
        <h2 class="cb-section-title"><?= $this->t('Personen') ?> (<?= count($contacts) ?>)</h2>
        <div class="cb-contacts-grid">
            <?php foreach ($contacts as $contact):
                $personName = trim(($contact['last_name'] ?? '') . ', ' . ($contact['first_name'] ?? ''));
            ?>
                <a href="/contacts/companies/<?= (int)$contact['company_id'] ?>" class="cb-person-card">
                    <?php if (!empty($contact['image_path'])): ?>
                        <img src="<?= $view->e($contact['image_path']) ?>" alt="<?= $this->te('Foto von {name}', ['name' => $personName]) ?>" class="cb-person-avatar-img">
                    <?php else: ?>
                        <span class="cb-person-avatar" aria-hidden="true">
                            <?= $view->e(strtoupper(mb_substr($contact['first_name'] ?? '?', 0, 1))) ?><?= $view->e(strtoupper(mb_substr($contact['last_name'] ?? '?', 0, 1))) ?>
                        </span>
                    <?php endif; ?>
                    <div class="cb-person-info">
                        <div class="cb-person-name"><?= $view->e($personName) ?></div>
                        <?php if (!empty($contact['position'])): ?>
                            <div class="cb-person-position"><?= $view->e($contact['position']) ?></div>
                        <?php endif; ?>
                        <div class="cb-person-company"><?= $view->e($contact['company_name'] ?? '') ?></div>
                    </div>
                    <div class="cb-person-contacts">
                        <?php if (!empty($contact['phone'])): ?>
                            <span class="cb-person-detail">&#128222; <?= $view->e($contact['phone']) ?></span>
                        <?php endif; ?>
                        <?php if (!empty($contact['email'])): ?>
                            <span class="cb-person-detail">&#9993; <?= $view->e($contact['email']) ?></span>
                        <?php endif; ?>
                    </div>
                </a>
            <?php endforeach; ?>
        </div>
    </div>
    <?php endif; ?>

    <!-- Firmen-Liste -->
    <div class="cb-content">
        <?php if ($search !== ''): ?>
            <h2 class="cb-section-title"><?= $this->t('Firmen') ?> (<?= (int)$totalComp ?>)</h2>
        <?php endif; ?>
        <?php if ($search !== '' && empty($companies) && empty($contacts)): ?>
            <div class="cb-empty-state">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="48" height="48" aria-hidden="true" focusable="false"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
                <p><?= $this->t('Keine Ergebnisse f&uuml;r &bdquo;{suche}&ldquo; gefunden', ['suche' => $view->e($search)]) ?></p>
                <a href="/contacts" class="cb-btn cb-btn-secondary"><?= $this->te('Alle Firmen anzeigen') ?></a>
            </div>
        <?php elseif ($search === '' && empty($companies)): ?>
            <div class="cb-empty-state">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="48" height="48" aria-hidden="true" focusable="false"><path d="M3 21h18"/><path d="M5 21V7l8-4v18"/><path d="M19 21V11l-6-4"/><path d="M9 9h1"/><path d="M9 13h1"/><path d="M9 17h1"/></svg>
                <p><?= $this->te('Noch keine Firmen vorhanden') ?></p>
                <?php if ($canManage): ?>
                    <button type="button" class="cb-btn cb-btn-primary" data-modal-open="newCompanyModal"><?= $this->te('Erste Firma anlegen') ?></button>
                <?php endif; ?>
            </div>
        <?php elseif (!empty($companies)): ?>

            <!-- KARTENANSICHT -->
            <div class="cb-grid <?= $viewMode === 'list' ? 'cb-hidden' : '' ?>" id="cbCardsView">
                <?php foreach ($companies as $company): ?>
                    <a href="/contacts/companies/<?= (int)$company['id'] ?>" class="cb-card">
                        <div class="cb-card-header">
                            <?php if (!empty($company['image_path'])): ?>
                                <img src="<?= $view->e($company['image_path']) ?>" alt="<?= $this->te('Logo von {firma}', ['firma' => $company['name'] ?? '']) ?>" class="cb-card-avatar-img">
                            <?php else: ?>
                            <span class="cb-card-avatar" style="background: <?= $view->e($company['color'] ?? 'var(--color-primary)') ?>" aria-hidden="true">
                                <?= $view->e(strtoupper(mb_substr($company['name'] ?? '', 0, 1))) ?>
                            </span>
                            <?php endif; ?>
                            <div class="cb-card-title">
                                <div class="cb-card-name"><?= $view->e($company['name'] ?? '') ?></div>
                                <?php if (!empty($company['customer_number'])): ?>
                                    <div class="cb-card-custnr"><?= $this->te('Kd-Nr: {nummer}', ['nummer' => $company['customer_number']]) ?></div>
                                <?php endif; ?>
                                <?php if (!empty($company['address'])): ?>
                                    <div class="cb-card-address">
                                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="13" height="13" aria-hidden="true" focusable="false"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
                                        <span><?= $view->e($company['address']) ?></span>
                                    </div>
                                <?php endif; ?>
                            </div>
                        </div>

                        <div class="cb-card-details">
                            <?php if (!empty($company['phone'])): ?>
                                <span class="cb-card-detail">
                                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" aria-hidden="true" focusable="false"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
                                    <span><?= $view->e($company['phone']) ?></span>
                                </span>
                            <?php endif; ?>
                            <?php if (!empty($company['email'])): ?>
                                <span class="cb-card-detail">
                                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" aria-hidden="true" focusable="false"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
                                    <span><?= $view->e($company['email']) ?></span>
                                </span>
                            <?php endif; ?>
                        </div>

                        <div class="cb-card-footer">
                            <span class="cb-card-contacts-badge">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" aria-hidden="true" focusable="false"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
                                <?= (int)($company['contact_count'] ?? 0) ?> Kontakt<?= ((int)($company['contact_count'] ?? 0)) !== 1 ? 'e' : '' ?>
                            </span>
                            <span class="cb-card-arrow">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16" aria-hidden="true" focusable="false"><polyline points="9 18 15 12 9 6"/></svg>
                            </span>
                        </div>
                    </a>
                <?php endforeach; ?>
            </div>

            <!-- LISTENANSICHT -->
            <div class="cb-list-view <?= $viewMode !== 'list' ? 'cb-hidden' : '' ?>" id="cbListView">
                <?php foreach ($companies as $company):
                    $contactCount = (int)($company['contact_count'] ?? 0);
                    $phone   = trim((string)($company['phone'] ?? ''));
                    $email   = trim((string)($company['email'] ?? ''));
                    $address = trim((string)($company['address'] ?? ''));
                ?>
                    <a href="/contacts/companies/<?= (int)$company['id'] ?>" class="cb-list-item">
                        <div class="cb-list-avatar">
                            <?php if (!empty($company['image_path'])): ?>
                                <img src="<?= $view->e($company['image_path']) ?>" alt="<?= $this->te('Logo von {firma}', ['firma' => $company['name'] ?? '']) ?>" class="cb-list-avatar-img">
                            <?php else: ?>
                                <span class="cb-list-avatar-initials" style="background: <?= $view->e($company['color'] ?? 'var(--color-primary)') ?>" aria-hidden="true">
                                    <?= $view->e(strtoupper(mb_substr($company['name'] ?? '', 0, 1))) ?>
                                </span>
                            <?php endif; ?>
                        </div>

                        <div class="cb-list-main">
                            <span class="cb-list-name"><?= $view->e($company['name'] ?? '') ?></span>
                            <?php if (!empty($company['customer_number'])): ?>
                                <span class="cb-list-custnr"><?= $this->te('Kd-Nr: {nummer}', ['nummer' => $company['customer_number']]) ?></span>
                            <?php endif; ?>
                        </div>

                        <span class="cb-list-cell<?= $phone === '' ? ' cb-list-cell-empty' : '' ?>">
                            <svg class="cb-list-cell-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" aria-hidden="true" focusable="false"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
                            <span class="cb-list-cell-val"><?= $phone !== '' ? $view->e($phone) : '&ndash;' ?></span>
                        </span>

                        <span class="cb-list-cell<?= $email === '' ? ' cb-list-cell-empty' : '' ?>">
                            <svg class="cb-list-cell-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" aria-hidden="true" focusable="false"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
                            <span class="cb-list-cell-val"><?= $email !== '' ? $view->e($email) : '&ndash;' ?></span>
                        </span>

                        <span class="cb-list-cell cb-list-cell-addr<?= $address === '' ? ' cb-list-cell-empty' : '' ?>">
                            <svg class="cb-list-cell-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" aria-hidden="true" focusable="false"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
                            <span class="cb-list-cell-val"><?= $address !== '' ? $view->e($address) : '&ndash;' ?></span>
                        </span>

                        <div class="cb-list-badge">
                            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="13" height="13" aria-hidden="true" focusable="false"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
                            <?= $contactCount ?> Kontakt<?= $contactCount !== 1 ? 'e' : '' ?>
                        </div>

                        <span class="cb-list-arrow">
                            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14" aria-hidden="true" focusable="false"><polyline points="9 18 15 12 9 6"/></svg>
                        </span>
                    </a>
                <?php endforeach; ?>
            </div>

            <!-- Pagination -->
            <?php if ($totalPages > 1): ?>
                <nav class="cb-pagination" aria-label="<?= $this->te('Seitennavigation') ?>">
                    <?php if ($page > 1): ?>
                        <a class="cb-page-link" href="<?= $view->e($pageUrl($page - 1)) ?>" rel="prev" aria-label="<?= $this->te('Vorherige Seite') ?>">&laquo;</a>
                    <?php endif; ?>
                    <?php
                    $start = max(1, $page - 2);
                    $end = min($totalPages, $page + 2);
                    if ($start > 1): ?>
                        <a class="cb-page-link" href="<?= $view->e($pageUrl(1)) ?>">1</a>
                        <?php if ($start > 2): ?><span class="cb-page-ellipsis">…</span><?php endif; ?>
                    <?php endif; ?>
                    <?php for ($p = $start; $p <= $end; $p++): ?>
                        <?php if ($p === $page): ?>
                            <span class="cb-page-link cb-page-current" aria-current="page"><?= $p ?></span>
                        <?php else: ?>
                            <a class="cb-page-link" href="<?= $view->e($pageUrl($p)) ?>"><?= $p ?></a>
                        <?php endif; ?>
                    <?php endfor; ?>
                    <?php if ($end < $totalPages): ?>
                        <?php if ($end < $totalPages - 1): ?><span class="cb-page-ellipsis">…</span><?php endif; ?>
                        <a class="cb-page-link" href="<?= $view->e($pageUrl($totalPages)) ?>"><?= $totalPages ?></a>
                    <?php endif; ?>
                    <?php if ($page < $totalPages): ?>
                        <a class="cb-page-link" href="<?= $view->e($pageUrl($page + 1)) ?>" rel="next" aria-label="<?= $this->te('Nächste Seite') ?>">&raquo;</a>
                    <?php endif; ?>
                </nav>
                <div class="cb-page-info"><?= $this->te('Seite {seite} von {gesamt} &middot; {firmen} Firmen', ['seite' => (int)$page, 'gesamt' => (int)$totalPages, 'firmen' => (int)$totalComp]) ?></div>
            <?php endif; ?>

        <?php endif; ?>
    </div>
</div>

<?php if ($canManage): ?>
<!-- Modal: Neue Firma -->
<div id="newCompanyModal" class="cb-modal" role="dialog" aria-modal="true" aria-labelledby="newCompanyModalTitle" hidden>
    <div class="cb-modal-backdrop" data-close></div>
    <div class="cb-modal-dialog">
        <div class="cb-modal-header">
            <h2 id="newCompanyModalTitle"><?= $this->te('Neue Firma anlegen') ?></h2>
            <button type="button" class="cb-modal-close" data-close aria-label="<?= $this->te('Dialog schließen') ?>">&times;</button>
        </div>
        <form method="POST" action="/contacts/companies" enctype="multipart/form-data">
            <input type="hidden" name="_csrf" value="<?= $view->e($csrfToken) ?>">
            <div class="cb-modal-body">
                <div class="cb-form-group">
                    <label for="cb-company-image"><?= $this->te('Firmenlogo') ?></label>
                    <input type="file" id="cb-company-image" name="image" class="cb-input" accept="image/jpeg,image/png,image/gif,image/webp">
                </div>
                <div class="cb-form-row">
                    <div class="cb-form-group">
                        <label for="cb-company-name"><?= $this->te('Name *') ?></label>
                        <input type="text" id="cb-company-name" name="name" class="cb-input" placeholder="<?= $this->te('z.B. Muster GmbH') ?>" required>
                    </div>
                    <div class="cb-form-group">
                        <label for="cb-company-custnr"><?= $this->te('Kundennummer') ?></label>
                        <input type="text" id="cb-company-custnr" name="customer_number" class="cb-input" placeholder="<?= $this->te('z.B. KD-12345') ?>">
                    </div>
                </div>
                <div class="cb-form-group">
                    <label for="cb-company-address"><?= $this->te('Adresse') ?></label>
                    <textarea id="cb-company-address" name="address" class="cb-input cb-textarea" rows="2" placeholder="<?= $this->te('Stra&szlig;e, PLZ Ort') ?>"></textarea>
                </div>
                <div class="cb-form-row">
                    <div class="cb-form-group">
                        <label for="cb-company-phone"><?= $this->te('Telefon') ?></label>
                        <input type="text" id="cb-company-phone" name="phone" class="cb-input" placeholder="+49 ...">
                    </div>
                    <div class="cb-form-group">
                        <label for="cb-company-email"><?= $this->t('E-Mail') ?></label>
                        <input type="email" id="cb-company-email" name="email" class="cb-input" placeholder="<?= $this->te('info@firma.de') ?>">
                    </div>
                </div>
                <div class="cb-form-group">
                    <label for="cb-company-website"><?= $this->te('Website') ?></label>
                    <input type="url" id="cb-company-website" name="website" class="cb-input" placeholder="https://www.firma.de">
                </div>
                <?= $view->render('contacts/_channel_fields', ['channels' => []]) ?>
                <div class="cb-form-group">
                    <label for="cb-company-notes"><?= $this->te('Notizen') ?></label>
                    <textarea id="cb-company-notes" name="notes" class="cb-input cb-textarea" rows="3" placeholder="<?= $this->te('Interne Anmerkungen...') ?>"></textarea>
                </div>
            </div>
            <div class="cb-modal-footer">
                <button type="button" class="cb-btn cb-btn-secondary" data-close><?= $this->te('Abbrechen') ?></button>
                <button type="submit" class="cb-btn cb-btn-primary"><?= $this->te('Firma erstellen') ?></button>
            </div>
        </form>
    </div>
</div>

<div id="importModal" class="cb-modal" role="dialog" aria-modal="true" aria-labelledby="importModalTitle" hidden>
    <div class="cb-modal-backdrop" data-close></div>
    <div class="cb-modal-dialog">
        <div class="cb-modal-header">
            <h2 id="importModalTitle"><?= $this->te('Kontakte importieren') ?></h2>
            <button type="button" class="cb-modal-close" data-close aria-label="<?= $this->te('Dialog schließen') ?>">&times;</button>
        </div>
        <form action="/contacts/import" method="POST" enctype="multipart/form-data">
            <input type="hidden" name="_csrf" value="<?= $view->e($csrfToken) ?>">
            <div class="cb-modal-body">
                <div class="cb-form-group">
                    <label for="cb-import-file"><?= $this->te('CSV- oder vCard-Datei') ?></label>
                    <input type="file" id="cb-import-file" name="file" class="cb-input" accept=".csv,.vcf,.vcard,text/csv,text/vcard" required>
                </div>
                <p class="cb-import-hint">
                    <?= $this->t('<strong>CSV:</strong> Erste Zeile als Kopfzeile mit Spalten wie <code>Vorname;Nachname;Position;Firma;Telefon;Mobil;E-Mail;Notizen</code> (Semikolon- oder Komma-getrennt). Das Format entspricht dem CSV-Export.<br> <strong>vCard (.vcf):</strong> Standard-vCards werden erkannt; <code>ORG</code> wird als Firma &uuml;bernommen.<br> Existierende Firmen werden anhand des Namens wiederverwendet, fehlende neu angelegt. Kontakte ohne Firma landen unter &bdquo;Unzugeordnet&ldquo;.') ?>
                </p>
            </div>
            <div class="cb-modal-footer">
                <button type="button" class="cb-btn cb-btn-secondary" data-close><?= $this->te('Abbrechen') ?></button>
                <button type="submit" class="cb-btn cb-btn-primary"><?= $this->te('Importieren') ?></button>
            </div>
        </form>
    </div>
</div>
<?php endif; ?>