Skip to content
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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"@tanstack/react-query": "^5.66.9",
"@tosspayments/widget-sdk-react-native": "^1.3.5",
"@types/react-native-vector-icons": "^6.4.18",
"@ummgoban/shared": "^0.0.6-nightly.20250808.a3cf0f6",
"@ummgoban/shared": "^0.0.6-nightly.20250812.4b293fc",
"axios": "^1.7.4",
"dayjs": "^1.11.13",
"react": "18.3.1",
Expand All @@ -61,6 +61,7 @@
"react-native-splash-screen": "^3.3.0",
"react-native-svg": "^15.8.0",
"react-native-vector-icons": "^10.1.0",
"react-native-webview": "^13.15.0",
"tosspayments-react-native-webview": "^1.0.0",
"zustand": "^5.0.3"
},
Expand Down
1 change: 1 addition & 0 deletions react-native-config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ declare module 'react-native-config' {
NAVER_CONSUMER_SECRET_KEY: string;
TOSS_CLIENT_KEY: string;
TOSS_CUSTOMER_KEY: string;
WEBVIEW_URL: string;
}

export const Config: NativeConfig;
Expand Down
9 changes: 9 additions & 0 deletions src/apis/auth/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ import {
} from './model';

import CustomError from '../CustomError';
import {getStorage} from '@/utils/storage';
import {SessionType} from '@ummgoban/shared';

export const useSession = () =>
useQuery({
queryKey: ['session'],
queryFn: async (): Promise<SessionType | null> =>
await getStorage('session'),
});

