import React, { useState } from 'react';
import {
Container,
Grid,
Card,
CardContent,
Typography,
Button,
Box,
TextField,
Avatar,
Divider,
Switch,
FormControlLabel,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Tab,
Tabs,
Paper,
List,
ListItem,
ListItemText,
ListItemSecondaryAction,
IconButton,
Chip,
} from '@mui/material';
import {
Edit,
Save,
Cancel,
Person,
Security,
Notifications,
Delete,
Visibility,
VisibilityOff,
} from '@mui/icons-material';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useForm, Controller } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import { useAuth } from '../../contexts/AuthContext';
import { usersAPI, notificationsAPI } from '../../services/api';
import { User, UserSettings } from '../../types';
import toast from 'react-hot-toast';
import { formatDistanceToNow } from 'date-fns';
const profileSchema = yup.object({
firstName: yup.string().required('Ad gereklidir').min(2, 'Ad en az 2 karakter olmalıdır'),
lastName: yup.string().required('Soyad gereklidir').min(2, 'Soyad en az 2 karakter olmalıdır'),
email: yup.string().required('E-posta gereklidir').email('Geçersiz e-posta formatı'),
});
const passwordSchema = yup.object({
currentPassword: yup.string().required('Mevcut şifre gereklidir'),
newPassword: yup.string().required('Yeni şifre gereklidir').min(6, 'Şifre en az 6 karakter olmalıdır'),
confirmPassword: yup.string()
.required('Şifre onayı gereklidir')
.oneOf([yup.ref('newPassword')], 'Şifreler eşleşmelidir'),
});
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
{value === index && {children}}
);
}
const ProfilePage: React.FC = () => {
const { user, updateProfile, changePassword } = useAuth();
const queryClient = useQueryClient();
const [tabValue, setTabValue] = useState(0);
const [editingProfile, setEditingProfile] = useState(false);
const [changePasswordDialogOpen, setChangePasswordDialogOpen] = useState(false);
const [showCurrentPassword, setShowCurrentPassword] = useState(false);
const [showNewPassword, setShowNewPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
// Fetch user settings
const { data: settingsData } = useQuery({
queryKey: ['userSettings'],
queryFn: () => usersAPI.getUserSettings(),
});
// Fetch user activities - temporarily disabled
// const { data: activitiesData } = useQuery({
// queryKey: ['userActivities'],
// queryFn: () => usersAPI.getUserActivities({ limit: 10 }),
// });
const activitiesData = { data: [] };
// Update profile mutation
const updateProfileMutation = useMutation({
mutationFn: (data: Partial) => updateProfile(data),
onSuccess: () => {
toast.success('Profil başarıyla güncellendi!');
setEditingProfile(false);
},
onError: (error: any) => {
toast.error(error.response?.data?.message || 'Profil güncellenemedi');
},
});
// Change password mutation
const changePasswordMutation = useMutation({
mutationFn: (data: { currentPassword: string; newPassword: string }) =>
changePassword(data.currentPassword, data.newPassword),
onSuccess: () => {
toast.success('Şifre başarıyla değiştirildi!');
setChangePasswordDialogOpen(false);
passwordReset();
},
onError: (error: any) => {
toast.error(error.response?.data?.message || 'Şifre değiştirilemedi');
},
});
// Update settings mutation with optimistic cache sync to avoid flicker
const updateSettingsMutation = useMutation({
mutationFn: (data: Partial) => usersAPI.updateUserSettings(data),
onSuccess: (res) => {
const serverSettings = (res?.data?.data?.settings ?? {}) as Partial;
// Update local state to the authoritative server value
setLocalSettings(serverSettings);
// Update the react-query cache so refetch won't revert UI
queryClient.setQueryData(['userSettings'], (prev: any) => {
if (!prev) return res;
try {
const next = {
...prev,
data: {
...prev.data,
data: {
...(prev?.data?.data || {}),
settings: serverSettings,
},
},
};
return next;
} catch {
return res;
}
});
toast.success('Ayarlar başarıyla güncellendi!');
},
onError: (error: any) => {
toast.error(error.response?.data?.message || 'Ayarlar güncellenemedi');
},
});
const {
control: profileControl,
handleSubmit: handleProfileSubmit,
reset: profileReset,
formState: { errors: profileErrors },
} = useForm({
resolver: yupResolver(profileSchema),
defaultValues: {
firstName: user?.firstName || '',
lastName: user?.lastName || '',
email: user?.email || '',
},
});
const {
control: passwordControl,
handleSubmit: handlePasswordSubmit,
reset: passwordReset,
formState: { errors: passwordErrors },
} = useForm({
resolver: yupResolver(passwordSchema),
defaultValues: {
currentPassword: '',
newPassword: '',
confirmPassword: '',
},
});
// Backend returns { success, data: { settings } }
const settings = (settingsData?.data?.data?.settings ?? {}) as Partial;
const [localSettings, setLocalSettings] = useState>({});
const activities = activitiesData?.data || [];
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
setTabValue(newValue);
};
const handleUpdateProfile = (data: any) => {
updateProfileMutation.mutate(data);
};
const handleChangePassword = (data: any) => {
changePasswordMutation.mutate({
currentPassword: data.currentPassword,
newPassword: data.newPassword,
});
};
const handleSettingChange = async (key: keyof UserSettings, value: boolean) => {
const previous = localSettings[key];
setLocalSettings((prev) => ({ ...prev, [key]: value }));
try {
await updateSettingsMutation.mutateAsync({ [key]: value } as Partial);
} catch (error) {
// Revert optimistic update on error
setLocalSettings((prev) => ({ ...prev, [key]: previous as boolean }));
}
};
React.useEffect(() => {
// Avoid overriding optimistic state while a mutation is pending
if (!updateSettingsMutation.isPending) {
setLocalSettings(settings);
}
}, [settings, updateSettingsMutation.isPending]);
React.useEffect(() => {
if (user) {
profileReset({
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
});
}
}, [user, profileReset]);
if (!user) {
return (
Yükleniyor...
);
}
return (
{/* Header */}
{user.firstName?.[0] || ''}{user.lastName?.[0] || ''}
{user.firstName || ''} {user.lastName || ''}
{user.email}
Üye olma tarihi: {new Date(user.createdAt).toLocaleDateString()}
{/* Tabs */}
} label="Profil" />
} label="Güvenlik" />
} label="Bildirimler" />
{/* Profile Tab */}
Kişisel Bilgiler
{!editingProfile ? (
}
onClick={() => setEditingProfile(true)}
>
Düzenle
) : (
}
onClick={() => {
setEditingProfile(false);
profileReset();
}}
sx={{ mr: 1 }}
>
İptal
}
onClick={handleProfileSubmit(handleUpdateProfile)}
disabled={updateProfileMutation.isPending}
>
Kaydet
)}
Son Aktiviteler
{activities.length === 0 ? (
Son aktivite bulunmuyor
) : (
activities.map((activity: any, index: number) => (
))
)}
{/* Security Tab */}
Şifre
Güçlü bir şifre kullanarak hesabınızı güvende tutun
Hesap Durumu
Hesap Durumu:
{/* Notifications Tab */}
Bildirim Tercihleri
Hangi bildirimleri almak istediğinizi seçin
handleSettingChange('emailNotifications', e.target.checked)}
/>
handleSettingChange('pushNotifications', e.target.checked)}
/>
handleSettingChange('itemUpdateNotifications', e.target.checked)}
/>
{/* Pazarlama E-postaları kaldırıldı */}
{/* Change Password Dialog */}
);
};
export default ProfilePage;