diff --git a/v2_adminpanel/leads/repositories.py b/v2_adminpanel/leads/repositories.py index 8859907..a08141a 100644 --- a/v2_adminpanel/leads/repositories.py +++ b/v2_adminpanel/leads/repositories.py @@ -295,4 +295,36 @@ class LeadRepository: deleted = cur.rowcount > 0 cur.close() - return deleted \ No newline at end of file + return deleted + + def get_all_contacts_with_institutions(self) -> List[Dict[str, Any]]: + """Get all contacts with their institution information""" + with self.get_db_connection() as conn: + cur = conn.cursor(cursor_factory=RealDictCursor) + + query = """ + SELECT + c.id, + c.first_name, + c.last_name, + c.position, + c.created_at, + c.updated_at, + c.institution_id, + i.name as institution_name, + (SELECT COUNT(*) FROM lead_contact_details + WHERE contact_id = c.id AND detail_type = 'phone') as phone_count, + (SELECT COUNT(*) FROM lead_contact_details + WHERE contact_id = c.id AND detail_type = 'email') as email_count, + (SELECT COUNT(*) FROM lead_notes + WHERE contact_id = c.id AND is_current = true) as note_count + FROM lead_contacts c + JOIN lead_institutions i ON i.id = c.institution_id + ORDER BY c.last_name, c.first_name + """ + + cur.execute(query) + results = cur.fetchall() + cur.close() + + return results \ No newline at end of file diff --git a/v2_adminpanel/leads/routes.py b/v2_adminpanel/leads/routes.py index 97cde9c..4b60cc7 100644 --- a/v2_adminpanel/leads/routes.py +++ b/v2_adminpanel/leads/routes.py @@ -54,6 +54,17 @@ def contact_detail(contact_id): flash(f'Fehler beim Laden des Kontakts: {str(e)}', 'error') return redirect(url_for('leads.institutions')) +@leads_bp.route('/contacts') +@login_required +def all_contacts(): + """Show all contacts across all institutions""" + try: + contacts = lead_service.list_all_contacts() + return render_template('leads/all_contacts.html', contacts=contacts) + except Exception as e: + flash(f'Fehler beim Laden der Kontakte: {str(e)}', 'error') + return render_template('leads/all_contacts.html', contacts=[]) + # API Routes @leads_bp.route('/api/institutions', methods=['POST']) @login_required diff --git a/v2_adminpanel/leads/services.py b/v2_adminpanel/leads/services.py index 566b713..77c3b90 100644 --- a/v2_adminpanel/leads/services.py +++ b/v2_adminpanel/leads/services.py @@ -143,4 +143,8 @@ class LeadService: """Delete a note (soft delete)""" success = self.repo.delete_note(note_id) - return success \ No newline at end of file + return success + + def list_all_contacts(self) -> List[Dict[str, Any]]: + """Get all contacts across all institutions with summary info""" + return self.repo.get_all_contacts_with_institutions() \ No newline at end of file diff --git a/v2_adminpanel/leads/templates/leads/all_contacts.html b/v2_adminpanel/leads/templates/leads/all_contacts.html new file mode 100644 index 0000000..ecddeaa --- /dev/null +++ b/v2_adminpanel/leads/templates/leads/all_contacts.html @@ -0,0 +1,239 @@ +{% extends "base.html" %} + +{% block title %}Alle Kontakte{% endblock %} + +{% block content %} +
Übersicht aller Kontakte aus allen Institutionen
+| Name | +Institution | +Position | +Kontaktdaten | +Notizen | +Zuletzt aktualisiert | +Aktionen | +
|---|---|---|---|---|---|---|
| + + {{ contact.last_name }}, {{ contact.first_name }} + + | ++ + {{ contact.institution_name }} + + | +{{ contact.position or '-' }} | ++ {% if contact.phone_count > 0 %} + + {{ contact.phone_count }} + + {% endif %} + {% if contact.email_count > 0 %} + + {{ contact.email_count }} + + {% endif %} + {% if contact.phone_count == 0 and contact.email_count == 0 %} + - + {% endif %} + | ++ {% if contact.note_count > 0 %} + + {{ contact.note_count }} + + {% else %} + - + {% endif %} + | ++ {{ (contact.updated_at or contact.created_at).strftime('%d.%m.%Y %H:%M') }} + | ++ + Details + + | +
Noch keine Kontakte vorhanden.
+ + Zu Institutionen + ++ {{ contacts|length }} von {{ contacts|length }} Kontakten angezeigt +
+