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 ( ); } 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 ? ( ) : ( )}
( )} /> ( )} /> ( )} />
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 */} setChangePasswordDialogOpen(false)} maxWidth="sm" fullWidth > Şifre Değiştir
( setShowCurrentPassword(!showCurrentPassword)} edge="end" > {showCurrentPassword ? : } ), }} /> )} /> ( setShowNewPassword(!showNewPassword)} edge="end" > {showNewPassword ? : } ), }} /> )} /> ( setShowConfirmPassword(!showConfirmPassword)} edge="end" > {showConfirmPassword ? : } ), }} /> )} />
); }; export default ProfilePage;