Skip to content

Commit

Permalink
Merge branch 'develop' into page-search
Browse files Browse the repository at this point in the history
  • Loading branch information
seoye0ng authored Jan 21, 2024
2 parents cd1d286 + 786b042 commit c45e731
Show file tree
Hide file tree
Showing 36 changed files with 543 additions and 279 deletions.
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test": "vitest",
"test:ui": "vitest --ui",
"chromatic": "npx chromatic --project-token=chpt_228d999e438e234"
},
"dependencies": {
Expand All @@ -28,7 +29,7 @@
"react-dom": "^18",
"react-hook-form": "^7.49.2",
"react-redux": "^9.0.4",
"swiper": "^11"
"react-slick": "^0.29.0"
},
"devDependencies": {
"@storybook/addon-essentials": "^7.6.6",
Expand All @@ -47,9 +48,11 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react-slick": "^0.23.13",
"@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.15.0",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/ui": "^1.2.1",
"chromatic": "^10.2.0",
"eslint": "^8",
"eslint-config-airbnb": "^19.0.4",
Expand All @@ -62,6 +65,7 @@
"jsdom": "^23.2.0",
"msw": "^2.0.13",
"sass": "^1.69.6",
"slick-carousel": "^1.8.1",
"storybook": "^7.6.6",
"storybook-react-context": "^0.6.0",
"stylelint": "^16.1.0",
Expand All @@ -75,4 +79,4 @@
"msw": {
"workerDirectory": "public"
}
}
}
3 changes: 3 additions & 0 deletions public/assets/icons/star.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/product.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
3 changes: 3 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
@import "~slick-carousel/slick/slick.css";
@import "~slick-carousel/slick/slick-theme.css";

:root {
--primary: #0075FF;
--secondary: #B2D6FF;
Expand Down
7 changes: 1 addition & 6 deletions src/app/page.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@
padding: 0 24px;
}

.bannerWrapper {
max-height: 140px;
overflow-y: hidden;
}

