Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

제품 상세페이지, 로케이트 설정 #4

Merged
merged 4 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "My Progressive Web App",
"short_name": "MyPWA",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#3367D6"
}
110 changes: 66 additions & 44 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="theme-color" content="#FFFFFF" />
<meta
name="description"
content="Web site created using create-react-app"
Expand Down
45 changes: 45 additions & 0 deletions service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// service-worker.js

const CACHE_NAME = 'my-pwa-cache-v1';
const urlsToCache = [
'/',
'/index.html',
'/styles.css',
'/main.js',
'/icons/icon-192x192.png',
'/icons/icon-512x512.png'
];

// 설치 단계에서 캐시할 리소스를 지정
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(urlsToCache);
})
);
});

// 요청을 가로채고 캐시에서 리소스를 제공
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});

// 오래된 캐시를 삭제
self.addEventListener('activate', (event) => {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName);
}
})
);
})
);
});
25 changes: 25 additions & 0 deletions src/assets/icon/Bookmark.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';

const Bookmark = () => {
return (
<svg
width="33"
height="34"
viewBox="0 0 33 34"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="majesticons:bookmark">
<path
id="Vector"
fill-rule="evenodd"
clip-rule="evenodd"
d="M9.625 3.25C8.53098 3.25 7.48177 3.6846 6.70818 4.45818C5.9346 5.23177 5.5 6.28098 5.5 7.375V28.1898C5.49988 28.551 5.59466 28.906 5.77487 29.2192C5.95508 29.5323 6.21438 29.7927 6.52683 29.9741C6.83927 30.1555 7.19389 30.2517 7.55519 30.2529C7.91648 30.2542 8.27178 30.1606 8.5855 29.9814L15.818 25.8481C16.0257 25.7295 16.2608 25.6671 16.5 25.6671C16.7392 25.6671 16.9743 25.7295 17.182 25.8481L24.4145 29.9814C24.7282 30.1606 25.0835 30.2542 25.4448 30.2529C25.8061 30.2517 26.1607 30.1555 26.4732 29.9741C26.7856 29.7927 27.0449 29.5323 27.2251 29.2192C27.4053 28.906 27.5001 28.551 27.5 28.1898V7.375C27.5 6.28098 27.0654 5.23177 26.2918 4.45818C25.5182 3.6846 24.469 3.25 23.375 3.25H9.625Z"
fill="black"
/>
</g>
</svg>
);
};

export default Bookmark;
5 changes: 5 additions & 0 deletions src/assets/icon/Down.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 src/assets/image/Tomato.png
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 src/assets/image/Tomato2.png
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 src/assets/image/Tomato3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 13 additions & 6 deletions src/components/MenuBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,31 @@ import Profile from 'assets/icon/Profile';
import Register from 'assets/icon/Register';
import { theme } from 'lib/utils/style/theme';
import * as _ from './style';
import { useNavigate } from 'react-router-dom';

interface MenuBarProps {
selectState: number;
setSelectState: (id: number) => void;
}

const MenuBar = ({ selectState, setSelectState }: MenuBarProps) => {
const navigate = useNavigate();
const menuItems = [
{ id: 1, label: '홈', Icon: Home },
{ id: 2, label: '등록하기', Icon: Register },
{ id: 3, label: '알림', Icon: Alarm },
{ id: 4, label: '프로필', Icon: Profile }
{ id: 1, label: '홈', Icon: Home, location: '/' },
{ id: 2, label: '등록하기', Icon: Register, location: '/' },
{ id: 3, label: '알림', Icon: Alarm, location: '/' },
{ id: 4, label: '프로필', Icon: Profile, location: '/' }
];

const onTabClick = (id: number, location: string) => {
navigate(location);
setSelectState(id);
};

return (
<_.MenuBar_Container>
{menuItems.map(({ id, label, Icon }) => (
<_.Menubar_Icon key={id} onClick={() => setSelectState(id)}>
{menuItems.map(({ id, label, Icon, location }) => (
<_.Menubar_Icon key={id} onClick={() => onTabClick(id, location)}>
<Icon
color={selectState === id ? theme.green[400] : theme.grey[500]}
/>
Expand Down
23 changes: 22 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
@font-face {
font-family: 'Pretendard';
src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}

@font-face {
font-family: 'Pretendard';
src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-SemiBold.woff') format('woff');
font-weight: 600;
font-style: normal;
}

@font-face {
font-family: 'Pretendard';
src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
}

* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Pretendard';
}
}
111 changes: 111 additions & 0 deletions src/pages/GoodsDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* eslint-disable */
import React, { useState } from 'react';
import * as S from './style';
import Bookmark from 'assets/icon/Bookmark';
import BackIcon from 'assets/icon/BackIcon';
import Tomato1 from 'assets/image/Tomato.png';
import Tomato2 from 'assets/image/Tomato2.png'
import Tomato3 from 'assets/image/Tomato3.png'
import { Carousel } from 'react-responsive-carousel';
import { useNavigate } from 'react-router-dom';

const GoodsDetail = () => {
const navigate = useNavigate();
const [currentIndex, setCurrentIndex] = useState(0);
const countData = [10, 30, 50, 100];
const goodsInfoData = [
{ category: '상품번호', value: '9382837263529483' },
{ category: '제조사', value: '할아버지 컴퍼니' },
{ category: '상품상태', value: 'A등급' },
{ category: '원산지', value: '충청남도 아산시' }
];
const imageData = [
{
label: 'Image 1',
alt: 'image1',
url: Tomato1
},

{
label: 'Image 2',
alt: 'image2',
url: Tomato2
},

{
label: 'Image 3',
alt: 'image3',
url: Tomato3
}
];

const handleChange = (index: number) => {
setCurrentIndex(index);
};

const renderSlides = imageData.map((image) => (
<S.MainSlide key={image.alt}>
<S.GoodsImg src={image.url} alt={image.alt} />
</S.MainSlide>
));

return (
<S.Layout>
<S.GoodsHeader>
<S.BackIconLayout onClick={() => navigate(-1)}>
<BackIcon />
</S.BackIconLayout>
</S.GoodsHeader>
<S.GoodsImgLayout>
<S.CustomCarousel>
<Carousel
showArrows={false}
autoPlay={true}
showThumbs={false}
selectedItem={currentIndex}
onChange={handleChange}
showStatus={false}
>
{renderSlides}
</Carousel>
</S.CustomCarousel>
</S.GoodsImgLayout>
<S.GoodsInfo>
<S.TitleNRating>
<S.Rating>A등급</S.Rating>
<S.Price>
3,600<S.Semibold>원</S.Semibold>
</S.Price>
</S.TitleNRating>
<S.TitleLayout>
<S.KoreanTitle>할아버지가 직접 키운 토마토</S.KoreanTitle>
<S.EnglishTitle>Produce grown by my grandfather</S.EnglishTitle>
</S.TitleLayout>
</S.GoodsInfo>
<S.CountWrapper>
<S.CountLayout>
<S.CountOption>수량</S.CountOption>
{countData.map((item) => (
<S.CountOption>{item}개</S.CountOption>
))}
</S.CountLayout>
</S.CountWrapper>
<S.GoodsInfoDetail>
{goodsInfoData.map((item) => (
<S.Row>
<S.Attribute>{item.category}</S.Attribute>
<S.Content>{item.value}</S.Content>
</S.Row>
))}
</S.GoodsInfoDetail>
<S.GoodsFooter>
<S.FooterContent>
<Bookmark />
<S.Perchase>구매</S.Perchase>
</S.FooterContent>
</S.GoodsFooter>
</S.Layout>
);
};

export default GoodsDetail;
Loading
Loading