'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;