diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index e9a241d..6475f87 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -53,7 +53,7 @@ jobs:
CACHE_HIT="${{ steps.yarn-cache.outputs.cache-hit }}"
NODE_MODULES_EXISTS=$(test -d "node_modules" && echo "true" || echo "false")
if [[ "$CACHE_HIT" != 'true' || "$NODE_MODULES_EXISTS" == 'false' ]]; then
- sh ./.script/ci.sh
+ yarn install
fi
- name: Lint check
diff --git a/.npmrc b/.npmrc
deleted file mode 100644
index 7586b3b..0000000
--- a/.npmrc
+++ /dev/null
@@ -1,2 +0,0 @@
-@ummgoban:registry=https://npm.pkg.github.com/
-//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
diff --git a/.script/ci.sh b/.script/ci.sh
deleted file mode 100644
index b5bd0d3..0000000
--- a/.script/ci.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-sh ./.script/pre-install.sh
-
-yarn install
-
-sh ./.script/post-install.sh
diff --git a/.script/post-install.sh b/.script/post-install.sh
deleted file mode 100644
index 3627d3e..0000000
--- a/.script/post-install.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-echo "=== postinstall ==="
-
-# .yarnrc.yml.temp 가 없으면 종료
-if [ ! -f .yarnrc.yml.temp ]; then
- echo "No .yarnrc.yml.temp file found"
- exit 0
-fi
-
-# 원본 복구
-cp .yarnrc.yml.temp .yarnrc.yml
-
-# 임시 파일 삭제
-rm .yarnrc.yml.temp
\ No newline at end of file
diff --git a/.script/pre-install.sh b/.script/pre-install.sh
deleted file mode 100644
index 8e0f78a..0000000
--- a/.script/pre-install.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-echo "=== preinstall ==="
-
-# 원본 유지
-cp .yarnrc.yml .yarnrc.yml.temp
-
-NPM_TOKEN=$(grep NPM_TOKEN .env | cut -d '=' -f2 | tr -d '"' | xargs) envsubst < .yarnrc.yml.template > .yarnrc.yml
diff --git a/.yarnrc.yml.template b/.yarnrc.yml.template
deleted file mode 100644
index 7e52b02..0000000
--- a/.yarnrc.yml.template
+++ /dev/null
@@ -1,12 +0,0 @@
-nodeLinker: node-modules
-
-yarnPath: .yarn/releases/yarn-3.6.4.cjs
-
-npmScopes:
- ummgoban:
- npmRegistryServer: 'https://npm.pkg.github.com'
-
-npmRegistries:
- 'https://npm.pkg.github.com':
- npmAlwaysAuth: true
- npmAuthToken: '${NPM_TOKEN}'
\ No newline at end of file
diff --git a/package.json b/package.json
index e829245..246a5af 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,7 @@
"@react-navigation/native": "^6.1.18",
"@react-navigation/stack": "^6.4.1",
"@tanstack/react-query": "^5.66.9",
- "@ummgoban/shared": "0.0.1-alpha.6",
+ "@ummgoban/shared": "^0.0.5-250804.0",
"axios": "^1.7.4",
"dayjs": "^1.11.13",
"react": "18.3.1",
diff --git a/src/components/common/Checkbox/SquareCheckbox.style.tsx b/src/components/common/Checkbox/SquareCheckbox.style.tsx
new file mode 100644
index 0000000..4331016
--- /dev/null
+++ b/src/components/common/Checkbox/SquareCheckbox.style.tsx
@@ -0,0 +1,23 @@
+import styled from '@emotion/native';
+
+const S = {
+ Container: styled.View`
+ display: flex;
+ background-color: ${({theme}) => theme.colors.secondary};
+
+ border-radius: 8px;
+ justify-content: center;
+ align-items: center;
+ width: 32px;
+ height: 32px;
+ `,
+
+ TouchWrapper: styled.Pressable`
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+ `,
+};
+
+export default S;
diff --git a/src/components/common/Checkbox/SquareCheckbox.tsx b/src/components/common/Checkbox/SquareCheckbox.tsx
new file mode 100644
index 0000000..0cbbe7b
--- /dev/null
+++ b/src/components/common/Checkbox/SquareCheckbox.tsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import Icon from 'react-native-vector-icons/Entypo';
+import S from './SquareCheckbox.style';
+
+type SquareCheckboxProps = {
+ checked: boolean;
+ onPress: () => void;
+ size?: number;
+ color?: string;
+};
+
+const SquareCheckbox = ({
+ checked,
+ onPress,
+ size = 18,
+ color = 'black',
+}: SquareCheckboxProps) => {
+ return (
+
+
+ {checked && }
+
+
+ );
+};
+
+export default SquareCheckbox;
diff --git a/src/components/common/Checkbox/index.ts b/src/components/common/Checkbox/index.ts
new file mode 100644
index 0000000..eee3cce
--- /dev/null
+++ b/src/components/common/Checkbox/index.ts
@@ -0,0 +1 @@
+export {default as SquareCheckbox} from './SquareCheckbox';
diff --git a/src/components/common/TextInput/TextInput.style.tsx b/src/components/common/TextInput/TextInput.style.tsx
index 22d7735..2a9d471 100644
--- a/src/components/common/TextInput/TextInput.style.tsx
+++ b/src/components/common/TextInput/TextInput.style.tsx
@@ -34,7 +34,6 @@ const S = {
ErrorText: styled(Text)`
color: ${({theme}) => theme.colors.error};
-
font-family: Pretendard;
font-size: 14px;
font-style: normal;
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index b5c1071..f71b8c4 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -4,3 +4,5 @@ export {default as BottomButton} from './BottomButton';
export {default as Label} from './Label';
export {ToggleButton, ToggleButtonGroup} from './ToggleButton';
+
+export {SquareCheckbox} from './Checkbox';
diff --git a/src/screens/MarketInfoScreen/MarketInfoScreen.style.tsx b/src/screens/MarketInfoScreen/MarketInfoScreen.style.tsx
index 866cc75..b3ffeda 100644
--- a/src/screens/MarketInfoScreen/MarketInfoScreen.style.tsx
+++ b/src/screens/MarketInfoScreen/MarketInfoScreen.style.tsx
@@ -1,5 +1,5 @@
import styled from '@emotion/native';
-import {Button, Text} from 'react-native-paper';
+import {Button} from 'react-native-paper';
export const HORIZONTAL_MARGIN = 16;
export const IMAGE_CARD_GAP = 8;
@@ -8,6 +8,7 @@ const S = {
Container: styled.View`
flex: 1;
`,
+
ScrollView: styled.ScrollView`
padding: 16px;
@@ -21,19 +22,75 @@ const S = {
gap: 8px;
`,
+ BusinessTimeInput: styled.View`
+ padding: 12px 40px;
+ `,
+
+ TimeHeader: styled.View`
+ flex-direction: row;
+ align-items: center;
+ margin-bottom: 4px;
+ padding: 0 12px;
+ `,
+
+ DayHeaderText: styled.Text`
+ flex: 1;
+ text-align: left;
+ padding-left: 4px;
+ ${({theme}) => theme.fonts.body2}
+ `,
+
+ TimeHeaderText: styled.Text`
+ ${({theme}) => theme.fonts.body2}
+ flex: 1;
+ text-align: center;
+ `,
+
+ ClosedHeaderText: styled.Text`
+ flex: 1;
+ ${({theme}) => theme.fonts.body2}
+ text-align: right;
+ margin-left: 0px;
+ `,
+
TimeContainer: styled.View`
- display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin-bottom: 4px;
+ padding: 0 8px;
+ `,
+
+ DayText: styled.Text`
+ flex: 1;
+ ${({theme}) => theme.fonts.body2};
+ text-align: left;
+ `,
+
+ TimeRange: styled.View`
+ flex: 1;
flex-direction: row;
align-items: center;
justify-content: center;
`,
- TimePickerButton: styled(Button)``,
+ ClosedCheckboxWrapper: styled.View`
+ display: flex;
+ flex: 1;
+ align-items: flex-end;
+ `,
+
+ ClosedCheckboxContainer: styled.View`
+ width: 36px;
+ justify-content: center;
+ align-items: center;
+ background-color: white;
+ border-radius: 8px;
+ margin: 4px;
+ `,
- BusinessTimeInput: styled.View``,
+ TimePickerButton: styled(Button)``,
ImageCardGrid: styled.View`
- display: flex;
flex-direction: row;
flex-wrap: wrap;
@@ -42,17 +99,12 @@ const S = {
margin: 16px 0;
`,
- DayText: styled(Text)`
- ${({theme}) => theme.fonts.body2}
- `,
-
ImageCardPlusButton: styled(Button)`
border: 1px solid #e0e0e0;
-
width: 100%;
-
margin: 16px 0;
`,
+
ImageCard: styled.View<{width: number}>`
position: relative;
@@ -65,6 +117,7 @@ const S = {
box-sizing: border-box;
+ height: 92px;
border: 1px solid #e0e0e0;
`,
@@ -83,9 +136,8 @@ const S = {
border-radius: 16px;
- background-color: #fff;
-
display: flex;
+ background-color: #fff;
justify-content: center;
align-items: center;
`,
diff --git a/src/screens/MarketInfoScreen/index.tsx b/src/screens/MarketInfoScreen/index.tsx
index ab3be1f..056860e 100644
--- a/src/screens/MarketInfoScreen/index.tsx
+++ b/src/screens/MarketInfoScreen/index.tsx
@@ -7,7 +7,7 @@ import {RefreshControl} from 'react-native-gesture-handler';
import {Text} from 'react-native-paper';
import {updateMarketInfo} from '@/apis/Market';
-import {BottomButton, Label} from '@/components/common';
+import {BottomButton, SquareCheckbox, Label} from '@/components/common';
import EmptyMarket from '@/components/common/EmptyMarket';
import NonRegister from '@/components/common/NonRegister';
import TextInput from '@/components/common/TextInput/TextInput';
@@ -16,33 +16,14 @@ import usePullDownRefresh from '@/hooks/usePullDownRefresh';
import {RootStackParamList} from '@/types/StackNavigationType';
import {format} from '@/utils/date';
-import {OpenHour, Weekday} from '@/types/Market';
+import {WEEKDAYS, OpenHour, dayMap} from '@ummgoban/shared';
+
import {useQueryClient} from '@tanstack/react-query';
import S from './MarketInfoScreen.style';
import {useReadManagers} from '@/apis/managers';
import ManagerLists from '@/components/manager/ManagerLists';
import useMarket from '@/hooks/useMarket';
-const WEEKDAYS: Weekday[] = [
- 'MONDAY',
- 'TUESDAY',
- 'WEDNESDAY',
- 'THURSDAY',
- 'FRIDAY',
- 'SATURDAY',
- 'SUNDAY',
-];
-
-const dayMap: Record = {
- MONDAY: '월요일',
- TUESDAY: '화요일',
- WEDNESDAY: '수요일',
- THURSDAY: '목요일',
- FRIDAY: '금요일',
- SATURDAY: '토요일',
- SUNDAY: '일요일',
-};
-
const MarketInfoScreen = () => {
const {profile} = useProfile();
const queryClient = useQueryClient();
@@ -79,27 +60,26 @@ const MarketInfoScreen = () => {
const [openHours, setOpenHours] = useState(
WEEKDAYS.map(day => ({
dayOfWeek: day,
- openTime: null,
- closeTime: null,
+ openTime: '',
+ closeTime: '',
})),
);
useEffect(() => {
if (marketInfo) {
- setSummary(marketInfo.summary);
setMarketName(marketInfo.name);
+ setSummary(marketInfo.summary);
+
+ const newOpenHours = WEEKDAYS.map(day => {
+ const found = marketInfo.openHours.find(h => h.dayOfWeek === day);
- if (marketInfo.openHours?.length) {
- const newOpenHours = WEEKDAYS.map(day => {
- const found = marketInfo.openHours.find(h => h.dayOfWeek === day);
- return {
- dayOfWeek: day,
- openTime: found ? new Date(`2024-01-01T${found.openTime}`) : null,
- closeTime: found ? new Date(`2024-01-01T${found.closeTime}`) : null,
- };
- });
- setOpenHours(newOpenHours);
- }
+ return {
+ dayOfWeek: day,
+ openTime: found?.openTime ?? '',
+ closeTime: found?.closeTime ?? '',
+ };
+ });
+ setOpenHours(newOpenHours);
}
}, [marketInfo]);
@@ -133,29 +113,59 @@ const MarketInfoScreen = () => {
/>
{/* */}
{/* TODO: 스위치 버튼으로 임시 휴무 */}
+
+
-
- {openHours.map((item, idx) => (
-
- {dayMap[item.dayOfWeek]}:
- setOpenModal({type: 'open', index: idx})}
- disabled={!isEditPermission}>
- {item.openTime
- ? format((item.openTime as Date).getTime(), 'HH:mm')
- : '시작 시간'}
-
- {'~'}
- setOpenModal({type: 'close', index: idx})}
- disabled={!isEditPermission}>
- {item.closeTime
- ? format((item.closeTime as Date).getTime(), 'HH:mm')
- : '종료 시간'}
-
-
- ))}
+
+ 요일
+ 영업시간
+ 휴업
+
+
+ {openHours.map((item, idx) => {
+ const isClosed =
+ item.openTime === '00:00' && item.closeTime === '00:00';
+
+ return (
+
+ {dayMap[item.dayOfWeek]}
+
+
+ setOpenModal({type: 'open', index: idx})}
+ disabled={!isEditPermission || isClosed}>
+ {/* TODO: openHours.openTime 타입 string으로 고정 */}
+ {item.openTime as string}
+
+ ~
+ setOpenModal({type: 'close', index: idx})}
+ disabled={!isEditPermission || isClosed}>
+ {item.closeTime as string}
+
+
+
+ {
+ setOpenHours(prev => {
+ const updated = [...prev];
+ const target = updated[idx];
+ updated[idx] = {
+ ...target,
+ openTime: !isClosed ? '00:00' : '12:00',
+ closeTime: !isClosed ? '00:00' : '18:00',
+ };
+ return updated;
+ });
+ }}
+ />
+
+
+ );
+ })}
+
{/*
{
date={new Date('2025-01-01T08:00:00')}
onConfirm={date => {
if (openModal) {
+ const formatted = format(date.getTime(), 'HH:mm');
setOpenHours(prev => {
const updated = [...prev];
if (openModal.type === 'open') {
- updated[openModal.index].openTime = date;
+ updated[openModal.index].openTime = formatted;
} else {
- updated[openModal.index].closeTime = date;
+ updated[openModal.index].closeTime = formatted;
}
return updated;
});
}
setOpenModal(null);
}}
- onCancel={() => {
- setOpenModal(null);
- }}
+ onCancel={() => setOpenModal(null)}
minuteInterval={30}
cancelText="취소"
confirmText="확인"
title={
openModal
- ? `${openHours[openModal.index].dayOfWeek} ${
+ ? `${dayMap[openHours[openModal.index].dayOfWeek]} ${
openModal.type === 'open' ? '시작' : '종료'
} 시간`
: undefined
}
/>
+
{
+ console.log(openHours);
if (!summary || openHours.some(h => !h.openTime || !h.closeTime)) {
Alert.alert('필수 입력사항을 모두 입력해주세요.');
return;
@@ -297,8 +308,8 @@ const MarketInfoScreen = () => {
const openHoursPayload = openHours.map(h => ({
dayOfWeek: h.dayOfWeek,
- openTime: format((h.openTime! as Date).getTime(), 'HH:mm'),
- closeTime: format((h.closeTime! as Date).getTime(), 'HH:mm'),
+ openTime: h.openTime,
+ closeTime: h.closeTime,
}));
const res = await updateMarketInfo(marketInfo.id, {
diff --git a/src/types/Market.ts b/src/types/Market.ts
index a86d12b..7eff396 100644
--- a/src/types/Market.ts
+++ b/src/types/Market.ts
@@ -1,19 +1,4 @@
-import {ProductType} from '@ummgoban/shared';
-
-export type Weekday =
- | 'MONDAY'
- | 'TUESDAY'
- | 'WEDNESDAY'
- | 'THURSDAY'
- | 'FRIDAY'
- | 'SATURDAY'
- | 'SUNDAY';
-
-export type OpenHour = {
- dayOfWeek: Weekday;
- openTime: Date | string | null;
- closeTime: Date | string | null;
-};
+import {ProductType, OpenHour} from '@ummgoban/shared';
export type MarketType = {
id: number;
diff --git a/yarn.lock b/yarn.lock
index 39986db..7f1b48d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4131,12 +4131,14 @@ __metadata:
languageName: node
linkType: hard
-"@ummgoban/shared@npm:0.0.1-alpha.6":
- version: 0.0.1-alpha.6
- resolution: "@ummgoban/shared@npm:0.0.1-alpha.6::__archiveUrl=https%3A%2F%2Fnpm.pkg.github.com%2Fdownload%2F%40ummgoban%2Fshared%2F0.0.1-alpha.6%2Fb1e3599cd964a5e0fa7115ba0f4339c6d986ccd6"
+"@ummgoban/shared@npm:^0.0.5-250804.0":
+ version: 0.0.5-250804.0
+ resolution: "@ummgoban/shared@npm:0.0.5-250804.0"
peerDependencies:
+ axios: ">=1.7.4"
react: ">=18.0.0"
- checksum: e34d56624940aa68f23516f18cf2ab8648a8c87f692353f7055c0383fddd1bb6ae9ea0d6d99638357a0f8586b3c49ab83d66c8f7fd0cd5abd3b3615ff5eab4fd
+ react-native: ">=0.79.0"
+ checksum: b0892d9460ca71a841acd8a420c374a41e7c3c7c8c6cdfed1f41fb93a2b8cffdab8de054a4b7c5718517bcde0cf8efd30d7abcc4f476b419305b7276bd02a7eb
languageName: node
linkType: hard
@@ -4176,7 +4178,7 @@ __metadata:
"@types/react": ^18.2.6
"@types/react-native-vector-icons": ^6.4.18
"@types/react-test-renderer": ^18.0.0
- "@ummgoban/shared": 0.0.1-alpha.6
+ "@ummgoban/shared": ^0.0.5-250804.0
axios: ^1.7.4
babel-jest: ^29.6.3
babel-plugin-module-resolver: ^5.0.2