import React, { useState, useRef } from 'react'; import { X, User, Mail, Phone, Shield, Check, Save, Camera, Upload, Trash2 } from 'lucide-react'; import { useAuth } from '../context/AuthContext'; import { SupabaseService } from '../services/supabaseService'; interface UserProfileModalProps { isOpen: boolean; onClose: () => void; } export const UserProfileModal: React.FC = ({ isOpen, onClose }) => { const { profile, updateProfile } = useAuth(); const [fullName, setFullName] = useState(profile?.fullName || ''); const [phone, setPhone] = useState(profile?.phone || ''); const [avatarUrl, setAvatarUrl] = useState(profile?.avatarUrl || ''); const [isSaved, setIsSaved] = useState(false); const [isSaving, setIsSaving] = useState(false); const [isUploadingPhoto, setIsUploadingPhoto] = useState(false); const fileInputRef = useRef(null); if (!isOpen || !profile) return null; const handleFileChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setIsUploadingPhoto(true); try { // 1. Try uploading to Supabase Storage const path = `avatars/${profile.id}_${Date.now()}.${file.name.split('.').pop() || 'jpg'}`; const storageUrl = await SupabaseService.uploadFileToStorage('equipment-files', path, file); if (storageUrl) { setAvatarUrl(storageUrl); } else { // Fallback: Read as Data URL for immediate local preview & storage const reader = new FileReader(); reader.onload = (event) => { if (event.target?.result) { setAvatarUrl(event.target.result as string); } }; reader.readAsDataURL(file); } } catch (err) { console.warn('Could not upload to storage bucket, using data URL fallback:', err); const reader = new FileReader(); reader.onload = (event) => { if (event.target?.result) { setAvatarUrl(event.target.result as string); } }; reader.readAsDataURL(file); } finally { setIsUploadingPhoto(false); } }; const handleSave = async (e: React.FormEvent) => { e.preventDefault(); setIsSaving(true); await updateProfile({ fullName, phone, avatarUrl }); setIsSaving(false); setIsSaved(true); setTimeout(() => setIsSaved(false), 2500); }; const getRoleBadgeStyle = (role: string) => { switch (role) { case 'admin': case 'disponent': return { bg: 'rgba(56, 189, 248, 0.15)', border: '#38bdf8', color: '#38bdf8', label: 'Admin / Disponent' }; case 'monteur': return { bg: 'rgba(74, 222, 128, 0.15)', border: '#4ade80', color: '#4ade80', label: 'Monteur / Außendienst' }; case 'kunde': return { bg: 'rgba(250, 204, 21, 0.15)', border: '#facc15', color: '#facc15', label: 'Kunde' }; default: return { bg: '#1e293b', border: '#64748b', color: '#94a3b8', label: role }; } }; const badge = getRoleBadgeStyle(profile.role); return (
{/* Header */}
{avatarUrl ? ( {fullName} ) : (
{profile.fullName.charAt(0).toUpperCase()}
)}

Mein Profil

Profilbild & Benutzerkontodaten

{/* Content Form */}
{/* Avatar Upload Section */}
fileInputRef.current?.click()}> {avatarUrl ? ( Profilbild ) : (
{fullName.charAt(0).toUpperCase() || 'U'}
)}
Profilfoto
JPG, PNG oder WebP Format
{avatarUrl && ( )}
{/* Role Pill */}
Zugriffsrolle
{badge.label}
{/* Full Name */}
setFullName(e.target.value)} style={{ width: '100%', padding: '10px 14px 10px 42px', backgroundColor: '#0f172a', border: '1px solid #334155', borderRadius: '8px', color: '#f8fafc', fontSize: '0.9rem', boxSizing: 'border-box', outline: 'none' }} />
{/* Email (Readonly) */}
{/* Phone */}
setPhone(e.target.value)} style={{ width: '100%', padding: '10px 14px 10px 42px', backgroundColor: '#0f172a', border: '1px solid #334155', borderRadius: '8px', color: '#f8fafc', fontSize: '0.9rem', boxSizing: 'border-box', outline: 'none' }} />
{/* Footer Actions */}
); };