Skip to content

Commit

Permalink
Merge pull request #24 from Sopo2023/orgin/feat/Profile/#15
Browse files Browse the repository at this point in the history
Orgin/feat/profile/#15
  • Loading branch information
kyumin7487 authored Sep 9, 2024
2 parents b2d57eb + c84d58d commit cf5de48
Show file tree
Hide file tree
Showing 26 changed files with 1,095 additions and 47 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ config
npm-debug.log*
yarn-debug.log*
yarn-error.log*

.idea
50 changes: 50 additions & 0 deletions src/assets/imgs/profile/Empty.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/imgs/profile/Lock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/imgs/profile/delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/imgs/profile/write.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 34 additions & 10 deletions src/components/home/profile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
import React from "react";

const Profile =()=>{
return(
<>

</>
)
}
export default Profile;
import React, { useState } from "react";
import Profile from "src/components/home/profile/profile";
import ProfileEdit from "src/components/home/profile/profileEdit";
import ProfileSetting from "src/components/home/profile/profileSetting";
import Layout from "src/components/common/layout/layout";

const MainProfile: React.FC = () => {
const [isEditing, setIsEditing] = useState(false);
const [isSetting, setIsSetting] = useState(false);

const handleEditToggle = () => {
setIsEditing(!isEditing);
setIsSetting(false);
};

const handleSettingToggle = () => {
setIsSetting(!isSetting);
setIsEditing(false);
};

return (
<Layout>
{isEditing ? (
<ProfileEdit onCancel={handleEditToggle} />
) : isSetting ? (
<ProfileSetting onCancel={handleSettingToggle} />
) : (
<Profile onEdit={handleEditToggle} onSetting={handleSettingToggle} />
)}
</Layout>
);
};

export default MainProfile;
60 changes: 60 additions & 0 deletions src/components/home/profile/profile/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useState } from "react";
import * as S from "./style";
import AvatarImg from "src/assets/imgs/header/AvatarImg.svg";
import Pencil from "src/assets/imgs/profile/write.svg";
import Empty from "src/assets/imgs/profile/Empty.svg";
import { useGetProfileList } from "src/queries/profile/profile.query";
import { renderEmptyMessage } from "src/utils/profile/renderEmptyMessage";

interface ProfileProps {
onEdit: () => void;
onSetting: () => void;
}

const Profile: React.FC<ProfileProps> = ({ onEdit, onSetting }) => {
const [selected, setSelected] = useState(0);
const { data } = useGetProfileList();

const handleSelect = (index: number) => {
setSelected(index);
};

return (
<S.profileWrap>
<S.mainWrap>
<S.TitleWrap>
<S.AvatarContainer>
<S.Avatar src={AvatarImg} alt="프로필 이미지" />
<S.PencilIconContainer>
<S.PencilIcon src={Pencil} alt="편집 아이콘" />
</S.PencilIconContainer>
</S.AvatarContainer>
<S.ProfileInfo>
<S.UserName>{data?.data.memberName}</S.UserName>
<S.ButtonContainer>
<S.EditButton onClick={onEdit}>프로필 수정</S.EditButton>
<S.SettingsButton onClick={onSetting}>프로필 설정</S.SettingsButton>
</S.ButtonContainer>
</S.ProfileInfo>
</S.TitleWrap>
<S.SelectWrap>
{["선배가 후배에게", "포트폴리오", "대회", "북마크"].map((text, index) => (
<S.Span
key={index}
isSelected={selected === index}
onClick={() => handleSelect(index)}
>
{text}
</S.Span>
))}
</S.SelectWrap>
<S.emptyWrap>
<img src={Empty} alt="빈 이미지"/>
<span>{renderEmptyMessage(selected)}</span>
</S.emptyWrap>
</S.mainWrap>
</S.profileWrap>
);
};

export default Profile;
151 changes: 151 additions & 0 deletions src/components/home/profile/profile/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import styled from 'styled-components';

export const profileWrap = styled.main`
display: flex;
flex-direction: column;
margin-top: 4.44vh;
width: 100%;
height: calc(100% - 4.44vh);
align-items: center;
justify-content: center;
`;

export const mainWrap = styled.main`
width: 72vw;
height: 80vh;
border-radius: 13px;
background: #fff;
box-shadow: 0px 3px 9px 0px rgba(0, 0, 0, 0.12);
display: flex;
flex-direction: column;
align-items: center;
padding: 15px;
`;

export const TitleWrap = styled.div`
display: flex;
align-items: center;
width: 100%;
height: 10vh;
margin-top: 4vh;
padding-left: 5vw;
`;

export const AvatarContainer = styled.div`
position: relative;
margin-right: 1.25rem;
`;

export const Avatar = styled.img`
width: 5rem;
height: 5rem;
border-radius: 50%;
`;

export const ProfileInfo = styled.div`
display: flex;
flex-direction: column;
`;

export const UserName = styled.h2`
font-size: 1.5em;
font-weight: bold;
margin: 0;
`;

export const ButtonContainer = styled.div`
margin-top: 0.5rem;
display: flex;
gap: 0.5rem;
`;

