253 lines
5.7 KiB
TypeScript
253 lines
5.7 KiB
TypeScript
import { useEffect, useState, useMemo } from "react";
|
|
import {
|
|
Container,
|
|
Typography,
|
|
CircularProgress,
|
|
Card,
|
|
CardContent,
|
|
Grid,
|
|
Avatar,
|
|
Box,
|
|
Stack,
|
|
Divider,
|
|
Link,
|
|
} from "@mui/material";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { AppDispatch, RootState } from "../../redux/store/store";
|
|
import {
|
|
fetchAdminProfile,
|
|
updateProfile,
|
|
} from "../../redux/slices/profileSlice";
|
|
import EditIcon from "@mui/icons-material/Edit";
|
|
import EditProfileModal from "../../components/Modals/EditProfileModal/editProfileModal";
|
|
import { CustomIconButton } from "../../components/AddUserModal/styled.css";
|
|
|
|
const ProfilePage = () => {
|
|
const dispatch = useDispatch<AppDispatch>();
|
|
const { user, loading } = useSelector(
|
|
(state: RootState) => state.profileReducer
|
|
);
|
|
|
|
const [openEditModal, setOpenEditModal] = useState(false);
|
|
|
|
useEffect(() => {
|
|
dispatch(fetchAdminProfile());
|
|
}, [dispatch]);
|
|
|
|
const handleOpenEditModal = () => {
|
|
setOpenEditModal(true);
|
|
};
|
|
|
|
const handleClose = () => {
|
|
setOpenEditModal(false);
|
|
};
|
|
|
|
const handleUpdate = (
|
|
name: string,
|
|
phone: string,
|
|
bio?: string,
|
|
profilePhoto?: string | null
|
|
) => {
|
|
console.log("Dispatching updateProfile...");
|
|
dispatch(updateProfile({ name, phone, bio, profilePhoto }));
|
|
};
|
|
|
|
|
|
// Memoizing the user data for optimization
|
|
const displayUser = useMemo(
|
|
() => ({
|
|
name: user?.name || "N/A",
|
|
email: user?.email || "N/A",
|
|
phone: user?.phone || "N/A",
|
|
bio: user?.bio || "No bio available.",
|
|
userType: user?.userType || "N/A",
|
|
profilePhoto: user?.profilePhoto || "/avatar.png", // Default image path
|
|
}),
|
|
[user]
|
|
);
|
|
|
|
// Show loading indicator if data is being fetched
|
|
if (loading) {
|
|
return (
|
|
<Box
|
|
sx={{
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
height: "100vh",
|
|
}}
|
|
>
|
|
<CircularProgress />
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Container sx={{ py: 1 }}>
|
|
<Typography
|
|
variant="h4"
|
|
gutterBottom
|
|
sx={{ fontSize: "32px", fontWeight: 500, color: "#000000" }}
|
|
>
|
|
Account Info
|
|
</Typography>
|
|
<Card
|
|
sx={{
|
|
borderRadius: 2,
|
|
p: { xs: 2, sm: 3 },
|
|
mx: "auto",
|
|
backgroundColor: "#000000",
|
|
}}
|
|
>
|
|
<CardContent>
|
|
<Stack direction="column" spacing={2}>
|
|
<Stack
|
|
direction="row"
|
|
spacing={2}
|
|
alignItems="center"
|
|
position="relative"
|
|
>
|
|
<Box
|
|
position="relative"
|
|
sx={{
|
|
width: 60,
|
|
height: 60,
|
|
"&:hover .edit-icon": { opacity: 1 },
|
|
"&:hover .avatar-img": { opacity: 0.4 },
|
|
}}
|
|
>
|
|
<Avatar
|
|
alt="User Avatar"
|
|
src={displayUser.profilePhoto}
|
|
sx={{
|
|
width: 60,
|
|
height: 60,
|
|
transition: "opacity 0.3s",
|
|
}}
|
|
className="avatar-img"
|
|
/>
|
|
<CustomIconButton
|
|
onClick={handleOpenEditModal}
|
|
className="edit-icon"
|
|
sx={{
|
|
position: "absolute",
|
|
top: "50%",
|
|
left: "50%",
|
|
transform: "translate(-50%, -50%)",
|
|
color: "white",
|
|
opacity: 0,
|
|
transition: "opacity 0.3s",
|
|
}}
|
|
>
|
|
<EditIcon fontSize="small" />
|
|
</CustomIconButton>
|
|
</Box>
|
|
|
|
<Box>
|
|
<Typography
|
|
variant="body1"
|
|
sx={{ color: "#D0E1E9", fontWeight: 500 }}
|
|
>
|
|
{displayUser.name}
|
|
</Typography>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{ color: "#D9D8D8" }}
|
|
>
|
|
{displayUser.userType}
|
|
</Typography>
|
|
</Box>
|
|
</Stack>
|
|
|
|
<Divider
|
|
flexItem
|
|
sx={{ backgroundColor: "rgba(32, 32, 32, 0.5)" }}
|
|
/>
|
|
|
|
<Stack
|
|
direction={{ xs: "column", sm: "row" }}
|
|
justifyContent="space-between"
|
|
alignItems={{ xs: "flex-start", sm: "center" }}
|
|
>
|
|
<Typography
|
|
variant="body1"
|
|
sx={{
|
|
color: "#D0E1E9",
|
|
fontWeight: 500,
|
|
fontSize: "16px",
|
|
}}
|
|
>
|
|
Personal Information
|
|
</Typography>
|
|
<Link
|
|
component="button"
|
|
variant="body1"
|
|
color="#52ACDF"
|
|
onClick={handleOpenEditModal}
|
|
>
|
|
Edit
|
|
</Link>
|
|
</Stack>
|
|
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12} sm={4}>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{ color: "#D0E1E9", fontWeight: 500 }}
|
|
>
|
|
Full Name:
|
|
</Typography>
|
|
<Typography variant="body2" color="#D9D8D8">
|
|
{displayUser.name}
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={12} sm={4}>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{ color: "#D0E1E9", fontWeight: 500 }}
|
|
>
|
|
Phone:
|
|
</Typography>
|
|
<Typography variant="body2" color="#D9D8D8">
|
|
{displayUser.phone}
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={12} sm={4}>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{ color: "#D0E1E9", fontWeight: 500 }}
|
|
>
|
|
Email:
|
|
</Typography>
|
|
<Typography variant="body2" color="#D9D8D8">
|
|
{displayUser.email}
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={12} sm={4}>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{ color: "#D0E1E9", fontWeight: 500 }}
|
|
>
|
|
Bio:
|
|
</Typography>
|
|
<Typography variant="body2" color="#D9D8D8">
|
|
{displayUser.bio}
|
|
</Typography>
|
|
</Grid>
|
|
</Grid>
|
|
</Stack>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<EditProfileModal
|
|
open={openEditModal}
|
|
handleClose={handleClose}
|
|
handleUpdate={handleUpdate} // Passing the handleUpdate function to the modal
|
|
editUser={user} // Pass the current user to pre-fill the form in modal
|
|
/>
|
|
</Container>
|
|
);
|
|
};
|
|
|
|
export default ProfilePage;
|