export const useProfileQuery = () =>
useQuery({
Expand Down
8 changes: 2 additions & 6 deletions src/components/common/Appbar/AppbarOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import React from 'react';

import {StackNavigationOptions} from '@react-navigation/stack';

import ChevronLeft from '@/assets/icons/chevron-left.svg';
import {BackIcon} from './BackIcon';

export const defaultOptions: StackNavigationOptions = {
headerShown: true,
headerTitleAlign: 'left' as const,
headerBackTitleVisible: false,
headerBackImage: ({tintColor}) => (
<ChevronLeft color={tintColor} width={24} height={24} />
),
headerLeft: BackIcon,
};
64 changes: 64 additions & 0 deletions src/components/common/Appbar/BackIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';
import styled from '@emotion/native';

import {useWebViewHistoryStore} from '@/webview';

import ChevronLeft from '@/assets/icons/chevron-left.svg';
import {RootStackParamList} from '@/types/StackNavigationType';
import {useNavigation} from '@react-navigation/native';
import {
StackNavigationOptions,
StackNavigationProp,
} from '@react-navigation/stack';

const S = {
Container: styled.View`
display: flex;
align-items: center;
justify-content: center;

width: 48px;
height: 48px;
padding: 8px;
`,
Icon: styled(ChevronLeft)`
width: 24px;
height: 24px;
`,
};

export const BackIcon: StackNavigationOptions['headerLeft'] = ({
tintColor,
canGoBack,
}) => {
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
const {history, setHistory} = useWebViewHistoryStore();

if (!canGoBack && !history) {
return undefined;
}

return (
<S.Container>
<S.Icon
color={tintColor}
width={24}
height={24}
onPress={() => {
setHistory(undefined);
if (history) {
navigation.navigate(history.screen, {
screen: history.screen,
params: history.params,
webview: {
uri: history.webUri,
},
});
return;
}
navigation.goBack();
}}
/>
</S.Container>
);
};
5 changes: 5 additions & 0 deletions src/components/common/Appbar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import CartNavigatorIcon from './CartNavigatorIcon';
import SettingsNavigatorIcon from './SettingsNavigatorIcon';
import HeaderTitle from './HeaderTitle';

export {CartNavigatorIcon, SettingsNavigatorIcon, HeaderTitle};
6 changes: 2 additions & 4 deletions src/components/map/MyLocationMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {StackNavigationProp} from '@react-navigation/stack';
import {RootStackParamList} from '@/types/StackNavigationType';

import S from './MyLocationMap.style';
import {routeToDetail} from '@/navigation/navigator';

const MyLocationMap = ({
cords,
Expand All @@ -20,10 +21,7 @@ const MyLocationMap = ({
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
const handleMarkerClick = (marketId: number) => {
if (marketId !== -1) {
navigation.navigate('Detail', {
screen: 'MarketDetail',
params: {marketId},
});
routeToDetail(navigation, marketId);
}
};
return (
Expand Down
12 changes: 4 additions & 8 deletions src/components/marketDetailPage/Menu.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,17 @@ const MenuInfoWrapper = styled.View`

const MenuoriginPrice = styled.Text`
color: var(--gray-gray5, #979797);
font-size: 14px;
font-weight: 400;
${({theme}) => theme.fonts.body2}

text-decoration-line: line-through;
`;
const MenuDiscountPrice = styled.Text`
color: #2d3e39;
font-size: 16px;

font-weight: 700;
${({theme}) => theme.fonts.body2}
`;
const MenuStockCount = styled.Text`
color: green;
font-size: 16px;
font-weight: 700;
color: ${props => props.theme.colors.tertiary};
${({theme}) => theme.fonts.body2}
`;
const MenuBoxRight = styled.View`
display: flex;
Expand Down
8 changes: 3 additions & 5 deletions src/components/marketDetailPage/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ const Menu = ({product, initCount, onCountChange, isCart}: Props) => {
{product.originPrice !== product.discountPrice ? (
<S.MenuInfoWrapper>
<S.MenuoriginPrice>
{`정가: ${product.originPrice.toLocaleString()}원`}
{product.originPrice.toLocaleString()}원
</S.MenuoriginPrice>
<S.MenuDiscountPrice>
{`할인가: ${product.discountPrice.toLocaleString()}원`}
{product.discountPrice.toLocaleString()}원
</S.MenuDiscountPrice>
</S.MenuInfoWrapper>
) : (
<S.MenuDiscountPrice>
{`정가: ${product.originPrice.toLocaleString()}원`}
{product.originPrice.toLocaleString()}원
</S.MenuDiscountPrice>
)}
<S.MenuStockWrapper>
Expand All @@ -98,8 +98,6 @@ const Menu = ({product, initCount, onCountChange, isCart}: Props) => {
) : (
<S.MenuSoldOutText>{`현재 재고가 없어요`}</S.MenuSoldOutText>
)}

<S.MenuStockCount>{`${!isCart ? '' : `수량: ${product.count}`}`}</S.MenuStockCount>
</S.MenuStockWrapper>
{isCart && (
<S.MenuDeleteButtonWrapper onPress={deleteMenu}>
Expand Down
5 changes: 2 additions & 3 deletions src/components/orderDetail/OrderDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {to6DigitHash} from '@ummgoban/shared';
import {DetailStackParamList} from '@/types/StackNavigationType';

import S from './OrderDescription.style';
import {routeToDetail} from '@/navigation/navigator';

type Props = {
id: string;
Expand Down Expand Up @@ -48,9 +49,7 @@ const OrderCustomerInfo = ({id, navigation, orderDetail}: Props) => {
<S.Container>
<S.OrderStatusText>{orderStatusText}</S.OrderStatusText>
<S.MarketInformation
onPress={() =>
navigation.navigate('MarketDetail', {marketId: orderDetail.marketId})
}>
onPress={() => routeToDetail(navigation, orderDetail.marketId)}>
<S.MarketName>{orderDetail.marketName}</S.MarketName>
<S.MarketAddress>{orderDetail.address}</S.MarketAddress>
</S.MarketInformation>
Expand Down
2 changes: 1 addition & 1 deletion src/navigation/DetailNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React from 'react';

import {defaultOptions} from '@/components/common/Appbar/AppbarOptions';
import HeaderTitle from '@/components/common/Appbar/HeaderTitle';
import CartIcon from '@/components/common/CartNavigatorIcon';
import CartIcon from '@/components/common/Appbar/CartNavigatorIcon';

import MarketDetailScreen from '@/screens/MarketDetailScreen';
import OrderDetailScreen from '@/screens/OrderDetailScreen';
Expand Down
2 changes: 1 addition & 1 deletion src/navigation/FeedNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
import React from 'react';

import HeaderTitle from '@/components/common/Appbar/HeaderTitle';
import CartIcon from '@/components/common/CartNavigatorIcon';
import CartIcon from '@/components/common/Appbar/CartNavigatorIcon';
import {defaultOptions} from '@/components/common/Appbar/AppbarOptions';

import MapScreen from '@/screens/MapScreen';
Expand Down
4 changes: 2 additions & 2 deletions src/navigation/HomeNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
import React from 'react';

import HeaderTitle from '@/components/common/Appbar/HeaderTitle';
import CartIcon from '@/components/common/CartNavigatorIcon';
import SettingsIcon from '@/components/common/SettingsNavigatorIcon';
import CartIcon from '@/components/common/Appbar/CartNavigatorIcon';
import SettingsIcon from '@/components/common/Appbar/SettingsNavigatorIcon';
import {TabBar} from '@components/common';

import OrderHistoryScreen from '@/screens/OrderHistoryScreen';
Expand Down
17 changes: 12 additions & 5 deletions src/navigation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@ import RegisterNavigator from './RegisterNavigator';
import DetailNavigator from './DetailNavigator';
import CartNavigator from './CartNavigator';
import MyPageNavigator from './MyPageNavigator';
import withWebViewGate from './withWebViewGate';

import {RootStackParamList} from '@/types/StackNavigationType';

const Stack = createStackNavigator<RootStackParamList>();

const HomeWithGate = withWebViewGate(HomeNavigator);
const RegisterWithGate = withWebViewGate(RegisterNavigator);
const DetailWithGate = withWebViewGate(DetailNavigator);
const CartWithGate = withWebViewGate(CartNavigator);
const MyPageWithGate = withWebViewGate(MyPageNavigator);

const AppNavigator = () => {
/** omit top, because of `@react-navigation/stack` appbar containing top safe area */
// const {left, right, bottom} = useSafeAreaInsets();
Expand All @@ -19,11 +26,11 @@ const AppNavigator = () => {
<Stack.Navigator
initialRouteName="Home"
screenOptions={{headerShown: false}}>
<Stack.Screen name="Home" component={HomeNavigator} />
<Stack.Screen name="Register" component={RegisterNavigator} />
<Stack.Screen name="Detail" component={DetailNavigator} />
<Stack.Screen name="CartRoot" component={CartNavigator} />
<Stack.Screen name="MyPageRoot" component={MyPageNavigator} />
<Stack.Screen name="Home" component={HomeWithGate} />
<Stack.Screen name="Register" component={RegisterWithGate} />
<Stack.Screen name="Detail" component={DetailWithGate} />
<Stack.Screen name="CartRoot" component={CartWithGate} />
<Stack.Screen name="MyPageRoot" component={MyPageWithGate} />
</Stack.Navigator>
);
};
Expand Down
32 changes: 32 additions & 0 deletions src/navigation/navigator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {StackNavigationProp} from '@react-navigation/stack';

import {
DetailStackParamList,
FeedStackParamList,
HomeStackParamList,
MyPageStackParamList,
RegisterStackParamList,
RootStackParamList,
} from '@/types/StackNavigationType';
import Config from 'react-native-config';

export function routeToDetail(
navigation: StackNavigationProp<
| RootStackParamList
| HomeStackParamList
| FeedStackParamList
| RegisterStackParamList
| DetailStackParamList
| MyPageStackParamList
>,
marketId: number,
) {
navigation.navigate('Detail', {
screen: 'MarketDetail',
params: {marketId},
webview: {
uri: `${Config.WEBVIEW_URL}/market/${marketId}`,
title: `맘찬픽 가게`,
},
});
}
20 changes: 20 additions & 0 deletions src/navigation/withWebViewGate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';

import {WebViewScreen} from '@/webview/WebViewScreen';

type RouteWithWeb = {params: {webview?: {uri: string; title?: string}}};

const withWebViewGate = <P extends {route?: RouteWithWeb}>(
NavigatorComponent: React.ComponentType<P>,
) => {
return function WebViewGateComponent(props: P) {
const webview = props.route?.params?.webview;

if (webview?.uri) {
return <WebViewScreen {...webview} />;
}
return <NavigatorComponent {...props} />;
};
};

export default withWebViewGate;
8 changes: 2 additions & 6 deletions src/screens/CustomerReviewScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import S from './CustomerReviewScreen.style';
import {CustomerReviewCard} from '@/components/common/customerReview';
import {ActivityIndicator} from 'react-native-paper';
import EmptyComponent from '@/components/common/EmptyComponent';
import {routeToDetail} from '@/navigation/navigator';

type CustomerReviewScreenProps = StackScreenProps<
MyPageStackParamList,
Expand Down Expand Up @@ -49,12 +50,7 @@ const CustomerReviewScreen = ({
}

const navigateMarketDetail = (marketId: number) => {
navigation.navigate('Detail', {
screen: 'MarketDetail',
params: {
marketId: marketId,
},
});
routeToDetail(navigation, marketId);
};

if (reviews.length === 0) {
Expand Down
9 changes: 4 additions & 5 deletions src/screens/FeedScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import {useMarketList} from '@/apis/markets';
import FeedBottomFloatingButton from '@/components/common/FeedBottomFloatingButton';
import {Market} from '@/components/feedPage';

import usePullDownRefresh from '@/hooks/usePullDownRefresh';
import useGPSLocation from '@/hooks/useGPSLocation';
import usePullDownRefresh from '@/hooks/usePullDownRefresh';

import {RootStackParamList} from '@/types/StackNavigationType';

import {routeToDetail} from '@/navigation/navigator';

import S from './Feed.style';

type Props = {
Expand All @@ -36,10 +38,7 @@ const FeedScreen = ({navigation}: Props) => {
const marketList = data ? data.pages.flatMap(page => page.markets) : [];

const onPressStore = (marketId: number) => {
navigation.navigate('Detail', {
screen: 'MarketDetail',
params: {marketId},
});
routeToDetail(navigation, marketId);
};

const navigateMap = () => {
Expand Down
Loading