Skip to content

Commit

Permalink
Merge pull request #47 from Central-MakeUs/feat-44
Browse files Browse the repository at this point in the history
feat : 홈페이지 UI 추가
  • Loading branch information
DongjaJ authored Jan 28, 2025
2 parents 24f0057 + 1eff2e0 commit 39e9374
Show file tree
Hide file tree
Showing 16 changed files with 456 additions and 9 deletions.
16 changes: 16 additions & 0 deletions src/pages/home/components/recommend-category.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { style } from '@vanilla-extract/css';
import { color, typography } from '../../../ui';

export const container = style({
display: 'flex',
flexDirection: 'column',
gap: 4,
alignItems: 'center',
});

export const description = style([
typography('body_5_12_r'),
{
color: color('black'),
},
]);
18 changes: 18 additions & 0 deletions src/pages/home/components/recommend-category.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ElementType } from 'react';
import * as styles from './recommend-category.css';

type RecommendCategoryProps = {
Icon: ElementType;
name: string;
};

export const RecommendCategory = (props: RecommendCategoryProps) => {
const { Icon, name } = props;

return (
<div className={styles.container}>
<Icon />
<p className={styles.description}>{name}</p>
</div>
);
};
52 changes: 52 additions & 0 deletions src/pages/home/components/recommend-product.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { style } from '@vanilla-extract/css';
import { color, typography } from '../../../ui';

export const container = style({
display: 'flex',
flexDirection: 'column',
gap: 18,
overflow: 'hidden',
});

export const header = style({
display: 'flex',
flexDirection: 'column',
gap: 2,
padding: '5px 0 8px 0',
});

export const headerTitleContainer = style({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
});

export const gallery = style({
display: 'flex',
gap: 18,
overflowX: 'auto',
width: 'calc(100dvw - 40px)',
'@media': {
'screen and (min-width: 440px)': {
width: 400,
},
},
whiteSpace: 'nowrap',
'::-webkit-scrollbar': {
display: 'none',
},
});

export const description = style([
typography('body_3_14_r'),
{
color: color('grey600'),
},
]);

export const title = style([
typography('title_2_20_b'),
{
color: color('grey800'),
},
]);
33 changes: 33 additions & 0 deletions src/pages/home/components/recommend-product.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ButtonText } from '../../../ui/button-text';
import { Card } from '../../../ui/card/card';
import { MOCK_PRODUCT_LIST } from '../mock-product';
import * as styles from './recommend-product.css';

type RecommendProductGalleryProps = {
description: string;
title: string;
};

//TODO 추후 데이터 패칭 및 로딩 처리 필요
export const RecommendProductGallery = (
props: RecommendProductGalleryProps,
) => {
const { description, title } = props;

return (
<section className={styles.container}>
<header className={styles.header}>
<p className={styles.description}>{description}</p>
<div className={styles.headerTitleContainer}>
<h4 className={styles.title}>{title}</h4>
<ButtonText icon>더보기</ButtonText>
</div>
</header>
<div className={styles.gallery}>
{MOCK_PRODUCT_LIST.map((mockProduct) => (
<Card key={mockProduct.name} {...mockProduct} />
))}
</div>
</section>
);
};
80 changes: 79 additions & 1 deletion src/pages/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { useState } from 'react';
import { Cart, Logo } from '../../assets';
import { AppBar } from '../../ui/app-bar';
import { ButtonText } from '../../ui/button-text';
import { Chip } from '../../ui/chip';
import { PageLayout } from '../../ui/layout/page-layout';
import { SearchField } from '../../ui/search-field';
import { Spacer } from '../../ui/spacer/spacer';
import { Switch } from '../../ui/switch';
import { RecommendCategory } from './components/recommend-category';
import { RecommendProductGallery } from './components/recommend-product';
import { RECOMMEND_CATEGORY_LIST } from './recommend-category';
import * as styles from './styles.css';

