import React, { useEffect, useState } from 'react'; import { Users, Plus, Trash2, ArrowLeft, Check, AlertCircle, UserPlus, Shield, Pencil, X, LogOut, } from 'lucide-react'; import { Team, User } from '../../lib/types'; import { api, triggerHaptic } from '../../lib/api'; import { UserAutocomplete } from '../UserAutocomplete'; interface GroupsViewProps { currentUser: User; onBack: () => void; } export const GroupsView: React.FC = ({ currentUser, onBack }) => { const [teams, setTeams] = useState([]); const [directoryUsers, setDirectoryUsers] = useState([]); const [loading, setLoading] = useState(true); const [statusMsg, setStatusMsg] = useState<{ type: 'ok' | 'err'; text: string } | null>(null); // Create Group Modal State const [showCreateModal, setShowCreateModal] = useState(false); const [newGroupName, setNewGroupName] = useState(''); const [newGroupDesc, setNewGroupDesc] = useState(''); const [creating, setCreating] = useState(false); // Edit Group State const [editingTeamId, setEditingTeamId] = useState(null); const [editName, setEditName] = useState(''); const [editDesc, setEditDesc] = useState(''); // Add Member State per Team const [selectedUserByTeam, setSelectedUserByTeam] = useState>({}); const [memberRoleByTeam, setMemberRoleByTeam] = useState>({}); const loadData = async () => { try { const [userTeams, allUsers] = await Promise.all([ api.getUserTeams(), api.getUsersDirectory().catch(() => []), ]); setTeams(userTeams); setDirectoryUsers(allUsers); } catch (err: any) { setStatusMsg({ type: 'err', text: err.message || 'Fehler beim Laden der Gruppen' }); } finally { setLoading(false); } }; useEffect(() => { loadData(); }, []); const handleCreateGroup = async (e: React.FormEvent) => { e.preventDefault(); const name = newGroupName.trim(); if (!name) return; setCreating(true); setStatusMsg(null); triggerHaptic(15); try { const created = await api.createTeam(name, newGroupDesc.trim()); setNewGroupName(''); setNewGroupDesc(''); setShowCreateModal(false); await loadData(); setStatusMsg({ type: 'ok', text: `Gruppe "${created.name}" erfolgreich erstellt.` }); } catch (err: any) { setStatusMsg({ type: 'err', text: err.message || 'Fehler beim Erstellen der Gruppe' }); } finally { setCreating(false); } }; const handleStartEdit = (team: Team) => { setEditingTeamId(team.id); setEditName(team.name); setEditDesc(team.description || ''); }; const handleSaveEdit = async (teamId: string) => { const name = editName.trim(); if (!name) return; setStatusMsg(null); triggerHaptic(10); try { await api.updateTeam(teamId, name, editDesc.trim()); setEditingTeamId(null); await loadData(); setStatusMsg({ type: 'ok', text: 'Gruppe erfolgreich aktualisiert.' }); } catch (err: any) { setStatusMsg({ type: 'err', text: err.message || 'Fehler beim Aktualisieren der Gruppe' }); } }; const handleDeleteTeam = async (team: Team) => { if (!window.confirm(`Gruppe "${team.name}" wirklich löschen? Alle Freigaben für diese Gruppe werden entfernt.`)) { return; } setStatusMsg(null); triggerHaptic(15); try { await api.deleteTeam(team.id); await loadData(); setStatusMsg({ type: 'ok', text: `Gruppe "${team.name}" gelöscht.` }); } catch (err: any) { setStatusMsg({ type: 'err', text: err.message || 'Fehler beim Löschen der Gruppe' }); } }; const handleAddMember = async (teamId: string) => { const user = selectedUserByTeam[teamId]; if (!user) return; const role = memberRoleByTeam[teamId] || 'member'; setStatusMsg(null); triggerHaptic(10); try { await api.addTeamMember(teamId, { userId: user.id, role }); setSelectedUserByTeam((prev) => ({ ...prev, [teamId]: null })); await loadData(); setStatusMsg({ type: 'ok', text: `${user.displayName} wurde zur Gruppe hinzugefügt.` }); } catch (err: any) { setStatusMsg({ type: 'err', text: err.message || 'Fehler beim Hinzufügen des Mitglieds' }); } }; const handleChangeMemberRole = async (teamId: string, memberUserId: string, newRole: 'admin' | 'member') => { setStatusMsg(null); triggerHaptic(10); try { await api.updateTeamMemberRole(teamId, memberUserId, newRole); await loadData(); setStatusMsg({ type: 'ok', text: `Rolle erfolgreich zu "${newRole === 'admin' ? 'Gruppen-Admin' : 'Mitglied'}" geändert.`, }); } catch (err: any) { setStatusMsg({ type: 'err', text: err.message || 'Fehler beim Ändern der Rolle' }); } }; const handleRemoveMember = async (teamId: string, memberUserId: string, memberName: string) => { const isSelf = memberUserId === currentUser.id; const msg = isSelf ? 'Möchtest du diese Gruppe wirklich verlassen?' : `Mitglied "${memberName}" wirklich aus der Gruppe entfernen?`; if (!window.confirm(msg)) return; setStatusMsg(null); triggerHaptic(10); try { await api.removeTeamMember(teamId, memberUserId); await loadData(); setStatusMsg({ type: 'ok', text: isSelf ? 'Du hast die Gruppe verlassen.' : `Mitglied "${memberName}" wurde entfernt.`, }); } catch (err: any) { setStatusMsg({ type: 'err', text: err.message || 'Fehler beim Entfernen des Mitglieds' }); } }; // Group teams into managed (admin) and member-only const managedTeams = teams.filter((t) => (t.members || []).some((m) => m.userId === currentUser.id && m.role === 'admin') ); const memberTeams = teams.filter( (t) => (t.members || []).some((m) => m.userId === currentUser.id && m.role === 'member') && !managedTeams.some((mt) => mt.id === t.id) ); return (
{/* Page Header */}

Gruppen & Teams {teams.length}

Erstelle und verwalte Gruppen (z. B. Familie, WG oder Projektteams) für gemeinsame Notizen, Aufgaben und Listen.

{/* Status Messages */} {statusMsg && (
{statusMsg.type === 'ok' ? ( ) : ( )} {statusMsg.text}
)} {/* Modal: Neue Gruppe erstellen */} {showCreateModal && (
setShowCreateModal(false)} >
e.stopPropagation()} >

Neue Gruppe erstellen

setNewGroupName(e.target.value)} placeholder="z. B. Familie, WG, Arbeit, Projekt X…" required autoFocus className="w-full h-8 px-2.5 input-field text-xs" />
setNewGroupDesc(e.target.value)} placeholder="z. B. Gemeinsame Einkaufslisten & Notizen…" className="w-full h-8 px-2.5 input-field text-xs" />

