'use client'; import React, { useState, ReactElement } from 'react'; import { Container, Paper, Tabs, Stack, Title, Text, Avatar, Group, TextInput, Button, PasswordInput, Alert, Box, rem, } from '@mantine/core'; import { IconUser, IconLock, IconSettings, IconAlertCircle, IconCheck, } from '@tabler/icons-react'; import { useForm } from '@mantine/form'; import { UserProfileProps, UserProfilePageProps } from './UserProfile.types'; import { useUser } from '../../hooks/useUser'; import { notifications } from '@mantine/notifications'; // Sub-component for custom pages function Page({ label, labelIcon, children }: UserProfilePageProps) { return
{children}
; } export function UserProfile({ appearance, children, className, style, }: UserProfileProps) { const { user, refreshUser } = useUser(); const [activeTab, setActiveTab] = useState('profile'); const [loading, setLoading] = useState(false); // Extract custom pages from children const customPages: Array<{ label: string; icon?: ReactNode; content: ReactNode }> = []; if (children) { React.Children.forEach(children, (child) => { if (React.isValidElement(child) && child.type === Page) { const pageProps = child.props as UserProfilePageProps; customPages.push({ label: pageProps.label, icon: pageProps.labelIcon, content: pageProps.children, }); } }); } const profileForm = useForm({ initialValues: { displayName: user?.displayName || '', email: user?.email || '', }, }); const passwordForm = useForm({ initialValues: { currentPassword: '', newPassword: '', confirmPassword: '', }, validate: { newPassword: (value) => { if (!value) return 'New password is required'; if (value.length < 8) return 'Password must be at least 8 characters'; return null; }, confirmPassword: (value, values) => value !== values.newPassword ? 'Passwords do not match' : null, }, }); const handleProfileUpdate = async (values: any) => { setLoading(true); try { // Update profile logic here await refreshUser(); notifications.show({ title: 'Profile updated', message: 'Your profile has been updated successfully', color: 'green', icon: , }); } catch (error: any) { notifications.show({ title: 'Update failed', message: error.message || 'Failed to update profile', color: 'red', icon: , }); } finally { setLoading(false); } }; const handlePasswordUpdate = async (values: any) => { setLoading(true); try { // Update password logic here notifications.show({ title: 'Password updated', message: 'Your password has been updated successfully', color: 'green', icon: , }); passwordForm.reset(); } catch (error: any) { notifications.show({ title: 'Update failed', message: error.message || 'Failed to update password', color: 'red', icon: , }); } finally { setLoading(false); } }; if (!user) { return null; } const displayName = user.displayName || user.email?.split('@')[0] || 'User'; const avatarUrl = user.photoURL || undefined; const initials = displayName .split(' ') .map(n => n[0]) .join('') .toUpperCase() .slice(0, 2); return ( {!avatarUrl && initials}
{displayName} {user.email}
}> Profile }> Security {customPages.map((page, index) => ( {page.label} ))}
{customPages.map((page, index) => ( {page.content} ))}
); } // Attach sub-component UserProfile.Page = Page;