Skip to content

Commit

Permalink
Merge pull request #61 from HYF-Class19/profilepage
Browse files Browse the repository at this point in the history
Profilepage
  • Loading branch information
podnesTaF authored Apr 9, 2023
2 parents 6af2d06 + e1d19cf commit 0986d11
Show file tree
Hide file tree
Showing 9 changed files with 359 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/components/profile/ChangePasswordForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import { Button, Container, Typography } from "@mui/material";
import { useForm, FormProvider } from "react-hook-form";
import { FormField } from "@/components/shared/FormField";

export interface ChangePasswordFormData {
oldPassword: string;
newPassword: string;
confirmNewPassword: string;
}

interface ChangePasswordFormProps {
onSubmit: (data: ChangePasswordFormData) => void;
}

const ChangePasswordForm: React.FC<ChangePasswordFormProps> = ({ onSubmit }) => {
const methods = useForm<ChangePasswordFormData>();

return (
<Container maxWidth="sm">
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<Typography variant="h6" sx={{ marginBottom: 1 }}>
Change Password
</Typography>
<FormField name="oldPassword" label="Old Password" type="password" />
<FormField name="newPassword" label="New Password" type="password" />
<FormField
name="confirmNewPassword"
label="Confirm New Password"
type="password"
/>
<Button
variant="contained"
color="warning"
type="submit"
sx={{ display: "block", margin: "0 auto", marginTop: 5 }}
>
Change
</Button>
</form>
</FormProvider>
</Container>
);
};

export default ChangePasswordForm;
46 changes: 46 additions & 0 deletions src/components/profile/EditableText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { useState } from "react";
import { Box, IconButton, InputBase, Typography } from "@mui/material";
import { Edit, Check } from "@mui/icons-material";

interface EditableTextProps {
label: string;
onSubmit: (value: string) => void;
placeholder: string;
}

const EditableText: React.FC<EditableTextProps> = ({
label,

onSubmit,
placeholder,
}) => {
const [value, setValue] = useState("");
const [isEditable, setIsEditable] = useState(false);

const handleIconClick = () => {
if (isEditable) {
onSubmit(value);
}
setIsEditable(!isEditable);
};

return (
<Box sx={{ display: "flex", alignItems: "center", color: "#FFFFFF" }}>
<Typography sx={{ marginRight: 1 }}>{label}:</Typography>
<InputBase
value={value}
onChange={(e) => setValue(e.target.value)}
readOnly={!isEditable}
multiline
placeholder={placeholder}
inputProps={{ style: { borderBottom: isEditable ? "2px solid blue" : "1px solid #F3FB8C" } }}
sx= { {color: isEditable ? "blue" : "#FFFFFF" } }
/>
<IconButton size="small" onClick={handleIconClick}>
{isEditable ? <Check /> : <Edit />}
</IconButton>
</Box>
);
};

export default EditableText;
78 changes: 78 additions & 0 deletions src/components/profile/ProfileInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React, { useState } from "react";
import { Box, TextField, Typography } from "@mui/material";
import { PersonOutline, PhoneIphone, EmailOutlined } from "@mui/icons-material";
import EditableText from "./EditableText";
import { FormField } from "../shared/FormField";

interface ProfileInfoProps {
name: string;
bio: string;
setBio: (bio: string) => void;
phoneNumber: string;
setPhoneNumber: (phoneNumber: string) => void;
email: string;
setEmail: (email: string) => void;
}

const ProfileInfo: React.FC<ProfileInfoProps> = ({
name,
bio,
setBio,
phoneNumber,
setPhoneNumber,
email,
setEmail,
}) => {
return (
<div>
<Typography variant="h2">{name}</Typography>
<TextField
name="bio"
label="Bio"
value={bio}
onChange={(e) => setBio(e.target.value)}
multiline
rows={4}
variant="outlined"
sx={{
color: "#fffff",
margin: 2,
width: "100%",
"& .MuiOutlinedInput-notchedOutline": {
borderColor: "transparent",
},
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "transparent",
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: "transparent",
},
}}
/>
<Box sx={{ display: "flex", alignItems: "center" , marginBottom: "2", justifyContent: "space-between"}}>
<PhoneIphone sx={{ margin: 3 }} />
<EditableText
label="Phone"
onSubmit={(value) => setPhoneNumber(value)}
placeholder="Enter your phone number..."
/>
</Box>

<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between"}}>
<EmailOutlined sx={{ margin: 3 , "&:hover .icon": {
visibility: "visible",
opacity: 1,
}}} />
<EditableText
label="Email"
onSubmit={(value) => setEmail(value)}
placeholder="Enter your email..."
/>
</Box>


</div>
);
};

export default ProfileInfo;
26 changes: 26 additions & 0 deletions src/components/profile/SideMenuButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react";
import { Button } from "@mui/material";
import EditIcon from "@mui/icons-material/Edit";
import LockIcon from "@mui/icons-material/Lock";


