Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Week14] 김하늘 #510

15 changes: 6 additions & 9 deletions components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import { Container, Copy, Info, Sns } from "@/components/Footer/Footer.styled";
import { Dom } from "@/hooks/useObserver";
import { SetRefForObserver } from "@/hooks/useObserver";
import Image from "next/image";
import Link from "next/link";
import { memo } from "react";

interface Props {
dom?: React.MutableRefObject<Dom>;
setRefForObserver?: SetRefForObserver;
}

export default function Footer({ dom }: Props) {
export default memo(function Footer({ setRefForObserver }: Props) {
return (
<Container
ref={(el) => {
dom && (dom.current.footer = el);
}}
>
<Container ref={setRefForObserver}>
<Copy>©codeit - 2023</Copy>
<Info>
<Link href="/privacy">Privacy Policy</Link>
Expand All @@ -35,4 +32,4 @@ export default function Footer({ dom }: Props) {
</Sns>
</Container>
);
}
});
19 changes: 8 additions & 11 deletions components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import defaultAvatar from "@/public/Avatar.png";
import useData from "@/hooks/useData";
import { Container, User, UserImg, UserText, UserTitle } from "@/components/Header/Header.styled";
import { URLS } from "@/utils/getData.type";
import { PATHS } from "@/constants/path";

export default function Header() {
const folderName = useData(URLS.SHARED_FOLDERNAME);
const folderName = useData(PATHS.SHARED_FOLDERNAME);
if (!folderName) {
return null;
}

return (
<Container>
<User>
{folderName ? (
<>
<UserImg src={folderName.owner.profileImageSource ?? defaultAvatar} alt="유저 프로필 이미지" />
<UserText>{folderName.owner.name}</UserText>
<UserTitle>{folderName.folderName}</UserTitle>
</>
) : (
<p>폴더 정보를 읽어오는 데 실패했습니다.</p>
)}
<UserImg src={folderName.owner.profileImageSource ?? defaultAvatar.src} alt="유저 프로필 이미지" />
<UserText>{folderName.owner.name}</UserText>
<UserTitle>{folderName.folderName}</UserTitle>
</User>
</Container>
);
Expand Down
41 changes: 17 additions & 24 deletions components/Header/HeaderInput.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
import { useState } from "react";
import { Float, Form, Input, InputButton, InputImg, InputWrapper } from "@/components/Header/HeaderInput.styled";
import { PATHS } from "@/constants/path";
import useData from "@/hooks/useData";
import useModal from "@/hooks/useModal";
import { Dom } from "@/hooks/useObserver";
import { URLS } from "@/utils/getData.type";
import { SetRefForObserver } from "@/hooks/useObserver";
import { ChangeEvent, FormEvent, memo, useState } from "react";

interface Props {
id: number;
dom: React.MutableRefObject<Dom>;
setRefForObserver: SetRefForObserver;
}

export default function HeaderSearch({ id, dom }: Props) {
const folder = useData(URLS.FOLDER_CATEGORY, id);
export default memo(function HeaderSearch({ id, setRefForObserver }: Props) {
const folder = useData(PATHS.FOLDER_CATEGORY, id);
const { modal, dispatch } = useModal();
const [value, setValue] = useState("");

const handleModal = (e: React.FormEvent) => {
const handleModal = (e: FormEvent) => {
e.preventDefault();
if (folder?.path === URLS.FOLDER_CATEGORY) {
dispatch({ title: value, type: "추가하기", data: folder.data });
}
dispatch({ title: value, type: "추가하기", data: folder.data });
};

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target === dom.current.headerInput) {
const input = dom.current.headerInput as HTMLInputElement;
setValue(input.value);
}
if (e.target === dom.current.floatInput) {
const input = dom.current.floatInput as HTMLInputElement;
setValue(input.value);
}
const handleChange = (e: ChangeEvent) => {
const input = e.target as HTMLInputElement;
setValue(input.value);
};

return (
<>
<Form ref={(el) => (dom.current.headerForm = el)} onSubmit={handleModal}>
<Input ref={(el) => (dom.current.headerInput = el)} value={value} onChange={handleChange} placeholder="링크를 추가해보세요." />
<Form ref={setRefForObserver} onSubmit={handleModal}>
<Input ref={setRefForObserver} value={value} onChange={handleChange} placeholder="링크를 추가해보세요." />
<InputWrapper>
<InputImg src="/link.svg" />
<InputButton>추가하기</InputButton>
</InputWrapper>
<Float ref={(el) => (dom.current.floatDiv = el)}>
<Input ref={(el) => (dom.current.floatInput = el)} value={value} onChange={handleChange} placeholder="링크를 추가해보세요." />
<Float ref={setRefForObserver}>
<Input ref={setRefForObserver} value={value} onChange={handleChange} placeholder="링크를 추가해보세요." />
Comment on lines +36 to +37
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 input은 어디에 사용되는건가요? 화면에도 출력되지 않아보이네요.

<InputWrapper>
<InputImg src="/link.svg" />
<InputButton>추가하기</InputButton>
Expand All @@ -51,4 +44,4 @@ export default function HeaderSearch({ id, dom }: Props) {
{modal}
</>
);
}
});
11 changes: 4 additions & 7 deletions components/Header/index/HomeHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { CutLine, StyledHeader, StyledImage, Title, WrapperLink } from "@/components/Header/index/HomeHeader.styled";
import Link from "next/link";
import { useEffect } from "react";

let locate = "/folder";
import { useRef } from "react";

export default function HomeHeader() {
const locate = useRef("/signin");
const accessToken = typeof window !== "undefined" ? sessionStorage.getItem("accessToken") : null;
if (accessToken) {
locate = `/folder?a=${accessToken}`;
locate.current = `/folder`;
}
Comment on lines +6 to 10
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useRef를 이용하여 locate 값을 설정하고 있지만, useEffect나 조건부 렌더링을 활용하여 해당 값의 설정을 컴포넌트 마운트 이후에 하는 것이 좋을 수 있습니다.
컴포넌트 렌더링 사이클을 분리할 수 있어 코드가 더 명확해지거든요.

아래 return 구문의 <>는 제거해도 괜찮겠네요~


return (
Expand All @@ -22,9 +21,7 @@ export default function HomeHeader() {
<p>구경 해보기</p>
<Link href="/shared">폴더 공유하기</Link>
<CutLine />
<Link href={locate} as="/folder">
링크 추가하기
</Link>
<Link href={locate.current}>링크 추가하기</Link>
</WrapperLink>
<StyledImage priority width={1} height={1} src="index/_img.svg" alt="링크검색기능 예시이미지" />
</StyledHeader>
Expand Down
92 changes: 0 additions & 92 deletions components/Main/Card/CardList.tsx

This file was deleted.

41 changes: 41 additions & 0 deletions components/Main/CardList/Card.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import styled from "styled-components";

export const WrapperCardImg = styled.div`
height: 20.5rem;
margin: 0 auto;
overflow: hidden;
border-top-right-radius: 1.5rem;
border-top-left-radius: 1.5rem;
`;

export const CardImg = styled.img`
width: 34rem;
height: 100%;
border-radius: 1.5rem 1.5rem 0 0;
object-fit: cover;
`;

export const CardText = styled.div`
display: flex;
flex-direction: column;
height: 13.5rem;
padding: 1.5rem 2rem;
gap: 1rem;
`;

export const WrapperTime = styled.div`
display: flex;
justify-content: space-between;
font-size: 1.2rem;
color: var(--Gray5);
`;

export const H3 = styled.h3`
font-size: 1.4rem;
`;

export const ButtonStar = styled.button`
position: absolute;
top: 1.5rem;
right: 1.5rem;
`;
29 changes: 29 additions & 0 deletions components/Main/CardList/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ButtonStar, CardImg, CardText, H3, WrapperCardImg, WrapperTime } from "@/components/Main/CardList/Card.styled";
import { CardProps } from "@/components/Main/CardList/CardList.type";
import Kebab from "@/components/Main/CardList/Kebab";
import TimeFlow from "@/components/Main/CardList/TimeFlow";
import { formatDate } from "@/utils/filterAndData";
import Image from "next/image";
import starImg from "@/public/star.svg";

export default function Card({ folder, url, imageSource, image_source, title, description, createdAt, created_at }: CardProps) {
return (
<>
<WrapperCardImg>
<CardImg src={imageSource || image_source || "/nofileimg.png"} alt="카드 이미지" />
</WrapperCardImg>
<CardText>
<WrapperTime>
<TimeFlow createdAt={createdAt ?? (created_at as string)} />
{folder && <Kebab folder={folder} url={url} />}
</WrapperTime>
<H3>{title?.length > 40 ? title.slice(0, 40) + "..." : title}</H3>
<p>{description?.length > 50 ? description.slice(0, 50) + "..." : description}</p>
<p>{formatDate(createdAt ?? (created_at as string))}</p>
Comment on lines +13 to +22
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

내부에 연산 값이 많아 가독성을 헤칩니다. 상단 변수로 올려서 computed하게 변수를 만들어 사용하는 것을 추천드려요.

</CardText>
<ButtonStar>
<Image src={starImg} alt="즐겨찾기에 추가하기" />
</ButtonStar>
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CardImg } from "@/components/Main/CardList/Card.styled";
import styled from "styled-components";

export const Absolute = styled.div`
Expand All @@ -23,29 +24,6 @@ export const ContainerCardList = styled.div`
}
`;

export const WrapperCardImg = styled.div`
height: 20.5rem;
margin: 0 auto;
overflow: hidden;
border-top-right-radius: 1.5rem;
border-top-left-radius: 1.5rem;
`;

export const CardImg = styled.img`
width: 34rem;
height: 100%;
border-radius: 1.5rem 1.5rem 0 0;
object-fit: cover;
`;

export const CardText = styled.div`
display: flex;
flex-direction: column;
height: 13.5rem;
padding: 1.5rem 2rem;
gap: 1rem;
`;

export const CardLink = styled.a`
position: relative;
display: flex;
Expand All @@ -62,23 +40,6 @@ export const CardLink = styled.a`
}
`;

export const WrapperTime = styled.div`
display: flex;
justify-content: space-between;
font-size: 1.2rem;
color: var(--Gray5);
`;

export const H3 = styled.h3`
font-size: 1.4rem;
`;

export const ButtonStar = styled.button`
position: absolute;
top: 1.5rem;
right: 1.5rem;
`;

export const EmptyBox = styled.div`
display: flex;
justify-content: center;
Expand Down
Loading