export const HomePage = () => {
const [searchMode, setSearchMode] = useState<string>('AI 증상 검색');

return (
<PageLayout
header={
Expand All @@ -13,7 +24,74 @@ export const HomePage = () => {
}
className={styles.home}
>
HomePage
<div className={styles.mainContainer}>
<div className={styles.mainSearchContainer}>
<Switch
left="증상 AI 검색"
right="제품 검색"
value={searchMode}
onValueChange={setSearchMode}
/>

<SearchField
placeholder="건강 불편 증상을 검색해 보세요"
variant="home"
disabled
/>
</div>
<Spacer size={32} />
<div className={styles.contentContainer}>
<div>
<h4 className={styles.recommendSearchTitle}>추천 검색어</h4>
<p className={styles.recommendSearchDescription}>
이렇게 검색헤보세요
</p>
</div>
<div className={styles.recommendSearchKeywordContainer}>
<Chip state="default" shape="pill" color="default">
다이어트 하는 중에 탈모가 왔어요
</Chip>
<Chip state="default" shape="pill" color="default">
야채 섭취가 부족해요
</Chip>
<Chip state="default" shape="pill" color="default">
일어날 때 머리가 어지러워요
</Chip>
</div>
</div>
</div>

<div className={styles.bottomSheetContainer}>
<div className={styles.bottomSheetHealthCategoryContainer}>
{/* TODO 추후 캐러셀 추가 */}
<section className={styles.recommendCategoryContainer}>
<h4 className={styles.recommendCategoryTitle}>
추천 건강 고민 카테고리
</h4>
<div className={styles.recommendCategoryGallery}>
{RECOMMEND_CATEGORY_LIST.map(({ icon, name }) => (
<RecommendCategory key={name} Icon={icon} name={name} />
))}
</div>
</section>
</div>
<button className={styles.viewAllButton}>
<ButtonText icon>건강 고민 전체 보기</ButtonText>
</button>
<div className={styles.separator} />

<div className={styles.recommendProductContainer}>
{/* TODO 추후 배열로 렌더링할 예정 */}
<RecommendProductGallery
description="약통에 많이 담기고 있어요!"
title="인기 건강 기능 식품"
/>
<RecommendProductGallery
description="20대 여성"
title="추천 건강 식품"
/>
</div>
</div>
</PageLayout>
);
};
8 changes: 8 additions & 0 deletions src/pages/home/mock-product.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const MOCK_PRODUCT = {
imageUrl: 'https://picsum.photos/200/300',
company: '종근당건강 종근당건강 종근당건강',
name: '이뮨베라 이뮨베라 이뮨베라 이뮨베라 이뮨베라 이뮨베라 이뮨베라 ',
price: 77000,
};

export const MOCK_PRODUCT_LIST = Array.from({ length: 10 }, () => MOCK_PRODUCT);
27 changes: 27 additions & 0 deletions src/pages/home/recommend-category.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ElementType } from 'react';
import {
IcAnemia_S,
IcBloodcirculation_S,
IcBloodfat_S,
IcBloodpressure_S,
IcBloodsugar_S,
IcBone_S,
IcImmunity_S,
IcTooth_S,
} from '../../assets';

type RecommendCategory = {
icon: ElementType;
name: string;
};

export const RECOMMEND_CATEGORY_LIST: RecommendCategory[] = [
{ icon: IcImmunity_S, name: '면역 기능' },
{ icon: IcBloodpressure_S, name: '혈압' },
{ icon: IcBloodsugar_S, name: '혈당' },
{ icon: IcBloodfat_S, name: '헐중 지방' },
{ icon: IcBloodcirculation_S, name: '혈액 순환' },
{ icon: IcAnemia_S, name: '빈혈' },
{ icon: IcBone_S, name: '뼈 건강' },
{ icon: IcTooth_S, name: '치아&잇몸' },
];
99 changes: 98 additions & 1 deletion src/pages/home/styles.css.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,101 @@
import { style } from '@vanilla-extract/css';
import { color } from '../../ui';
import { color, typography } from '../../ui';

export const home = style({ backgroundColor: color('blue100') });

export const mainContainer = style({
padding: '60px 20px 86px 20px',
});

export const contentContainer = style({
display: 'flex',
gap: 18,
flexDirection: 'column',
});

export const mainSearchContainer = style([
contentContainer,
{
alignItems: 'center',
},
]);

export const recommendSearchTitle = style([
typography('head_1_18_sb'),
{
color: color('grey900'),
},
]);

export const recommendSearchDescription = style([
typography('body_5_12_r'),
{
color: color('grey500'),
},
]);

export const recommendSearchKeywordContainer = style([
contentContainer,
{
gap: 15,
},
]);

export const bottomSheetContainer = style({
backgroundColor: color('white'),
borderRadius: '20px 20px 0px 0px',
boxShadow: '0 -1.01px 12.3px 5px rgba(148, 161, 201, 0.3)',
});

export const bottomSheetHealthCategoryContainer = style({
padding: '16px 20px',
});

export const viewAllButton = style({
width: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: '8px 0',
borderTop: `1px solid ${color('grey100')}`,
cursor: 'pointer',
});

export const separator = style({
height: 10,
backgroundColor: color('grey100'),
});

export const bottomSheetDescription = style([
typography('body_3_14_r'),
{
color: color('grey600'),
},
]);

export const recommendCategoryContainer = style({
display: 'flex',
flexDirection: 'column',
gap: 14,
});

export const recommendCategoryTitle = style([
typography('head_1_18_sb'),
{
color: color('grey800'),
padding: '5px 0',
},
]);

export const recommendCategoryGallery = style({
display: 'grid',
gridTemplateColumns: 'repeat(4, 1fr)',
gap: '18px 32px',
});

export const recommendProductContainer = style({
display: 'flex',
flexDirection: 'column',
gap: 50,
padding: '30px 20px 36px 20px',
});
5 changes: 2 additions & 3 deletions src/ui/app-bar/app-bar.styles.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { typography } from '../typography.css';
export const appBar = recipe({
base: {
position: 'relative',
height: 44,
display: 'flex',
alignItems: 'center',
maxWidth: 440,
Expand All @@ -14,14 +13,14 @@ export const appBar = recipe({
default: [
typography('title_1_22_b'),
{
padding: '0 10px 0 20px',
padding: '6px 10px 6px 20px',
},
],
page: [
typography('head_1_18_sb'),
{
justifyContent: 'center',
padding: '0 10px 0 3px',
padding: '6px 10px 6px 3px',
},
],
},
Expand Down
Loading

0 comments on commit 39e9374

Please sign in to comment.