Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 가게 세부 페이지 찜버튼 추가 #68

Merged
merged 9 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions src/apis/Login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const signInWithKakao = async (): Promise<SessionType | null> => {
console.log('카카오 로그인 성공:', response);

return {
//TODO: JWT 토큰으로 대체 필요
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accessToken: token.accessToken,
refreshToken: token.refreshToken,
accessTokenExpiresAt: new Date(token.accessTokenExpiresAt).getTime(),
Expand Down
1 change: 1 addition & 0 deletions src/apis/MarketDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {MarketType} from '@/types/Market';
const dummyMarketDetail: MarketType = {
id: 1,
name: '반찬가게1',
isLike: false,
pickupStartAt: 1609718400000,
pickupEndAt: 1727622000000,
products: [
Expand Down
47 changes: 47 additions & 0 deletions src/components/common/SubscribeIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import {TouchableOpacity} from 'react-native';
import Icon from 'react-native-vector-icons/AntDesign';
import {CommonResponseType} from '@/types/CommonResponseType';
import apiClient from '@/apis/ApiClient';

type SubscribeIconProps = {
marketIsLiked: boolean;
marketId?: number;
handleSubscribe: () => void;
};

const SubscribeIcon = ({
marketIsLiked,
marketId,
handleSubscribe,
}: SubscribeIconProps) => {
const handleLikePress = async () => {
try {
let res;
if (marketIsLiked) {
console.log('DEL');
res = await apiClient.del<CommonResponseType | null>(
`/market/${marketId}/like`,
);
} else {
console.log('POST');
res = await apiClient.post<CommonResponseType | null>(
`/market/${marketId}/like`,
);
}
handleSubscribe();
return res;
} catch (error) {
console.error('Error subscribe', error);
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

각 서버에 요청을 보내는 코드들은 apis/ 폴더 아래에 파일을 선언해서 추가해주세요. apis/Market.ts에 함수들을 추가해주면 되겠네요. updateMarketLike 와 같은 함수이름으로 하면 좋겟습니다.

+ javascript에서 빈 객체({}) 또한 truly 이기 때문에 해당 코드는 res의 값이 타당하지 않을 수 있을 것 같습니다. 지금의 api문서에서 del은 200코드, post는 201 코드를 반환하니 코드가 타당한지로 판단하는 게 좋을 것 같네요.

스크린샷 2024-11-05 오후 1 36 10

+ 카톡으로 상민이형이랑 나눈 api endpoint관련해서는 확정되면 그렇게 수정하시죠.

};

return (
<TouchableOpacity onPress={handleLikePress}>
<Icon name={marketIsLiked ? 'heart' : 'hearto'} size={24} />
</TouchableOpacity>
);
};

export default SubscribeIcon;
14 changes: 14 additions & 0 deletions src/screens/MarketDetailScreen/MarketDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {ProductType} from '@/types/ProductType';
import {useNavigation} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import {RootStackParamList} from '@/types/StackNavigationType';
import SubscribeIcon from '@/components/common/SubscribeIcon';

type CartItem = {
productId: number;
Expand All @@ -29,6 +30,8 @@ const MarketDetailPage = ({
pickupEndAt,
address,
products,
isLike,
marketId,
}: Omit<MarketType, 'id' | 'images'>) => {
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
const [cart, setCart] = useState<CartItem[]>([]);
Expand All @@ -42,6 +45,7 @@ const MarketDetailPage = ({
{},
);
const [tagWidths, setTagWidths] = useState<{[key: string]: number}>({});
const [marketisLiked, setMarketisLiked] = useState<boolean>(isLike);
const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const handleCountChange = (productId: number, newCount: number) => {
handleCart(
Expand Down Expand Up @@ -209,6 +213,9 @@ const MarketDetailPage = ({
scrollToSection(tag);
};

const handleSubscribe = () => {
setMarketisLiked(prevState => !prevState);
};
const navigatePage = () => {
if (cart.length === 0) {
Alert.alert('장바구니가 비어 있습니다.');
Expand Down Expand Up @@ -253,6 +260,13 @@ const MarketDetailPage = ({
)} ~ ${format(pickupEndAt, 'HH시 mm분')}`}</S.MarketSideInfo>
<S.MarketSideInfo>{address}</S.MarketSideInfo>
</S.MarketSideInfoWrapper>
<View>
<SubscribeIcon
marketIsLiked={marketisLiked}
marketId={marketId}
handleSubscribe={handleSubscribe}
/>
</View>
<S.SideTagBarScrollView
horizontal
showsHorizontalScrollIndicator={false}
Expand Down
2 changes: 2 additions & 0 deletions src/screens/MarketDetailScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ const MarketDetailScreen = ({navigation, route}: Props) => {
return (
<MarketDetailPage
name={marketDetail.name}
isLike={marketDetail.isLike}
pickupStartAt={marketDetail.pickupStartAt}
pickupEndAt={marketDetail.pickupEndAt}
address={marketDetail.address}
products={marketDetail.products}
marketId={route.params.marketId}
/>
);
};
Expand Down
4 changes: 4 additions & 0 deletions src/types/CommonResponseType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type CommonResponseType = {
code: number;
message: string;
};
Copy link
Contributor

@99mini 99mini Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

response 타입까지 알 필요는 없을 것 같아요. 그래도 강력한 타입을 지원하려면 apiClient에서 선언하는 rest method의 구현에서 사용할 수는 있을 것 같습니다.

// CommonResponseType.ts
export type CommonResponseType<T> = {
  code: number;
  message: string;
  data?: T;
};
// ApiClient.ts
const get = async <T>(url: string): Promise<T | null> => {
  try {
    const res: AxiosResponse<CommonResponseType<T>> = await this.axiosInstance.get(url);

    if (res.data.code === 200 && res.data.data) {
      return res.data.data;
    }

    return null;
  } catch (error) {
    console.error(error);
    return null;
  }
};

3 changes: 3 additions & 0 deletions src/types/Market.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ export type MarketType = {
address: string;
products: ProductType[];
images: string[];
isLike: boolean;
// TODO: 논의 필요
marketId?: number;
Comment on lines +12 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id는 아마도 string 일것같아요

};
Loading