-
Notifications
You must be signed in to change notification settings - Fork 35
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
[김세환]sprint11 #318
The head ref may contain hidden characters: "Next-\uAE40\uC138\uD658-sprint11"
[김세환]sprint11 #318
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
{ | ||
"cSpell.words": ["addboard", "addfile", "sortmobile"] | ||
"cSpell.words": ["addboard", "addfile", "Kakao", "signup", "sortmobile"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import axios from "@/lib/axios"; | ||
|
||
interface SignInData { | ||
email: string; | ||
password: string; | ||
} | ||
|
||
interface SignUpData extends SignInData { | ||
passwordConfirmation: string; | ||
nickname: string; | ||
} | ||
|
||
interface ResponseData { | ||
accessToken: string; | ||
refreshToken: string; | ||
} | ||
|
||
export const postSignUp = async (signUpData: SignUpData) => { | ||
try { | ||
await axios.post("/auth/signUp", signUpData); | ||
return true; | ||
} catch (err) { | ||
console.log(err); | ||
return false; | ||
} | ||
}; | ||
|
||
export const postSignIn = async (signInData: SignInData) => { | ||
try { | ||
const res = await axios.post("/auth/signIn", signInData); | ||
return res.data; | ||
} catch (err) { | ||
return false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p5; 클라이언트에서도 어떤 에러때문에 요청이 실패했는지 알 수 있도록 작성해보면 좋을 것 같아요! 지금은 이렇게만으로도 충분할 것 같긴 합니다! |
||
}; |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import axios from "@/lib/axios"; | ||
|
||
export const getMe = async () => { | ||
try { | ||
const res = await axios.get("/users/me"); | ||
return res.data; | ||
} catch { | ||
console.log("유저정보가 없습니다"); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { PropsWithChildren, ReactNode } from "react"; | ||
import Image from "next/image"; | ||
|
||
import logoImg from "@/public/images/img_logo.svg"; | ||
import logoText from "@/public/images/img_logo_text.svg"; | ||
import icKakao from "@/public/images/ic_kakao.png"; | ||
import icGoogle from "@/public/images/ic_google.png"; | ||
import Link from "next/link"; | ||
import { usePathname } from "next/navigation"; | ||
import path from "path"; | ||
|
||
const INITIAL_TEXT = { | ||
login: { | ||
msg: "판다마켓이 처음이신가요?", | ||
link: "회원가입", | ||
}, | ||
signup: { | ||
msg: "이미 회원이신가요?", | ||
link: "로그인", | ||
}, | ||
} as const; | ||
|
||
export default function AuthContainer({ children }: PropsWithChildren) { | ||
const pathName = usePathname(); | ||
const nowPathname = pathName === "/auth/login" ? "login" : "signup"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p4; |
||
|
||
return ( | ||
<div className="mx-auto mt-20 max-w-2xl px-4 md:mt-48 md:px-5 lg:mt-56"> | ||
<div className="flex-center"> | ||
<Link href="/" className="flex-center gap-3 md:gap-5"> | ||
<div className=" relative w-[52px] md:w-[103px] h-[52px] md:h-[103px]"> | ||
<Image fill priority src={logoImg} alt="로고 이미지" /> | ||
</div> | ||
<div className="relative h-[45px] md:h-[90px] w-[133px] md:w-[268px] "> | ||
<Image fill priority src={logoText} alt="로고 글씨" /> | ||
</div> | ||
</Link> | ||
</div> | ||
<div className="pt-6 md:pt-14">{children}</div> | ||
<div className="mt-6 flex w-full items-center justify-between rounded-lg bg-blue-100 px-6 py-4"> | ||
<span className="text-base">간편 로그인하기</span> | ||
<div className="flex gap-4"> | ||
<Image alt="구글 아이콘" src={icGoogle} width={42} height={42} /> | ||
<Image alt="카카오 아이콘" src={icKakao} width={42} height={42} /> | ||
</div> | ||
</div> | ||
<p className="flex-center gap-1 pt-6 text-sm font-medium"> | ||
{INITIAL_TEXT[nowPathname].msg} | ||
<Link | ||
href={nowPathname === "login" ? "/auth/signup" : "/auth/login"} | ||
className="text-my-blue underline" | ||
> | ||
{INITIAL_TEXT[nowPathname].link} | ||
</Link> | ||
</p> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { useContext, useEffect, useState } from "react"; | ||
import { usePathname } from "next/navigation"; | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
|
||
import { UserContext, UserContextInterface } from "@/context/userProvider"; | ||
|
||
import logoImg from "@/public/images/img_logo.svg"; | ||
import logoText from "@/public/images/img_logo_text.svg"; | ||
import icProfile from "@/public/images/ic_profile.svg"; | ||
|
||
export default function Header() { | ||
const pathname = usePathname(); | ||
const [visibleHeader, setVisibleHeader] = useState(false); | ||
const [isLogin, setIsLogin] = useState(false); | ||
const { user } = useContext(UserContext) as UserContextInterface; | ||
useEffect(() => { | ||
if (!user) { | ||
setIsLogin(false); | ||
} else { | ||
setIsLogin(true); | ||
} | ||
}, [user]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p3; 그럼에도 isLogin이라는 상태가 꼭 필요하다면 const isLogin = useMemo(() => {
if (!user) return false;
return true;
}, [user]) |
||
|
||
useEffect(() => { | ||
if (pathname?.includes("auth")) { | ||
setVisibleHeader(false); | ||
} else { | ||
setVisibleHeader(true); | ||
} | ||
}, [pathname]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p4; const isHeaderVisible = pathname?.includes("auth");
if (!isHeaderVisible) return null;
return (
<nav>
...
</nav>
) |
||
return ( | ||
<> | ||
{visibleHeader && ( | ||
<nav | ||
className={`fixed top-0 w-full border-b bg-white drop-shadow-sm z-10`} | ||
> | ||
<div className="mx-auto flex h-[70px] max-w-[1120px] items-center justify-between gap-2 px-4 py-2.5 md:gap-5 lg:gap-8"> | ||
<Link href="/" className="flex gap-2.5"> | ||
<Image | ||
src={logoImg} | ||
alt="로고이미지" | ||
width={40} | ||
height={41} | ||
className="hidden md:block" | ||
priority | ||
/> | ||
<Image | ||
src={logoText} | ||
alt="로고글씨" | ||
width={101} | ||
height={41} | ||
priority | ||
/> | ||
</Link> | ||
{pathname?.includes("items") && ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p3; |
||
<div className="grow font-bold"> | ||
<Link href="forum" className="px-1 md:px-4"> | ||
자유게시판 | ||
</Link> | ||
<Link href="items" className={`px-1 text-gray-600 md:px-4`}> | ||
중고마켓 | ||
</Link> | ||
</div> | ||
)} | ||
{isLogin ? ( | ||
<Image | ||
src={icProfile} | ||
width={32} | ||
height={32} | ||
alt="유저프로필이미지" | ||
/> | ||
) : ( | ||
<Link href="/auth/login"> | ||
<button className="btn h-[48px] w-[128px]">로그인</button> | ||
</Link> | ||
)} | ||
</div> | ||
</nav> | ||
)} | ||
</> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { MouseEvent } from "react"; | ||
|
||
type ButtonProps = { | ||
className?: string; | ||
children: string; | ||
activeBtn?: boolean; | ||
}; | ||
|
||
export default function NewButton({ | ||
children, | ||
activeBtn, | ||
className, | ||
}: ButtonProps) { | ||
const activeColor = activeBtn ? "bg-my-blue" : "bg-gray-400"; | ||
|
||
return ( | ||
<button className={` flex-center text-white ${className} ${activeColor}`}> | ||
{children} | ||
</button> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { FieldErrors, FieldValues } from "react-hook-form"; | ||
|
||
interface InputProps { | ||
label: string; | ||
type: string; | ||
placeholder: string; | ||
name: string; | ||
register: any; | ||
validator: object; | ||
errors: any; | ||
} | ||
|
||
export default function NewInput({ | ||
name, | ||
placeholder, | ||
type, | ||
label, | ||
register, | ||
validator, | ||
errors, | ||
}: InputProps) { | ||
return ( | ||
<div className="flex flex-col pb-6"> | ||
<label className="pb-4 text-lg font-bold" htmlFor={name}> | ||
{label} | ||
</label> | ||
<input | ||
className="rounded-xl border-none bg-gray-100 px-6 py-4 outline-none" | ||
type={type} | ||
placeholder={placeholder} | ||
id={name} | ||
{...register(name, validator)} | ||
></input> | ||
<div className="text-my-error-red">{errors[name]?.message}</div> | ||
</div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
인터셉터를 사용하니, 인증 헤더에 대한 부분을 요청시마다 반복적으로 쓰지 않아도 돼서 좋네요👍