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 #523

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import noImg from "@/src/image/noimg.svg";
import styled from "styled-components";
import { formatDate, getTimeDiff } from "../../utils/getTime";
import { formatDate, getTimeDiff } from "../../../utils/getTime";
import CardContent from "./CardContent";
import CardDate from "./CardDate";
import CardImage from "./CardImage";
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { LinksDataType, SampleLinksType } from "@/utils/types";
import { useEffect, useRef } from "react";
import styled from "styled-components";
import useGetLinks from "../../hooks/useGetLinks";
import useGetSampleLinks from "../../hooks/useGetSampleLinks";
import useGetLinks from "../../../hooks/useGetLinks";
import useGetSampleLinks from "../../../hooks/useGetSampleLinks";
import Card from "./Card";

interface CardListProps {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect, useRef, useState } from "react";
import styled from "styled-components";
import kebab from "@/src/image/kebab.svg";
import AddLinkModal from "../modal/AddLinkModal";
import DeleteLinkModal from "../modal/DeleteLinkModal";
import AddLinkModal from "../../modal/AddLinkModal";
import DeleteLinkModal from "../../modal/DeleteLinkModal";
import Image from "next/image";

interface KebabProps {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChangeEvent, FormEvent, useState } from "react";
import styled from "styled-components";
import linkIcon from "@/src/image/link.svg";
import AddLinkModal from "../modal/AddLinkModal";
import AddLinkModal from "../../modal/AddLinkModal";

