이번엔 사용자의 프로필을 만들어 볼겁니다.
profile.tsx로 가서 기본적인 폼을 작성합니다.
import styled from "styled-components";
import { auth } from "../firebase";
const Wrapper = styled.div`
`;
const AvatarUpload = styled.label``;
const AvatarImg = styled.img``;
const AvatarInput = styled.input`
display: none;
`;
const Name = styled.span``;
export default function Profile() {
const user = auth.currentUser;
return <Wrapper>
<AvatarUpload>
<AvatarImg/ >
</AvatarUpload>
<AvatarInput type="file" accept="image/*" />
<Name>
{user?.displayName ?? "Anonymous"}
</Name>
</Wrapper>;
}
만약 사용자의 이름이 없다면 Anonymous가 되도록 해줍니다.
이제 사용자의 이미지 여부를 확인하고 state에 저장해주는 작업을 할겁니다.
export default function Profile() {
const user = auth.currentUser;
const [avatar, serAvatar] = useState(user?.photoURL);
return <Wrapper>
<AvatarUpload>
<AvatarImg/ >
</AvatarUpload>
<AvatarInput type="file" accept="image/*" />
<Name>
{user?.displayName ?? "Anonymous"}
</Name>
</Wrapper>;
avatar를 useState로 만들어주고 photoURL로 넣어줍니다.
<AvatarUpload>
{avatar ? <AvatarImg src={avatar} /> : null}
</AvatarUpload>
avatar가 있다면 이미지를 넣지만 없다면 아이콘을 넣어주기위해 위와 같이 작성합니다.
null에는 heroicons.dev 나 다른 아이콘 플랫폼에서 코드를 복사, 붙여너힉 해주면 됩니다.
이후 css를 적용하고 결과를 보면
const Wrapper = styled.div`
display: flex;
align-items: center;
flex-direction: column;
gap: 20px;
`;
const AvatarUpload = styled.label`
width: 80px;
overflow: hidden;
height: 80px;
border-radius: 50%;
background-color: #1d9bf0;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
svg {
width: 50px;
}
`;
성공적으로 프로필이 만들어졌습니다.
이제 위 프로필을 누르면 숨겨진 input이 나오도록 할겁니다.
return <Wrapper>
<AvatarUpload htmlFor="avatar">
{avatar ? <AvatarImg src={avatar} /> : <svg fill="none" strokeWidth={1.5} stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
</svg>}
</AvatarUpload>
<AvatarInput id="avatar" type="file" accept="image/*" />
<Name>
{user?.displayName ?? "Anonymous"}
</Name>
</Wrapper>;
AvatarInput에 id를 걸어주고
AvatarUpload에 htmlFor로 avatar를 넣어주면
프로필 이미지를 클릭시 input 창이 뜨게 됩니다.
const AvatarImg = styled.img`
width: 100%;
`;
const AvatarInput = styled.input`
display: none;
`;
const Name = styled.span`
font-size: 22px;
`;
간단한 css도 적용해줍니다.
이제 이미지를 업로드하면 실시간으로 보이게 만들겁니다.
먼저 Avatar 함수를 만들겁니다.
const onAvatarChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const {files} = e.target;
if (files && files.length){
const file = files[0];
const locationRef = ref(storage, `avatars/${user?.uid}`)
}
};
우선 onChange를 만들어주고 아바타이미지는 avatars라는 폴더에 userID로 저장해줄겁니다. 이렇게 하면 바뀔때마다 덮어써줄겁니다.
<AvatarInput onChange={onAvatarChange} id="avatar" type="file" accept="image/*" />
AvatarInput에 onChange를 넣어주고,
const onAvatarChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const {files} = e.target;
if (!user) return;
if (files && files.length){
const file = files[0];
const locationRef = ref(storage, `avatars/${user?.uid}`);
const result = await uploadBytes(locationRef, file);
const avatarUrl = await getDownloadURL(result.ref);
setAvatar(avatarUrl);
await updateProfile(user, {
photoURL: avatarUrl,
});
}
};
위와 같이 작성해줍니다.
사진을 업로드하면, URL을 가져와주고
URL을 state에 할당하여 사용자의 Avatar가 바뀌게 됩니다.
브라우저로 가서 이미지를 업로드하면 실시간으로 바뀌게 되고 다른 이미지를 업로드해도 firebase의 storage에는 덮어쓰이게 됩니다.
'Front-end > twitter_clone' 카테고리의 다른 글
[트위터 클론코딩 챌랜지] Deploy_20 (0) | 2024.04.11 |
---|---|
[트위터 클론코딩 챌랜지] 자신의 게시물만 가져오기_19 (0) | 2024.04.08 |
[트위터 클론코딩 챌랜지] Edit 만들기_17 (0) | 2024.04.05 |
[트위터 클론코딩 챌랜지] 트윗 Delete_16 (0) | 2024.04.04 |
[트위터 클론코딩 챌랜지] 실시간 트윗 적용_15 (0) | 2024.04.04 |