diff --git a/__tests__/utils/date.test.ts b/__tests__/utils/date.test.ts index 9a00aa75..35b63c5e 100644 --- a/__tests__/utils/date.test.ts +++ b/__tests__/utils/date.test.ts @@ -1,26 +1,24 @@ import {it, expect} from '@jest/globals'; -import date from '@utils/date'; +import {format, decimalToTime, zeroPad, isAfter} from '@utils/date'; it('should return format date', () => { const timestamp = 1618225200000; - expect(date.format(timestamp)).toBe('2021. 04. 12. (월)'); - expect(date.format(timestamp, 'YYYY년 M월 D일 (dd)')).toBe( - '2021년 4월 12일 (월)', - ); + expect(format(timestamp)).toBe('2021. 04. 12. (월)'); + expect(format(timestamp, 'YYYY년 M월 D일 (dd)')).toBe('2021년 4월 12일 (월)'); }); it('should return decimal to time', () => { - expect(date.decimalToTime(1.5)).toEqual([1, 30]); - expect(date.decimalToTime(1.75)).toEqual([1, 45]); + expect(decimalToTime(1.5)).toEqual([1, 30]); + expect(decimalToTime(1.75)).toEqual([1, 45]); }); it('should return zero pad', () => { - expect(date.zeroPad(1)).toBe('01'); - expect(date.zeroPad(10)).toBe('10'); + expect(zeroPad(1)).toBe('01'); + expect(zeroPad(10)).toBe('10'); }); it('should return is after', () => { - expect(date.isAfter(new Date(Date.now() - 10000))).toBe(true); - expect(date.isAfter(new Date(Date.now() + 10000))).toBe(false); + expect(isAfter(new Date(Date.now() - 10000))).toBe(true); + expect(isAfter(new Date(Date.now() + 10000))).toBe(false); }); diff --git a/package.json b/package.json index 4c0898e4..e11b0bfe 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "react": "18.3.1", "react-native": "0.75.2", "react-native-config": "^1.5.3", + "react-native-date-picker": "^5.0.7", "react-native-encrypted-storage": "^4.0.3", "react-native-gesture-handler": "^2.18.1", "react-native-paper": "^5.12.5", diff --git a/src/components/common/DatePicker.style.tsx b/src/components/common/DatePicker.style.tsx deleted file mode 100644 index 472180a0..00000000 --- a/src/components/common/DatePicker.style.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import styled from '@emotion/native'; -import {Chip} from 'react-native-paper'; - -const ChipContainer = styled.View` - flex-wrap: wrap; - flex-direction: row; - - gap: 8px; -`; - -const DateChip = styled(Chip)` - width: 84px; - height: 32px; - - background-color: ${props => - props.selected ? props.theme.colors.primary : '#f5f5f5'}; -`; - -const S = {ChipContainer, DateChip}; - -export default S; diff --git a/src/components/common/DatePicker.tsx b/src/components/common/DatePicker.tsx index 3660f8f5..22436aff 100644 --- a/src/components/common/DatePicker.tsx +++ b/src/components/common/DatePicker.tsx @@ -1,47 +1,22 @@ -import date from '@/utils/date'; -import React, {useState} from 'react'; -import S from './DatePicker.style'; +import React from 'react'; -type Props = { - onChange: (hour: number, minute: number) => void; - hour: number; - minute: number; - step?: number; - range?: [number, number]; -}; - -const DatePicker = ({ - onChange, - hour, - minute, - step = 30, - range = [0, 24], -}: Props) => { - const [selectedTime, setSelectedTime] = useState({hour, minute}); +import { + DatePickerProps, + default as RNDatePicker, +} from 'react-native-date-picker'; - const timeRange = Array.from( - {length: ((range[1] - range[0]) * 60) / step}, - (_, i) => range[0] + (i * step) / 60, - ); +type Props = {} & DatePickerProps; +const DatePicker = (props: Props) => { return ( - - {timeRange.map(time => { - const [h, m] = date.decimalToTime(time); - return ( - { - setSelectedTime({hour: h, minute: m}); - onChange(h, m); - }} - selected={h === selectedTime.hour && m === selectedTime.minute} - disabled={date.isAfter( - new Date(new Date().setHours(h, m, 0, 0)), - )}>{`${date.zeroPad(h)}:${date.zeroPad(m)}`} - ); - })} - + ); }; diff --git a/src/components/feedPage/Market.tsx b/src/components/feedPage/Market.tsx index a424baae..911dfafa 100644 --- a/src/components/feedPage/Market.tsx +++ b/src/components/feedPage/Market.tsx @@ -1,6 +1,6 @@ import {MarketType} from '@/types/Market'; import S from './Market.style'; -import date from '@utils/date'; +import {format} from '@utils/date'; import React from 'react'; type Props = { market: MarketType; @@ -21,10 +21,10 @@ const Market = ({market, onPress}: Props) => { {market.name} - {`픽업: ${date.format( + {`픽업: ${format( market.pickupStartAt, 'HH시 mm분', - )} ~ ${date.format(market.pickupEndAt, 'HH시 mm분')}`} + )} ~ ${format(market.pickupEndAt, 'HH시 mm분')}`} ); diff --git a/src/components/orderHistory/HistoryTimeline.tsx b/src/components/orderHistory/HistoryTimeline.tsx index e07c259a..1f62ad5b 100644 --- a/src/components/orderHistory/HistoryTimeline.tsx +++ b/src/components/orderHistory/HistoryTimeline.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import date from '@utils/date'; +import {format} from '@utils/date'; import S from './HistoryTimeline.style'; // TODO: 이미지 경로 수정 @@ -21,7 +21,7 @@ const HistoryTimeline = ({ {title} - {date.format(timestamp, 'HH시 mm분')} + {format(timestamp, 'HH시 mm분')} diff --git a/src/components/orderHistory/OrderHistory.tsx b/src/components/orderHistory/OrderHistory.tsx index 1d00ceaf..6d333ccb 100644 --- a/src/components/orderHistory/OrderHistory.tsx +++ b/src/components/orderHistory/OrderHistory.tsx @@ -1,9 +1,9 @@ import React from 'react'; import {Alert, Image} from 'react-native'; import {OrderType} from '@/types/OrderType'; -import date from '@utils/date'; import HistoryTimeline from './HistoryTimeline'; import S from './OrderHistory.style'; +import {format} from '@/utils/date'; const DESCRIPTION_MAX_LENGTH = 30; @@ -97,7 +97,7 @@ const OrderHistory = ({historyList, onPressMarket}: Props) => { - {`${date.format(order.createdAt)}${ + {`${format(order.createdAt)}${ status != null ? ` · ${status}` : '' }`} @@ -121,7 +121,7 @@ const OrderHistory = ({historyList, onPressMarket}: Props) => { timestamp={order.pendingAt} description={ order.doneAt == null - ? `${date.format( + ? `${format( order.pickupAt, 'HH시 mm분', )}까지 가게로 방문해주세요.` @@ -133,7 +133,7 @@ const OrderHistory = ({historyList, onPressMarket}: Props) => { { - const [reservedAt, setReservedAt] = useState({hour: 0, minute: 0}); + const now = new Date(); - // TODO: fetch marketPickupTime from server - const marketPickupAt: [number, number] = [18, 22]; + const [isOpen, setIsOpen] = useState(false); + const [reservedAt, setReservedAt] = useState(now); - const onChange = (hour: number, minute: number) => { - setReservedAt({hour, minute}); + const onConfirm = (date: Date) => { + setReservedAt(date); + setIsOpen(false); }; return ( - - 픽업 시간 + <> + + setIsOpen(true)}> + + {format(reservedAt.getTime(), 'a HH : mm')} + + + + {'으로 픽업 예약을 확정할게요'} + { + onConfirm(date); + setIsOpen(false); + }} + onCancel={() => setIsOpen(false)} /> - + ); }; diff --git a/src/screens/MarketDetailScreen/MarketDetailPage.tsx b/src/screens/MarketDetailScreen/MarketDetailPage.tsx index ad583b1c..f3a9a167 100644 --- a/src/screens/MarketDetailScreen/MarketDetailPage.tsx +++ b/src/screens/MarketDetailScreen/MarketDetailPage.tsx @@ -8,7 +8,7 @@ import { NativeScrollEvent, LayoutChangeEvent, } from 'react-native'; -import date from '@utils/date'; +import {format} from '@utils/date'; import Menu from '@/components/marketDetailPage/Menu'; import S from './MarketDetail.style'; import {MarketType} from '@/types/Market'; @@ -243,14 +243,14 @@ const MarketDetailPage = ({ 내 자식에게 준다는 마음으로 음식을 만들고 있습니다^^ - {`픽업 마감까지 ${date.format(pickupEndAt - Date.now(), 'HH시간 mm분')} 남았습니다!`} + {`픽업 마감까지 ${format(pickupEndAt - Date.now(), 'HH시간 mm분')} 남았습니다!`} - {`픽업: ${date.format( + {`픽업: ${format( pickupStartAt, 'HH시 mm분', - )} ~ ${date.format(pickupEndAt, 'HH시 mm분')}`} + )} ~ ${format(pickupEndAt, 'HH시 mm분')}`} {address} { - const [method, setMethod] = useState('toss'); const navigation = useNavigation>(); const {originalPrice, discountPrice} = useMemo( @@ -40,11 +32,7 @@ const PaymentPage = ({cart}: Props) => { - + {'// TODO: 결제수단 서버에서 받아와야 함'} = 17.0.1" + react-native: ">= 0.64.3" + checksum: 94191bf3ce6e88a3acc4ca5e5514eaa6fc15c61666393d85ca258dba3a3efd9145c8fd31ed0f18676d7f083e17f08c760de8193ad24367a65761330084bcdc6b + languageName: node + linkType: hard + "react-native-encrypted-storage@npm:^4.0.3": version: 4.0.3 resolution: "react-native-encrypted-storage@npm:4.0.3"