.recommandTextWrapper {
.recommendTextWrapper {
padding: 0 24px;
}

Expand Down
45 changes: 21 additions & 24 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import classNames from 'classnames/bind';
import dynamic from 'next/dynamic';

import BottomNav from '@components/shared/bottom-nav/BottomNav';
import Flex from '@components/shared/flex/Flex';
import Header from '@components/shared/header/Header';
import ProductArticle from '@components/shared/product-article/ProductArticle';
import Radio from '@components/shared/radio/Radio';
import Spacing from '@components/shared/spacing/Spacing';
import Text from '@components/shared/text/Text';
import BottomNav from '@shared/bottom-nav/BottomNav';
import Banner from '@shared/carousel/Banner';
import RecommendList from '@shared/carousel/RecommendList';
import Flex from '@shared/flex/Flex';
import Header from '@shared/header/Header';
import ProductArticle from '@shared/product-article/ProductArticle';
import Radio from '@shared/radio/Radio';
import SearchBar from '@shared/search-bar/SearchBar';
import Spacing from '@shared/spacing/Spacing';
import Text from '@shared/text/Text';

import styles from './page.module.scss';

const Banner = dynamic(() => { return import('@components/shared/carousel/Banner'); });
const RecommandList = dynamic(() => { return import('@components/shared/carousel/RecommandList'); });

const cx = classNames.bind(styles);

const bannerData = [
Expand Down Expand Up @@ -43,49 +42,49 @@ const bannerData = [
},
];

const recommandListData = [
const recommendListData = [
{
id: 1,
link: '/',
src: '/assets/recommandItem1.png',
src: '/assets/recommendItem1.png',
alt: '그림',
productName: '카샴푸',
},
{
id: 2,
link: '/',
src: '/assets/recommandItem2.png',
src: '/assets/recommendItem2.png',
alt: '그림',
productName: '휠 클리너',
},
{
id: 3,
link: '/',
src: '/assets/recommandItem3.png',
src: '/assets/recommendItem3.png',
alt: '그림',
productName: '타올',

},
{
id: 4,
link: '/',
src: '/assets/recommandItem4.png',
src: '/assets/recommendItem4.png',
alt: '그림',
productName: '먼지털이개',

},
{
id: 5,
link: '/',
src: '/assets/recommandItem4.png',
src: '/assets/recommendItem4.png',
alt: '그림',
productName: '먼지털이개',

},
{
id: 6,
link: '/',
src: '/assets/recommandItem4.png',
src: '/assets/recommendItem4.png',
alt: '그림',
productName: '먼지털이개',

Expand Down Expand Up @@ -137,23 +136,21 @@ export default function Home() {
<Spacing size={16} />
<Spacing size={24} />
</div>
<div className={cx('bannerWrapper')}>
<Banner bannerData={bannerData} />
</div>
<Banner bannerData={bannerData} />
<Spacing size={32} />
<div className={cx('recommandTextWrapper')}>
<div className={cx('recommendTextWrapper')}>
<Text bold>추천 세차용품</Text>
</div>
<Spacing size={16} />
<RecommandList recommandListData={recommandListData} />
<RecommendList recommendListData={recommendListData} />
<Spacing size={32} />
<div className={cx('productListContainer')}>
<Text bold>WashPedia 랭킹</Text>
<Spacing size={16} />
<Flex justify="space-between" align="center" gap={8}>
<Radio label="조회순" name="filter" type="filter" value="view" defaultChecked />
<Radio label="위반제품" name="filter" type="filter" value="violatingProduct" />
<Radio label="추천순" name="filter" type="filter" value="recommand" />
<Radio label="추천순" name="filter" type="filter" value="recommend" />
<Radio label="최신제품" name="filter" type="filter" value="latest" />
</Flex>
<Spacing size={16} />
Expand Down
7 changes: 7 additions & 0 deletions src/app/product/[id]/page.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.product {
padding: 0 24px;
}

.productInfo {
padding: 16px 24px;
}
43 changes: 43 additions & 0 deletions src/app/product/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import classNames from 'classnames/bind';
import Image from 'next/image';

import Star from '@components/icons/Star';
import Flex from '@shared/flex/Flex';
import Header from '@shared/header/Header';
import Radio from '@shared/radio/Radio';
import Spacing from '@shared/spacing/Spacing';
import Text from '@shared/text/Text';

import styles from './page.module.scss';

const cx = classNames.bind(styles);

function SuppliesPage() {
return (
<>
<Header isDisplayLogo={false} displayRightIconType="heartShare" className={cx('product')} />
<Image src="/assets/product.png" alt="상품 이미지" width={375} height={375} />
<Flex direction="column" className={cx('productInfo')}>
<Text color="primary" typography="t6">카믹스</Text>
<Text typography="t4" bold>아머올 세차용품 스피드 왁스 스프레이</Text>
<Flex align="center">
<Text color="tertiary" typography="t6">코팅제</Text>
<Spacing size={4} direction="vertical" />
<Text color="tertiary" typography="t6"></Text>
<Spacing size={4} direction="vertical" />
<Star size={14} />
<Spacing size={4} direction="vertical" />
<Text color="tertiary" typography="t6">4.5</Text>
<Spacing size={4} direction="vertical" />
<Text color="tertiary" typography="t6">(20)</Text>
</Flex>
</Flex>
<Flex>
<Radio type="product" label="제품정보" value="info" name="product" />
<Radio type="product" label="리뷰" value="review" name="product" />
</Flex>
</>
);
}

export default SuppliesPage;
10 changes: 10 additions & 0 deletions src/components/icons/Star.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function Star({ size }: { size: number }) {
return (
<svg width={size} height={size} viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.61835 0.820337C6.77435 0.504305 7.225 0.504305 7.381 0.820337L9.01274 4.12607C9.13652 4.37683 9.37567 4.55073 9.65238 4.59117L13.3021 5.12464C13.6508 5.1756 13.7898 5.60418 13.5373 5.85005L10.8974 8.42133C10.6968 8.61673 10.6052 8.89835 10.6526 9.17436L11.2755 12.8064C11.3351 13.1538 10.9704 13.4187 10.6585 13.2547L7.39554 11.5387C7.14772 11.4084 6.85163 11.4084 6.60381 11.5387L3.34089 13.2547C3.02892 13.4187 2.66425 13.1538 2.72383 12.8064L3.34677 9.17436C3.39411 8.89835 3.30254 8.61673 3.10193 8.42133L0.46201 5.85005C0.209584 5.60418 0.348549 5.1756 0.697217 5.12464L4.34697 4.59117C4.62368 4.55073 4.86283 4.37683 4.98661 4.12607L6.61835 0.820337Z" fill="#FFD15B" />
</svg>

);
}

export default Star;
72 changes: 40 additions & 32 deletions src/components/shared/accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* eslint-disable react/jsx-closing-tag-location */
/* eslint-disable max-len */
import type { Meta, StoryObj } from '@storybook/react';
import type { Meta } from '@storybook/react';

import Minus from '@components/icons/Minus';
import Plus from '@components/icons/Plus';
import Text from '@shared/text/Text';

import Accordion from './Accordion';
import AccordionBody from './body/AccordionBody';
import AccordionHeader from './header/AccordionHeader';
import AccordionItem from './item/AccordionItem';

const meta = {
title: 'Shared/Accordion',
Expand All @@ -18,35 +20,41 @@ const meta = {
} satisfies Meta<typeof Accordion>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Horizontal: Story = {
args: {
children: <>
<Accordion.Item label="1">
<Accordion.Header openIcon={<Plus />} closeIcon={<Minus />}>Accordion Item #1</Accordion.Header>
<Accordion.Body>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</Accordion.Body>
</Accordion.Item>
<Accordion.Item label="2">
<Accordion.Header openIcon={<Plus />} closeIcon={<Minus />}>Accordion Item #1</Accordion.Header>
<Accordion.Body>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</Accordion.Body>
</Accordion.Item>
</>,
export const AccordionStory = {
render: () => {
return (
<Accordion defaultActiveItems={['']}>
<AccordionItem itemName="목록1">
<AccordionHeader openIcon={<Plus />} closeIcon={<Minus />}>
<Text>
목록1
</Text>
</AccordionHeader>
<AccordionBody>
<Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
</Text>
</AccordionBody>
</AccordionItem>
<AccordionItem itemName="목록2">
<AccordionHeader>
<Text>
목록2
</Text>
</AccordionHeader>
<AccordionBody>
<Text>
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</Text>
</AccordionBody>
</AccordionItem>
</Accordion>
);
},
};
42 changes: 22 additions & 20 deletions src/components/shared/accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
import { useCallback, useMemo, useState } from 'react';
import {
forwardRef, useCallback, useMemo, useState,
} from 'react';

import AccordionContext from '@contexts/AccordionContext';
import AccordionContext from '@/contexts/AccordionContext';

import AccordionBody from './body';
import AccordionHeader from './header';
import AccordionItem from './item';
import { AccordionProps } from './type/accordion.type';

function Accordion({ children }: { children: React.ReactNode | React.ReactNode[] }) {
const [activeItem, setActiveItem] = useState('');
// eslint-disable-next-line max-len
const Accordion = forwardRef<HTMLDivElement, AccordionProps>(({ defaultActiveItems = [], children, ...props }, ref) => {
const [activeItems, setActiveItems] = useState<string[]>(defaultActiveItems);

const changeActiveItem = useCallback((value: string) => {
if (activeItem !== value) setActiveItem(value);
if (activeItem === value) setActiveItem('');
}, [setActiveItem, activeItem]);
const handleSetActiveItem = useCallback((item: string) => {
if (activeItems?.includes(item)) {
setActiveItems(activeItems.filter((activeItem) => { return activeItem !== item; }));
} else {
setActiveItems([...activeItems, item]);
}
}, [activeItems]);

const values = useMemo(() => {
return {
activeItem,
changeSelectedItem: changeActiveItem,
activeItems,
setActiveItem: handleSetActiveItem,
};
}, [activeItem, changeActiveItem]);
}, [activeItems, handleSetActiveItem]);

return (
<AccordionContext.Provider value={values}>
{children}
<div ref={ref} {...props}>
{children}
</div>
</AccordionContext.Provider>
);
}

Accordion.Item = AccordionItem;
Accordion.Header = AccordionHeader;
Accordion.Body = AccordionBody;
});

export default Accordion;
Loading

0 comments on commit c45e731

Please sign in to comment.