interface SideMenuButtonProps {
showForm: boolean;
onClick: () => void;
}

const SideMenuButton: React.FC<SideMenuButtonProps> = ({ showForm, onClick }) => {
return (
<Button
variant="contained"
color="warning"
onClick={onClick}
endIcon={showForm ? <LockIcon /> : <EditIcon />}
>
{showForm ? "Profile" : "Lock"}
</Button>

);
};

export default SideMenuButton;
12 changes: 12 additions & 0 deletions src/components/profile/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import { Avatar } from "@mui/material";

interface ProfileAvatarProps {
src: string;
}

const ProfileAvatar: React.FC<ProfileAvatarProps> = ({ src }) => {
return <Avatar alt="Profile Picture" src={src} sx={{ width: 180, height: 180 }} />;
};

export default ProfileAvatar;
31 changes: 31 additions & 0 deletions src/components/profile/customButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";
import { Button } from "@mui/material";
import { Lock, Add } from "@mui/icons-material";

interface SideMenuButtonProps {
onClick: () => void;
showForm: boolean;
}

const SideMenuButton: React.FC<SideMenuButtonProps> = ({ onClick, showForm }) => {
return (
<Button
variant="contained"
color="primary"
onClick={onClick}
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
height: "100%",
width: "100%",
}}
>
{showForm ? <Add /> : <Lock />}
{showForm ? "Profile" : "Change Password"}
</Button>
);
};

export default SideMenuButton;
25 changes: 25 additions & 0 deletions src/components/profile/mainContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import { Card, CardContent } from "@mui/material";

interface MainContentProps {
children: React.ReactNode;
}

const MainContent: React.FC<MainContentProps> = ({ children }) => {
return (
<Card
sx={{
height:'80vh',
backgroundColor: '#19053B',
color: '#ffffff',
border: 1,
marginLeft: 2,
marginTop: 2,
}}
>
<CardContent>{children}</CardContent>
</Card>
);
};

export default MainContent;
9 changes: 9 additions & 0 deletions src/components/shared/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {deleteUserData, selectUserData} from "@/store/slices/userSlice";
import {useAppDispatch} from "@/hooks/useAppHooks";
import {destroyCookie} from "nookies";
import {useRouter} from "next/router";
import { Box, Avatar, Typography } from '@mui/material';

const Header = () => {
const userData = useSelector(selectUserData);
Expand Down Expand Up @@ -36,6 +37,14 @@ const Header = () => {
<li>
<Link onClick={logout} href={'/'}>{userData.fullName} Logout</Link>
</li>
<li>
<Link href={'/profile'}>
<Box sx={{display: 'flex', flexDirection: 'row', alignItems:'center' }}>
<Avatar />
<Typography style={{paddingLeft:"5px" }}>Helen</Typography>
</Box>
</Link>
</li>
</ul>
) : (
<ul>
Expand Down
85 changes: 85 additions & 0 deletions src/pages/profile/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useState } from "react";
import { Box, Grid, colors } from "@mui/material";
import MainLayout from "@/layouts/MainLayout";
import { NextPage } from "next";
import ProfileAvatar from "@/components/profile/avatar";
import ProfileInfo from "@/components/profile/ProfileInfo";
import ChangePasswordForm , { ChangePasswordFormData} from "@/components/profile/ChangePasswordForm";
import SideMenuButton from "@/components/profile/SideMenuButton";
import MainContent from "@/components/profile/mainContent";

const Profile: NextPage = () => {
const [showChangePasswordForm, setShowChangePasswordForm] = useState(false);
const handleButtonClick = () => {
setShowChangePasswordForm(!showChangePasswordForm);
};

const onSubmit = (data: ChangePasswordFormData) => {
console.log(data);
};

const [bio, setBio] = useState("Software Developer");
const [phoneNumber, setPhoneNumber] = useState("123-456-7890");
const [email, setEmail] = useState("[email protected]");

return (
<MainLayout>
<Box sx={{ bgcolor: '#120428' }}>

<Grid container>
<Grid item xs={1}>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100vh",
}}
>
<SideMenuButton
showForm={showChangePasswordForm}
onClick={handleButtonClick}
/>
</Box>
</Grid>
<Grid item xs={11}>
<MainContent>
{!showChangePasswordForm && (
<>
<Box
sx={{
display: "flex",
alignItems: "center",
alignContent: "center",
justifyContent: "space-evenly",
flexDirection: "row",
marginTop: 5,
}}
>
<ProfileAvatar src={""} />
<ProfileInfo
name="John Doe"
bio={bio}
setBio={setBio}
phoneNumber={phoneNumber}
setPhoneNumber={setPhoneNumber}
email={email}
setEmail={setEmail}
/>
</Box>
</>
)}
{showChangePasswordForm && (
<ChangePasswordForm
onSubmit={onSubmit}
/>
)}
</MainContent>
</Grid>
</Grid>
</Box>
</MainLayout>
);
};

export default Profile;

0 comments on commit 0986d11

Please sign in to comment.