export const EditButton = styled.button`
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
padding: 0.5rem 1rem;
cursor: pointer;
&:hover {
background-color: #45a049;
}
`;

export const SettingsButton = styled.button`
background-color: #F3F3F3;
color: #1A9A18;
border: none;
border-radius: 5px;
padding: 0.5rem 1rem;
cursor: pointer;
&:hover {
background-color: #EEEEEE;
}
`;

export const PencilIconContainer = styled.div`
background-color: #178415;
width: 1.7rem;
height: 1.7rem;
border-radius: 50%;
position: absolute;
bottom: 0.18rem;
right: 0;
display: flex;
align-items: center;
justify-content: center;
`;

export const PencilIcon = styled.img`
width: 1rem;
height: 1rem;
cursor: pointer;
z-index: 1;
`;

export const SelectWrap = styled.div`
width: 100%;
height: 10vh;
display: flex;
align-items: center;
padding-left: 0.1vw;
`;

export const Span = styled.span<{ isSelected: boolean }>`
cursor: pointer;
position: relative;
color: ${({ isSelected }) => (isSelected ? "#178415" : "#808080")};
font-weight: ${({ isSelected }) => (isSelected ? "bold" : "normal")};
font-size: 20px;
margin-left: 50px;
&::after {
content: '';
position: absolute;
bottom: -5px;
left: 0;
width: ${({ isSelected }) => (isSelected ? "100%" : "0")};
height: 2px;
background: #136D11;
transition: width 0.4s;
}
`;

export const emptyWrap = styled.div`
display: flex;
flex-direction: column;
align-items: center;
margin-top: 6rem;
text-align: center;
img {
margin-bottom: 1.5rem;
}
span {
color: #808080;
font-size: 1.5rem;
}
`;
91 changes: 91 additions & 0 deletions src/components/home/profile/profileEdit/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React from "react";
import * as S from "src/components/home/profile/profileEdit/style";
import ReturnImg from "src/assets/imgs/profile/delete.svg";
import AvatarImg from "src/assets/imgs/header/AvatarImg.svg";
import Pencil from "src/assets/imgs/profile/write.svg";
import Modal from "src/components/home/profile/profileEdit/profileCorrection/index";
import useProfileEdit from "src/hooks/profile/useProfileEdit";

interface ProfileEditProps {
onCancel: () => void;
}

const ProfileEdit: React.FC<ProfileEditProps> = ({ onCancel }) => {
const {
data,
isModalOpen,
currentField,
currentValue,
handleEditClick,
handleSave,
setIsModalOpen,
} = useProfileEdit();

return (
<S.ProfileWrap>
<S.MainWrap>
<S.TitleWrap>
<S.AvatarContainer>
<S.Avatar src={AvatarImg} alt="프로필 이미지" />
<S.PencilIconContainer>
<S.PencilIcon src={Pencil} alt="편집 아이콘" />
</S.PencilIconContainer>
</S.AvatarContainer>
<S.ProfileInfo>
<S.UserName>{data?.data.memberId}</S.UserName>
</S.ProfileInfo>
<S.ReturnIcon src={ReturnImg} alt="돌아가기 이미지" onClick={onCancel} />
</S.TitleWrap>
<S.DetailWrap>
<S.SectionTitle>기본정보</S.SectionTitle>
<S.Detail>
<S.DetailLabel>학교</S.DetailLabel>
<S.DetailContainer>
<S.DetailValue>{data?.data.memberSchool}</S.DetailValue>
<S.EditButton onClick={() => handleEditClick("학교", data?.data.memberSchool || "학교 정보가 존재하지 않습니다.")}>
수정
</S.EditButton>
</S.DetailContainer>
</S.Detail>
<S.Detail>
<S.DetailLabel>이름</S.DetailLabel>
<S.DetailContainer>
<S.DetailValue>{data?.data.memberName}</S.DetailValue>
<S.EditButton onClick={() => handleEditClick("이름", data?.data.memberName || "이름이 올바르지 않습니다.")}>
수정
</S.EditButton>
</S.DetailContainer>
</S.Detail>
<S.Detail>
<S.DetailLabel>이메일</S.DetailLabel>
<S.DetailContainer>
<S.DetailValue>{data?.data.memberEmail}</S.DetailValue>
<S.EditButton onClick={() => handleEditClick("이메일", data?.data.memberEmail || "이메일이 존재하지 않습니다.")}>
수정
</S.EditButton>
</S.DetailContainer>
</S.Detail>
<S.Detail>
<S.DetailLabel>비밀번호</S.DetailLabel>
<S.DetailContainer>
<S.DetailValue>**********</S.DetailValue>
<S.EditButton onClick={() => handleEditClick("비밀번호", "**********")}>
수정
</S.EditButton>
</S.DetailContainer>
</S.Detail>
</S.DetailWrap>
</S.MainWrap>

<Modal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
title={`${currentField}`}
value={currentValue}
onSave={handleSave}
/>
</S.ProfileWrap>
);
};

export default ProfileEdit;
Loading

0 comments on commit cf5de48

Please sign in to comment.