interface HeaderAddLinkProps {
headerRef: React.RefObject<HTMLDivElement>;
Expand Down
76 changes: 76 additions & 0 deletions components/common/header/HeaderHome.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Image from "next/image";
import Link from "next/link";
import React from "react";
import styled from "styled-components";

import HeroImg from "@/src/image/hero.png";

const HeaderHome = () => (
<Header>
<MainHeader>
<MainTitle>
<MainTitleGradient>
<BackgroundClipText>세상의 모든 정보</BackgroundClipText>를<br />
<Span>쉽게 저장하고 </Span>
<Span>관리해 보세요</Span>
</MainTitleGradient>
</MainTitle>
<AddLinkButton href="signup" className="button add_link">
링크 추가하기
</AddLinkButton>
<MainImage src={HeroImg} alt="메인 이미지" className="main_image" />
</MainHeader>
</Header>
);

const Header = styled.header`
padding: 7rem 36rem 0 36rem;
background: #f0f6ff;
width: 100%;
`;

const MainHeader = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
gap: 4rem;
align-self: stretch;
`;

const MainTitle = styled.h1`
text-align: center;
font-size: 6.4rem;
font-weight: 700;
line-height: 8rem;
color: #000;
min-width: 708px;
`;

const MainTitleGradient = styled.span`
background-image: linear-gradient(91deg, #6d6afe 17.28%, #ff9f9f 74.98%);
`;

const BackgroundClipText = styled.span`
background-clip: text;
-webkit-background-clip: text;
color: transparent;
`;

const Span = styled.span``;

// const TitleBreakMiddle = styled.br`
// display: none;
// `;

const AddLinkButton = styled(Link)`
width: 35rem;
padding: 1.6rem 2rem;
`;

const MainImage = styled(Image)`
width: 120rem;
height: 59rem;
`;

export default HeaderHome;
8 changes: 4 additions & 4 deletions components/nav/Nav.tsx → components/common/nav/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import logo from "@/src/image/logo.svg";
import Image from "next/image";
import Link from "next/link";
import styled from "styled-components";
import useGetSampleUser from "../../hooks/useGetSampleUser";
import useGetUser from "../../hooks/useGetUser";
import useGetSampleUser from "@/hooks/useGetSampleUser";
import useGetUser from "@/hooks/useGetUser";
import NavLogin from "./NavLogin";
import NavProfile from "./NavProfile";

interface NavProps {
pageType: string;
pageType?: string;
Copy link
Collaborator

Choose a reason for hiding this comment

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

string 보단 유니온타입으로 타입을 명확하게 좁히는건 어떨까요?
타입스크립트에서는 되도록이면 타입을 좁히는게 좋습니다

pageType: "shared" | "..."

}

const Nav = ({ pageType }: NavProps) => {
const Nav = ({ pageType = "" }: NavProps) => {
const sharedUser = useGetSampleUser();
const folderUser = useGetUser();
const user = pageType === "shared" ? sharedUser : folderUser;
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion components/folder/FolderContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import styled from "styled-components";
import { useState } from "react";
import SearchBar from "../common/SearchBar";
import FolderList from "./FolderList";
import CardList from "../card/CardList";
import CardList from "../common/card/CardList";

const FolderContainer = () => {
const [selectedFolderId, setSelectedFolderId] = useState<number | null>(null);
Expand Down
4 changes: 2 additions & 2 deletions components/shared/SharedContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useState } from "react";
import styled from "styled-components";
import useGetSampleFolder from "../../hooks/useGetSampleFolder";
import CardList from "../card/CardList";
import CardList from "../common/card/CardList";
import SearchBar from "../common/SearchBar";
import Header from "../header/Header";
import Header from "../common/header/Header";

const SharedContainer = () => {
const folder = useGetSampleFolder();
Expand Down
58 changes: 58 additions & 0 deletions components/sign/SignHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Image from "next/image";
import Link from "next/link";
import styled from "styled-components";
import Logo from "@/src/image/logo.svg";

interface HeaderProps {
checkMember: string;
signSrc: string;
Copy link
Collaborator

Choose a reason for hiding this comment

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

이곳도 타입이 string 이면 협업자가 봤을때 어떤 값을 넣어야할지 SignHeader 파일을 뜯어봐야하는데요
type으로 signin or signup으로 체크해준다면 type 칸 에도 자동완성이 되기도 하고 더 명확해지죠

toSignText: string;
}

const SignHeader = ({ checkMember, signSrc, toSignText }: HeaderProps) => {
return (
<Header>
<LogoBtn href="/">
<LogoImg src={Logo} alt="로고 이미지" />
</LogoBtn>
<Text>
{checkMember}
<ToSign href={signSrc}>{toSignText}</ToSign>
</Text>
</Header>
);
};

const Header = styled.header`
display: flex;
flex-direction: column;
row-gap: 1.6rem;
`;

const LogoBtn = styled(Link)`
display: flex;
align-items: center;
`;

const LogoImg = styled(Image)`
width: 21.0583rem;
height: 3.8rem;
`;

const Text = styled.div`
display: flex;
gap: 0.8rem;

color: var(--linkbrary-black);

font-size: 1.6rem;
line-height: 2.4rem;
`;

const ToSign = styled(Link)`
color: var(--primary);

font-weight: 600;
`;

export default SignHeader;
64 changes: 64 additions & 0 deletions components/sign/Social.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import Image from "next/image";
import Link from "next/link";
import styled from "styled-components";
import GoogleImg from "@/src/image/google.svg";
import KakaoImg from "@/src/image/kakaotalk.svg";
import { ReactNode } from "react";

interface SocialProps {
children: ReactNode;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Social 부분도 텍스트형태로만 되어있으니
ReactNode 보다는 아래처럼 타입을 명확하게 좁혀주는게 좋습니다
협업할때 다른사람이 타입만 보고도 알수있으니까요

type: "signin" | "signup"

}

const Social = ({ children }: SocialProps) => {
return (
<Wrapper>
<SocialSign>{children}</SocialSign>
<Links>
<SocialLink href="https://www.google.com/">
<Image src={GoogleImg} alt="구글 로고" />
</SocialLink>

<SocialLink href="https://www.kakaocorp.com/page/">
<Image src={KakaoImg} alt="카카오 로고" />
</SocialLink>
</Links>
</Wrapper>
);
};

const Wrapper = styled.div`
width: 40rem;

display: flex;
justify-content: space-between;
align-items: center;
padding: 1.2rem 2.4rem;

border-radius: 0.8rem;
border: 0.1rem solid var(--gray30);
background: var(--gray40);
`;

const SocialSign = styled.p`
color: var(--gray10);

font-size: 1.4rem;
font-weight: 400;
`;

const Links = styled.div`
display: flex;
align-items: flex-start;
gap: 1.6rem;
`;

const SocialLink = styled(Link)`
display: flex;
justify-content: center;
align-items: center;
width: 4.2rem;
height: 4.2rem;
`;

// const LinkImg = styled(Image)``;
export default Social;
67 changes: 67 additions & 0 deletions components/sign/signInput/SignForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { FormEvent, useState } from "react";
import styled from "styled-components";
import SignInput from "./SignInput";

interface SignFormProps {
signup?: boolean;
children: string;
}

const SignForm = ({ signup, children }: SignFormProps) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");

const handleSubmit = async (e: FormEvent) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

각 로그인, 회원가입 post api 추가하려면
handleSubmit 함수내에 로그인, 회원가입 분기처리를 해줘야하는데요
그러면 SignFormProps의 타입도 추가 될거구요
SigninForm, SignupForm으로 로그인과 회원가입의 로직들을 분리하는게 명확해보입니다.

추가로 SignInput 컴포넌트 처럼 Button도 공통화해서 common에 관리를 한다면
SigninForm, SignupForm으로 분리해도 코드 중복을 최소화 할수있겠죠?

다음주 멘토링때 관련해서 설명 드릴게요

function SignInForm() {
...  useState()

function handleSubmit(e) {
  // signin api ...
}

return (
<SignInput label=email />
<SignInput ... />
<SignInput ... />

<Button buttonType="Primary" text="" ... />
}

e.preventDefault();
};

return (
<Form onSubmit={handleSubmit}>
<InputWrapper>
<SignInput label="이메일" type="email" placeholder="이메일을 입력해 주세요." inputValue={email} setValue={setEmail} />
<SignInput label="비밀번호" type="password" inputValue={password} setValue={setPassword} placeholder={signup ? "영문, 숫자를 조합해 8자 이상 입력해 주세요." : "비밀번호를 입력해 주세요."} />
{signup && (
<SignInput
label="비밀번호 확인"
type="confirmPassword"
inputValue={confirmPassword}
setValue={setConfirmPassword}
Copy link
Collaborator

Choose a reason for hiding this comment

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

이렇게 setter를 바로 Props로 넘겨주면 Input을 focus out할때 비밀번호 유효성검사를 하지못하는데요
보통 콜백함수 형태로 전달하는편이 좋아요

const 함수 = (e) => {
  const {value} = e.target;
  // pw value 유효성검사
  ...
  setPassword(value)
}

password={password}
placeholder="비밀번호와 일치하는 값을 입력해 주세요."
/>
)}
</InputWrapper>
<SubmitButton type="submit">{children}</SubmitButton>
</Form>
);
};

const Form = styled.form`
display: flex;
flex-direction: column;
gap: 3rem;
width: 40rem;
`;

const InputWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 2.4rem;
`;

const SubmitButton = styled.button`
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 5.4rem;
border-radius: 0.8rem;
background-image: var(--graBlueToSkyBlue);

color: #f5f5f5;
font-size: 1.8rem;
font-weight: 600;
`;

export default SignForm;
Loading