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

경북대 FE_정서현_2주차 과제 Step 1/2/3 #42

Open
wants to merge 33 commits into
base: 1oveydev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
be753d4
Docs: Add README.md
hyunaeri Jul 3, 2024
19420e1
Docs: modify README.md
hyunaeri Jul 3, 2024
dc14d2f
Refactor: rename files from index.tsx to component_name.tsx
hyunaeri Jul 3, 2024
f8955bb
Feat: add 'lint' command to package.json
hyunaeri Jul 4, 2024
77c1780
Feat: add Header & Footer components
hyunaeri Jul 4, 2024
abbec34
Feat: install react-router-dom library
hyunaeri Jul 4, 2024
b0c5be0
Refactor: modify Header & Footer css code
hyunaeri Jul 4, 2024
3c4be38
Refactor: remove duplicate css styles
hyunaeri Jul 4, 2024
772c681
Feat: implement SelectGiftRecipient component
hyunaeri Jul 4, 2024
2fc8b15
Refactor: add missing curly braces
hyunaeri Jul 4, 2024
1e85e1b
Refactor: improve code readability and structure
hyunaeri Jul 4, 2024
11f2f49
Refactor: improve code readability and structure
hyunaeri Jul 4, 2024
b414b75
Feat: Theme 카테고리 섹션 추가 및 페이지 이동 기능 구현
hyunaeri Jul 4, 2024
cf1f0ba
Feat: 카카오 선물하기 메인페이지 구현
hyunaeri Jul 4, 2024
886cec1
Feat: 초기 Theme / Login / My-account 페이지 구현
hyunaeri Jul 4, 2024
67e8007
Docs: 페이지 구현 완료 체크
hyunaeri Jul 4, 2024
52892d1
Feat: box-border 속성 추가
hyunaeri Jul 4, 2024
d658207
Feat: 메인 페이지의 테마 카테고리 섹션 구현 완료
hyunaeri Jul 4, 2024
71944a1
Feat: 실시간 급상승 선물랭킹 기능 구현 & Footer 하단 고정
hyunaeri Jul 5, 2024
9b5537d
Feat: 테마 페이지 및 라우팅 구현
hyunaeri Jul 5, 2024
d1c6bc6
Refactor: 테마 배너 컴포넌트 코드 수정
hyunaeri Jul 5, 2024
676b0aa
Docs: 최종 구현 기능 체크 완료
hyunaeri Jul 5, 2024
4a4a26e
Feat: Context API 를 이용한 로그인 / 내 정보 페이지 구현
hyunaeri Jul 5, 2024
e55c026
Fix: 폴더명 및 파일명의 대소문자 구분
hyunaeri Jul 8, 2024
2154079
Fix: 폴더명 및 파일명의 대소문자 구분
hyunaeri Jul 8, 2024
90bad78
Refactor: array.prototype.map 을 이용하여 메뉴버튼 코드 수정
hyunaeri Jul 8, 2024
b68e7ad
Refactor: MenuButton 을 div element 에서 button element 로 수정
hyunaeri Jul 8, 2024
eb7a364
Refactor: 필요하지 않은 함수(handleNavigate) 제거
hyunaeri Jul 8, 2024
b8a6ed9
Refactor: 중복되는 state 제거 및 반복되는 코드 패턴에 대해서 map을 이용하여 추상화
hyunaeri Jul 8, 2024
f4ef0d1
Feat: useMemo 를 이용한 최적화 및 MoreButton CSS 속성 추가
hyunaeri Jul 8, 2024
6672572
Feat: 별도의 Theme.tsx 파일에 데이터 저장 후 import 로 가져오기
hyunaeri Jul 8, 2024
f3901be
Refactor: 함수(handleChange)의 상태 업데이트 로직을 더 추상화된 형태로 개선
hyunaeri Jul 8, 2024
8b2d7fd
Refactor: GenderFilterType 와 WishFilterType 및 반복되는 코드 패턴 추상화
hyunaeri Jul 8, 2024
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
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"themekey"
]
}
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
# 카카오 테크 캠퍼스 - 프론트엔드 카카오 선물하기 편
<h1> 카카오 테크 캠퍼스 - 프론트엔드 카카오 선물하기 편 </h1>