Du wirst Gruppen-Admin

Als Ersteller kannst du weitere Mitglieder hinzufügen, Rollen zuweisen und die Gruppe verwalten.

)} {/* Main Content Area */} {loading ? (
Lade Gruppen…
) : teams.length === 0 ? (

Noch keine Gruppen vorhanden

Erstelle deine erste Gruppe, um Aufgaben, Einkaufslisten oder Dokumente gemeinsam mit anderen zu nutzen.

) : (
{/* SECTION 1: Gruppen, die ich verwalte */}

Gruppen, die ich verwalte ({managedTeams.length})

{managedTeams.length === 0 ? (
Du bist derzeit noch in keiner Gruppe als Admin eingetragen. Klicke oben auf "Neue Gruppe", um eine eigene Gruppe zu erstellen.
) : (
{managedTeams.map((team) => { const members = team.members || []; const isEditing = editingTeamId === team.id; const memberUserIds = members.map((m) => m.userId); return (
{/* Team Header */}
{isEditing ? (
setEditName(e.target.value)} placeholder="Gruppenname" className="w-full h-8 px-2.5 input-field text-xs font-bold" /> setEditDesc(e.target.value)} placeholder="Optionale Beschreibung" className="w-full h-7 px-2.5 input-field text-xs" />
) : (
{team.name} Gruppen-Admin {members.length} {members.length === 1 ? 'Mitglied' : 'Mitglieder'}
{team.description && (

{team.description}

)}
)}
{!isEditing && (
)}
{/* Members List */}

Mitglieder ({members.length})

{members.map((m) => { const isSelf = m.userId === currentUser.id; const isAdmin = m.role === 'admin'; return (
{(m.displayName || 'U').slice(0, 1).toUpperCase()}

{m.displayName} {isSelf && (Du)}

{m.email}

); })}
{/* Add Member Row */}
setSelectedUserByTeam((prev) => ({ ...prev, [team.id]: u })) } excludeUserIds={memberUserIds} placeholder="Benutzer suchen zum Hinzufügen…" />
); })}
)}
{/* SECTION 2: Meine Mitgliedschaften (als Mitglied) */} {memberTeams.length > 0 && (

Meine Mitgliedschaften ({memberTeams.length})

{memberTeams.map((team) => { const members = team.members || []; const admins = members.filter((m) => m.role === 'admin'); return (
{team.name} {members.length} {members.length === 1 ? 'Mitglied' : 'Mitglieder'}
{team.description && (

{team.description}

)}
{/* Admins & Members list in read-only mode */}

Gruppen-Admins:{' '} {admins.map((a) => a.displayName).join(', ') || 'Keiner'}

Alle Mitglieder:{' '} {members.map((m) => m.displayName).join(', ')}

); })}
)}
)}
); };