// ProfileView Component // Enhanced with username, share code, and bio features function ProfileView({ user, token, t, onUserUpdate }) { const [profile, setProfile] = useState(null); const [loading, setLoading] = useState(true); const [editing, setEditing] = useState({ username: false, bio: false }); const [formData, setFormData] = useState({ username: '', bio: '' }); const [error, setError] = useState(''); const [success, setSuccess] = useState(''); const [friends, setFriends] = useState([]); const [friendsLoading, setFriendsLoading] = useState(false); useEffect(() => { loadProfile(); loadFriends(); }, []); const loadProfile = async () => { try { const response = await fetch(API_URL + '/profile/me', { headers: { 'Authorization': `Bearer ${token}` } }); const data = await response.json(); setProfile(data); setFormData({ username: data.username || '', bio: data.bio || '' }); } catch (err) { console.error('Failed to load profile:', err); } finally { setLoading(false); } }; const updateUsername = async () => { setError(''); setSuccess(''); try { const response = await fetch(API_URL + '/profile/username', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ username: formData.username }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to update username'); } const data = await response.json(); setSuccess('Username updated successfully!'); setEditing({ ...editing, username: false }); loadProfile(); } catch (err) { setError(err.message); } }; const updateBio = async () => { setError(''); setSuccess(''); try { const response = await fetch(API_URL + '/profile/bio', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ bio: formData.bio }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to update bio'); } setSuccess('Bio updated successfully!'); setEditing({ ...editing, bio: false }); loadProfile(); } catch (err) { setError(err.message); } }; const regenerateShareCode = async () => { if (!confirm('Are you sure you want to generate a new share code? Your old code will stop working.')) { return; } try { const response = await fetch(API_URL + '/profile/regenerate-code', { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); const data = await response.json(); alert('New share code generated!'); loadProfile(); } catch (err) { alert('Failed to regenerate code'); } }; const copyToClipboard = (text, label) => { navigator.clipboard.writeText(text); setSuccess(`${label} copied to clipboard!`); setTimeout(() => setSuccess(''), 3000); }; const loadFriends = async () => { setFriendsLoading(true); try { const response = await fetch(API_URL + '/connections/my-friends', { headers: { 'Authorization': `Bearer ${token}` } }); const data = await response.json(); setFriends(data.friends || []); } catch (err) { console.error('Failed to load friends:', err); } finally { setFriendsLoading(false); } }; if (loading) { return
Loading profile...
; } if (!profile) { return
Failed to load profile
; } const profileLink = profile.username ? `${window.location.origin}/@${profile.username}` : `${window.location.origin}/user/${profile.id}`; return (

Profile

{/* Success/Error Messages */} {success && (
✓ {success}
)} {error && (
✗ {error}
)} {/* Basic Info Card */}
{ const updatedProfile = { ...profile, photo_url: newPhotoUrl }; setProfile(updatedProfile); // Propagate to Dashboard to update header if (onUserUpdate) { onUserUpdate({ photo_url: newPhotoUrl, profile_photo: newPhotoUrl }); } }} token={token} />

{profile.name}

📧 {profile.email}

Member since {new Date(profile.created_at).toLocaleDateString()}
{/* Discovery Info Card */}

🔍 Discovery Info

{/* Username Section */}
{!editing.username && ( )}
{editing.username ? (
@ setFormData({ ...formData, username: e.target.value })} placeholder="yourusername" className="form-input" style={{ flex: 1, padding: '0.5rem', fontSize: '16px' }} />

3-30 characters, letters, numbers, underscores. Can change once per 30 days.

) : (
{profile.username ? `@${profile.username}` : ( Not set - Click Edit to choose )}
)}
{/* Share Code Section */}
NV-{profile.share_code}

Share this code for quick connections.

{/* Profile Link Section */} {profile.username && (
)}
{/* Bio Card */}

📝 Bio

{!editing.bio && ( )}
{editing.bio ? (