[🔗 link](https://edu.nextstep.camp/s/hazAC9xa)
<h3>2주차 체크 리스트</h3>

## Week 1. 1단계 - 프로젝트 세팅
- [x] Header, Footer 와 같은 공통 컴포넌트 작성

[🔗 link](https://edu.nextstep.camp/s/hazAC9xa/ls/QzgHvzRM)
- [x] 각 Url Path 별로 페이지 만들기

## Week 1. 2단계 - Storybook을 사용하여 재사용 가능한 컴포넌트 구현
- Main page (`/`)

[🔗 link](https://edu.nextstep.camp/s/hazAC9xa/ls/4wYFPW1K)
- [x] Theme 카테고리 섹션 추가

## Week 2. 1단계 - 페이지 만들기
- [x] Theme 카테고리 Item 클릭 시 Theme page(`/theme/:themekey`) 로 이동

- Theme page (`/theme/:themekey`)

- [x] 재사용성을 고려하여 Header 섹션 추가

- [x] 상품 목록 섹션 추가

- Login page (`/login`)

- [x] ID와 PW를 입력하면 로그인이 되도록 구현

- My page (`/my-account`)

- [x] 로그아웃이 가능한 버튼 추가

[🔗 link](https://edu.nextstep.camp/s/hazAC9xa/ls/QzV1ncxk)
44 changes: 43 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"start": "craco start",
"build": "craco build",
"test": "craco test",
"lint": "eslint --fix src/",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
Expand All @@ -25,11 +26,10 @@
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-router-dom": "^6.24.1"
},
"devDependencies": {
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"@craco/craco": "^7.1.0",
"@emotion/eslint-plugin": "^11.11.0",
"@storybook/addon-essentials": "^7.6.17",
Expand Down Expand Up @@ -65,8 +65,10 @@
"eslint-plugin-storybook": "^0.8.0",
"prettier": "^3.2.5",
"prop-types": "^15.8.1",
"react-scripts": "5.0.1",
"storybook": "^7.6.17",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"typescript": "^4.9.5",
"webpack": "^5.90.3"
},
"overrides": {
Expand Down
50 changes: 39 additions & 11 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
import styled from '@emotion/styled';
import { type ReactNode } from 'react';
import { BrowserRouter, Navigate,Route, Routes } from 'react-router-dom';

const App = () => {
const name = 'Josh Perez';
import { AuthProvider, useAuth } from '@/components/AuthContext';
import LoginPage from "@/pages/LoginPage";
import MainPage from "@/pages/MainPage";
import MyAccountPage from "@/pages/MyAccountPage";
import ThemePage from "@/pages/ThemePage";

interface ProtectedRouteProps {
children: ReactNode;
}

const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
const { isAuth } = useAuth();

if (!isAuth) {
return <Navigate to={'/login'} replace />
} else {
return <>{children}</>;
}
};

const App = () => {
return (
<div>
<Title>Hello, {name}</Title>
</div>
<AuthProvider>
<BrowserRouter>
<Routes>
<Route path={'/'} element={<MainPage />} />
<Route path={'/login'} element={<LoginPage />} />
<Route path={'/theme/:themeKey'} element={<ThemePage />} />
<Route
path={'/my-account'}
element={
<ProtectedRoute>
<MyAccountPage />
</ProtectedRoute>
}
/>
</Routes>
</BrowserRouter>
</AuthProvider>
);
};

export default App;

const Title = styled.h1`
font-size: 1.5em;
color: gray;
`;
47 changes: 47 additions & 0 deletions src/components/AuthContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { ReactNode } from 'react';
import { createContext, useContext, useEffect,useState } from 'react';

interface AuthContextType {
isAuth: boolean;
login: (userName: string) => void;
logout: () => void;
}

const initAuthContext: AuthContextType = {
isAuth: false,
login: () => {},
logout: () => {},
};

interface AuthProviderProps {
children: ReactNode;
}

const AuthContext = createContext<AuthContextType>(initAuthContext);

export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
const [isAuth, setIsAuth] = useState(false);

useEffect(() => {
const token = sessionStorage.getItem('authToken');
if (token) {
setIsAuth(true);
}
}, []);

const login = (userName: string) => {
sessionStorage.setItem('authToken', userName);
setIsAuth(true);
};

const logout = () => {
sessionStorage.removeItem('authToken');
setIsAuth(false);
};

return <AuthContext.Provider value={{ isAuth, login, logout }}>{children}</AuthContext.Provider>;
};

export const useAuth = () => {
return useContext(AuthContext);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';

import { Button } from './index';
import { Button } from './Button';

// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/GoodsItem/Default.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from '@emotion/styled';

import { Image } from '@/components/common/Image';
import { Image } from '@/components/common/Image/Image';

export type DefaultGoodsItemsProps = {
imageSrc: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { Meta, StoryObj } from '@storybook/react';

import { Image } from '.';
import { Image } from './Image';

// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
title: 'Common/Image',
component: Image,
tags: ['autodocs'],
args: {

src: 'https://t1.kakaocdn.net/friends/www/talk/kakaofriends_talk_2018.png',
},
} satisfies Meta<typeof Image>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';

import { Container } from '.';
import { Container } from './Container';

// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
Expand Down
49 changes: 49 additions & 0 deletions src/components/common/layouts/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import styled from '@emotion/styled'

const Footer: React.FC = () => {
return (
<Wrapper>
<FooterContainer>
<FooterInner className='inner'>
<FooterLogo src="https://img1.kakaocdn.net/thumb/[email protected]/?fname=https%3A%2F%2Fgift-s.kakaocdn.net%2Fdn%2Fgift%2Fimages%2Fm640%2Fpc_smallbi_201223.png" alt="카카오톡 선물하기 로고2" />
</FooterInner>
</FooterContainer>
</Wrapper>
)
}

export default Footer

const Wrapper = styled.footer`
position: fixed;
width: 100%;
margin-top: auto;
z-index: 9;
padding: 28px 16px 88px;
background-color: rgb(250, 250, 252);
bottom: 0;

@media screen and (min-width: 768px) {
padding: 40px 16px 120px;
}
`;

const FooterContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
`;

const FooterInner = styled.div`
width: 100%;
max-width: 1024px;
height: 21px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
`;

const FooterLogo = styled.img`
height: 20px;
`;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';

import { Grid } from '.';
import { Grid } from './Grid';

const ChildComponent = () => (
<>
Expand Down
Loading