Skip to content

Commit

Permalink
✨ Feat: 그라디언트 컴포넌트 UI 생성 (#56)
Browse files Browse the repository at this point in the history
* ✨ Feat: 그라디언트 컴포넌트 UI 생성

* ♻️ Refactor: 랩퍼 컴포넌트 구조 개선

* ♻️ Refactor: Landing 및 Not Found 페이지 그라데이션 적용

* 📦️ Chore: 임시 내용 저장

* 🐛 Fix: 공통 컴포넌트 적용 완료

* 📦️ Chore: Background 컴포넌트 일부 적용 및 특정 페이지 내 scss 파일 변경
  • Loading branch information
Bersk3r authored May 15, 2024
1 parent 9c3fb52 commit 75bb3f2
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 88 deletions.
17 changes: 15 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import React from 'react';
import { Outlet } from 'react-router-dom';
import { Outlet, useLocation } from 'react-router-dom';

import Header from '@/components/Header';
import { Background } from '@/components/Background';

const App = () => {
return <Outlet />;
const location = useLocation();
const regxr = /(\/list|\/myPage)/;

return (
<>
{regxr.test(location.pathname) && <Header />}
<Background>
<Outlet />
</Background>
</>
);
};

export default App;
42 changes: 42 additions & 0 deletions src/assets/icons/Gradient.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from 'react';
const Gradient = ({ width = 225, height = 364, ...props }) => (
<svg
width={width}
height={height}
viewBox="0 0 225 364"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<g opacity={0.2} filter="url(#filter0_f_53_9901)">
<path
d="M84.899 45.8931C82.683 -28.1392 4.57085 -48.2158 -34.2082 -49C-66.1285 -44.2946 -126.328 -0.220261 -111.766 138.433C-97.2045 277.087 -8.09171 216.596 34.6444 169.019C52.3193 158.824 87.1149 119.925 84.899 45.8931Z"
fill="#14C3FE"
/>
</g>
<defs>
<filter
id="filter0_f_53_9901"
x={-254}
y={-189}
width={479}
height={553}
filterUnits="userSpaceOnUse"
colorInterpolationFilters="sRGB"
>
<feFlood floodOpacity={0} result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation={70}
result="effect1_foregroundBlur_53_9901"
/>
</filter>
</defs>
</svg>
);
export default Gradient;
18 changes: 18 additions & 0 deletions src/components/Background/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import PropTypes from 'prop-types';

import Gradient from '@/assets/icons/Gradient';
import style from './styles.module.scss';

export const Background = ({ children, isGradient = true }) => {
return (
<div className={style.container}>
{isGradient && <Gradient className={style.wrapper} />}
{children}
</div>
);
};

Background.propTypes = {
children: PropTypes.node.isRequired,
isGradient: PropTypes.bool,
};
15 changes: 15 additions & 0 deletions src/components/Background/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@import '../../styles/';

.container {
position: relative;
background-color: $color-black-200;
min-height: 100dvh;
}

.wrapper {
position: absolute;
top: 10px;
margin: 0;
padding: 0;
z-index: 99;
}
1 change: 0 additions & 1 deletion src/components/Modal/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@import '../../styles/';

.modalBackDrop {
z-index: 1; //위치지정 요소
position: fixed;
display: flex;
justify-content: center;
Expand Down
3 changes: 2 additions & 1 deletion src/main.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { RouterProvider } from 'react-router-dom';
import ReactDOM from 'react-dom/client';
import { RouterProvider } from 'react-router-dom';
import router from './router';

import 'reset-css';
import './styles/normalize.scss';
import { ToastContainer } from 'react-toastify';
Expand Down
1 change: 0 additions & 1 deletion src/pages/ListPage/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const ListPage = () => {
useScrollToTop();
return (
<div className={style.container}>
<Header />
<main className={style.main}>
<Credit />
<Donation />
Expand Down
2 changes: 1 addition & 1 deletion src/pages/ListPage/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import '../../styles/';

.container {
background-color: $color-black-200;
background-color: none;
}

.main {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
}

.title {
margin-block: 32px;
margin-block-end: 32px;
margin-left: 80px;

@include font-base($color-white, 700, 24px, 26px);
Expand Down Expand Up @@ -52,7 +52,7 @@

@media (max-width: $width-tablet) {
.title {
margin-block: 24px;
margin-block-end: 24px;
margin-left: 24px;

@include font-base($color-white, 700, 20px, 26px);
Expand All @@ -64,7 +64,7 @@

@media (max-width: $width-mobile) {
.title {
margin-block: 16px;
margin-block-end: 16px;
margin-left: 16px;

@include font-base($color-white, 700, 16px, 26px);
Expand Down
123 changes: 68 additions & 55 deletions src/pages/MyPage/index.jsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import classNames from 'classnames';
import style from './styles.module.scss';

import { useEffect, useState } from 'react';

import IdolFavoriteList from './components/IdolFavoriteList';
import IdolSelectList from './components/IdolSelectList';
import Header from '@/components/Header';
import testData from './mock.json';
import CustomButton from '@/components/CustomButton';
import Plus from '@/assets/icons/Plus';
import Footer from '@/components/Footer';

import { debounce } from '@/utils/debounce';
import { sortByItems } from '@/utils/sortItems';
import { getStorage, setStorage } from '@/utils/localStorage';


import useLoad from '@/hooks/useLoad';
import { getIdolData } from '@/apis/getIdolData';
import { useTitle } from '@/hooks/useTitle';
import useScrollToTop from '@/hooks/useScrollToTop';

const ITEM_COUNTS = 100;

const INITIAL_VALUE = {
allList: [],
favoriteIdolList: [],
favoriteList: [],
};

Expand All @@ -30,8 +30,10 @@ const MyPage = ({ pageSize = ITEM_COUNTS, keyword = '' }) => {
useScrollToTop();

const [idolList, setIdolList] = useState(INITIAL_VALUE);
const [isLoading, loadingError, handleLoad] = useLoad(getIdolData);
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
const [cursor, setCursor] = useState();
const [init, setInit] = useState(false);
const [cursor, setCursor] = useState(null);

const addFavorite = (selectedItem, clicked) => {
if (clicked) {
Expand All @@ -47,43 +49,36 @@ const MyPage = ({ pageSize = ITEM_COUNTS, keyword = '' }) => {
),
});
}
// setStorage('IdolList', JSON.stringify(idolList));
};

const deleteFavorite = (selectedItem) => {
let favoriteIdolList = JSON.parse(getStorage('favoriteIdolList'));

favoriteIdolList = favoriteIdolList.filter(
(idol) => idol.id !== selectedItem.id,
);

setStorage('favoriteIdolList', JSON.stringify(favoriteIdolList));

setIdolList({
...idolList,
allList: sortByItems([...idolList.allList, selectedItem], 'id'),
setIdolList((prevList) => {
return {
...prevList,
favoriteIdolList: prevList.favoriteIdolList
.filter((idol) => idol.id !== selectedItem.id)
.splice(),
allList: sortByItems([...prevList.allList, selectedItem], 'id'),
};
});
// setStorage('IdolList', JSON.stringify(idolList));
};

const submitIdolList = () => {
let favoriteIdolList = JSON.parse(getStorage('favoriteIdolList'));

favoriteIdolList = [...idolList.favoriteList, ...favoriteIdolList];

setStorage('favoriteIdolList', JSON.stringify(favoriteIdolList));

setIdolList({
...idolList,
favoriteIdolList: [
...idolList.favoriteList,
...idolList.favoriteIdolList,
],
allList: idolList.allList.filter(
(item) =>
!(idolList.favoriteList.filter((i) => item.id === i.id).length > 0),
),
favoriteList: [],
});
};

// UI용 데이터 호출 함수 제작
const getIdolList = () => {
setIdolList({ ...idolList, allList: testData.list });
// setStorage('IdolList', JSON.stringify(idolList));
};

const handleResize = () => {
Expand All @@ -101,50 +96,68 @@ const MyPage = ({ pageSize = ITEM_COUNTS, keyword = '' }) => {
};
}, [windowWidth]);

// const getIdolList = async (options) => {
// let result;
// result = await getData(options);
// const { list, nextCursor } = result;
// if (!options.cursor) {
// setIdolList(list);
// } else {
// setIdolList((prevList) => [...prevList, ...list]);
// }
const getIdolList = async (options) => {
let result;
result = await handleLoad(options);
const { list, nextCursor } = result;

// setCursor(nextCursor);
// };
if (!result) {
setInit(false);
return;
}

if (!options.cursor) {
setIdolList({ ...idolList, allList: list });
} else {
setIdolList((prevList) => {
return { ...idolList, allList: [...prevList, ...list] };
});
}
setCursor(nextCursor);
setInit(true);
// setStorage('IdolList', JSON.stringify(idolList));
};

// 100개 이상의 데이터가 존재하는 경우, 더 불러오기 위한 함수
// const getMoreIdolList = () => {
// getIdolList({ pageSize, cursor, keyword });
// };
const getMoreIdolList = () => {
getIdolList({ pageSize, cursor, keyword });
};

useEffect(() => {
// getIdolList({ pageSize, keyword });
getIdolList();
}, []);
if (!init) {
const IdolData = JSON.parse(getStorage('IdolList'));

if (IdolData) {
setIdolList(IdolData);
setInit(true);
} else {
getIdolList({ pageSize, keyword });
}
} else {
setStorage('IdolList', JSON.stringify(idolList));
}
}, [idolList]);

return (
<div className={style.container}>
<Header />
<main className={style.main}>
<IdolFavoriteList onDelete={deleteFavorite} windowWidth={windowWidth} />
<IdolFavoriteList
onDelete={deleteFavorite}
list={idolList.favoriteIdolList}
windowWidth={windowWidth}
isLoading={isLoading}
loadingError={loadingError}
/>
<div className={style.line}></div>
<IdolSelectList
list={idolList.allList}
favoriteList={idolList.favoriteList}
onClick={addFavorite}
windowWidth={windowWidth}
// onNextData={getMoreIdolList}
isLoading={isLoading}
loadingError={loadingError}
onSubmit={submitIdolList}
/>
<CustomButton
btnText="제출하기"
rounded={true}
iconTextGap={4}
onClick={submitIdolList}
>
<Plus />
</CustomButton>
</main>
<Footer />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/MyPage/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}

.container {
background-color: $color-black-200;
background-color: none;
min-height: 100vh;
padding-block-end: 20px;
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/NotFoundPage/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
align-items: center;
justify-content: space-around;

background-color: black;
background-color: none;
color: white;

height: 100vh;
Expand Down
Loading

0 comments on commit 75bb3f2

Please sign in to comment.