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
Binary file added public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions src/api/useGetAddress.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { api } from '@/lib/api'
import addressStore from '@/store/addressStore'
import memberStore from '@/store/user'
import { useQuery, useQueryClient } from '@tanstack/react-query'

Expand All @@ -24,13 +23,11 @@ export interface AddressResponseData {
const useGetAddress = () => {
const qc = useQueryClient()
const { member } = memberStore()
const { setAddress } = addressStore()

const { data: address, isSuccess } = useQuery({
queryKey: ['address'],
queryFn: async () => {
const response = await api.get<AddressResponseData>(`members/address`)
setAddress(response)

return response
},
Expand Down
3 changes: 0 additions & 3 deletions src/api/usePostLogout.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useLocalStorage } from '@/hooks/useLocalStorage'
import { api } from '@/lib/api'
import addressStore from '@/store/addressStore'
import memberStore from '@/store/user'
import { useMutation, useQueryClient } from '@tanstack/react-query'

Expand All @@ -9,7 +8,6 @@ const usePostLogout = () => {
const accessToken = useLocalStorage('accessToken')
const refreshToken = useLocalStorage('refreshToken')
const { resetMember } = memberStore()
const { resetAddress } = addressStore()

return useMutation({
mutationFn: async () =>
Expand All @@ -21,7 +19,6 @@ const usePostLogout = () => {
accessToken.resetValue()
refreshToken.resetValue()
resetMember()
resetAddress()
queryClient.removeQueries({ queryKey: ['member'] })
queryClient.removeQueries({ queryKey: ['favorites'] })
queryClient.removeQueries({ queryKey: ['carts'] })
Expand Down
Binary file removed src/app/favicon.ico
Binary file not shown.
3 changes: 3 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import './globals.css'
export const metadata: Metadata = {
title: '개발의민족',
description: '개발의민족',
icons: {
icon: '/favicon.png',
},
}

export const viewport = {
Expand Down
20 changes: 14 additions & 6 deletions src/app/mypage/address/_components/AddressOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import useDeleteAddress from '@/api/useDeleteAddress'
import useGetAddress, { AddressResponseData } from '@/api/useGetAddress'
import useGetAddressToGeolocation from '@/api/useGetAddressToGeolocation'
import useGetMember from '@/api/useGetMember'
import { AddressType } from '@/api/usePostAddress'
import usePostDefaultAddress from '@/api/usePostDefaultAddress'
import AddressSearchModal from '@/app/mypage/address/_components/AddressSearchModal'
Expand All @@ -15,9 +16,7 @@ import { useToast } from '@/hooks/useToast'
import { cn } from '@/lib/utils'
import { modalStore } from '@/store/modal'
import memberStore from '@/store/user'
import { ROUTE_PATHS } from '@/utils/routes'
import { useQueryClient } from '@tanstack/react-query'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import DaumPostcode from 'react-daum-postcode'
import AddressDetail, { AddressData } from '../detail/_components/AddressDetail'
Expand All @@ -26,17 +25,17 @@ const AddressOption = () => {
const [word, setWord] = useState('')
const [popup, setPopup] = useState(false)

const { member } = memberStore()
const { member, setMember } = memberStore()
const { showModal, hideModal } = modalStore()

const { mutate: deleteAddress, isPending: isPendingDeleting } = useDeleteAddress()
const { mutate: setDefaultAddress, isPending: isPendingSettingDefaultAddress } =
usePostDefaultAddress()
const { address } = useGetAddress()
const { mutate: addressToGeolocation } = useGetAddressToGeolocation()
const { refetch: refetchMember } = useGetMember()

const { toast } = useToast()
const router = useRouter()

const queryClient = useQueryClient()

Expand Down Expand Up @@ -88,14 +87,23 @@ const AddressOption = () => {
const handleClickSetDefaultAddress = (id: number | undefined) => {
if (!id || isPendingSettingDefaultAddress) return
if (id === address?.defaultAddress?.id) {
router.push(ROUTE_PATHS.HOME)
return
}

setDefaultAddress(id, {
onSuccess: () => {
router.push(ROUTE_PATHS.HOME)
refetchMember().then((res) => {
if (res.data) {
setMember(res.data)
}
})

queryClient.invalidateQueries({ queryKey: ['address'] })

toast({
title: '기본 주소가 변경되었습니다.',
position: 'center',
})
},
})
}
Expand Down
95 changes: 59 additions & 36 deletions src/app/pay/_components/OrderInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import usePostOrderPay, { OrderPay, OrderPayResponse, OrderPayType } from '@/api
import MenuItem from '@/app/pay/_components/MenuItem'
import Alert from '@/components/Alert'
import { Button } from '@/components/button'
import Confirm from '@/components/Confirm'
import Icon from '@/components/Icon'
import Separator from '@/components/Separator'
import { Checkbox } from '@/components/shadcn/checkbox'
import { Label } from '@/components/shadcn/label'
import useBottomSheet from '@/hooks/useBottomSheet'
import { useToast } from '@/hooks/useToast'
import { cn } from '@/lib/utils'
import addressStore from '@/store/addressStore'
import { modalStore } from '@/store/modal'
import memberStore from '@/store/user'
import { ROUTE_PATHS } from '@/utils/routes'
Expand All @@ -41,21 +41,35 @@ const OrderInfo = () => {

const { member } = memberStore()
const { showModal } = modalStore()
const { address } = addressStore()
// const { payments, setPayments } = successPaymentStore()

const { BottomSheet, hide } = useBottomSheet()
const { toast } = useToast()

const handleEmptyCart = () => {
if (!cartsState) return
const cartIds = cartsState.orderMenus.map((menu) => menu.cartId)
deleteCarts(
{ cartIds },
{
onSuccess: () => setCartsState(undefined),
}
)

showModal({
content: (
<Confirm
title="장바구니 비우기"
message="담은 메뉴를 모두 삭제할까요?"
confirmText="비우기"
onConfirmClick={() => {
const cartIds = cartsState.orderMenus.map((menu) => menu.cartId)
deleteCarts(
{ cartIds },
{
onSuccess: () => {
resetCarts()
setCartsState(undefined)
},
}
)
}}
/>
),
})
}
const handleIncreaseQuantity = (cartId: number) => {
const updateCartsState = (newQuantity: number) => {
Expand Down Expand Up @@ -138,7 +152,7 @@ const OrderInfo = () => {
}

const handleOrderPay = async () => {
if (!cartsState || !member || !address) {
if (!cartsState || !member) {
showModal({
content: (
<Alert
Expand All @@ -161,9 +175,9 @@ const OrderInfo = () => {

const orderData: OrderPay = {
storeId: cartsState.storeId,
roadAddress: address?.defaultAddress?.roadAddress || '',
jibunAddress: address?.defaultAddress?.jibunAddress || '',
detailAddress: address?.defaultAddress?.detailAddress || '',
roadAddress: member.address.roadAddress || '',
jibunAddress: member.address.jibunAddress || '',
detailAddress: member.address.detailAddress || '',
excludingSpoonAndFork: isExcludingSpoon,
orderType: 'DELIVERY',
// paymentType,
Expand Down Expand Up @@ -228,6 +242,11 @@ const OrderInfo = () => {
return
}

// 결제 시작 전 현재 URL을 히스토리에 추가
if (window.history && window.history.pushState) {
window.history.pushState(null, '', window.location.href)
}

if (paymentType === OrderPayType.PAY200) {
// SDK 초기화
const requestPayment = pay200SDK({
Expand Down Expand Up @@ -264,9 +283,9 @@ const OrderInfo = () => {
// customerMobilePhone: "01012341234",
card: {
useEscrow: false,
flowMode: 'DIRECT',
// flowMode: 'DEFAULT',
cardCompany: 'TOSSBANK',
flowMode: 'DEFAULT',
// flowMode: 'DIRECT',
// cardCompany: 'TOSSBANK',
useCardPoint: false,
useAppCardOnly: false,
},
Expand Down Expand Up @@ -316,7 +335,7 @@ const OrderInfo = () => {
}

return (
<div id="payment-method" className="my-5 flex flex-col gap-5">
<div id="payment-method" className="my-5 flex flex-col gap-5 pb-32">
<div className="flex flex-row justify-between">
<div className="flex flex-row gap-2">
<Icon name="Bike" size={24} />
Expand All @@ -333,16 +352,14 @@ const OrderInfo = () => {
<div className="flex flex-row gap-2">
<Icon name="MapPin" size={24} />
<div className="max-w-[calc(100dvw-24px-24px-54px-1rem-40px)] place-content-center truncate text-sm font-bold">
{`${address?.defaultAddress?.roadAddress} ${address?.defaultAddress?.detailAddress}`}
{`${member?.address.roadAddress} ${member?.address.detailAddress}`}
</div>
<div className="place-content-center text-xs">(으)로 배달</div>
</div>
<Icon name="ChevronRight" size={24} />
</div>
<div>
<div className="ml-7 text-xs text-gray-700">
[지번] {address?.defaultAddress?.jibunAddress}
</div>
<div className="ml-7 text-xs text-gray-700">[지번] {member?.address.jibunAddress}</div>
</div>
</div>
<div className="rounded-xl border border-solid border-gray-400">
Expand Down Expand Up @@ -443,22 +460,28 @@ const OrderInfo = () => {
{(totalMenuPrice + deliveryPrice).toLocaleString()}원
</div>
</div>
{isUnderMinOrder && (
<p className="pb-2 text-center text-sm font-bold text-red-600">
{(storeDetail.minimumOrderAmount - totalMenuPrice).toLocaleString()}원 더 담으면 배달
가능해요

{/* 배달비 무료 조건 추가 */}
<div className="fixed bottom-0 left-0 h-28 w-full rounded-t-2xl bg-white px-mobile_safe shadow-[0_-4px_6px_-2px_rgba(0,0,0,0.1)]">
<p
className={cn(
'py-3 text-center text-sm font-semibold text-blue-600',
isUnderMinOrder && 'text-red-600'
)}
>
{isUnderMinOrder
? `${(storeDetail.minimumOrderAmount - totalMenuPrice).toLocaleString()}원 더 담으면 배달 가능해요`
: '배달비 무료!'}
</p>
)}
<Button
onClick={handleOrderPay}
className={cn(
'text-base font-semibold',
isUnderMinOrder && 'bg-gray-400 hover:bg-gray-400'
)}
disabled={isUnderMinOrder}
>
{(totalMenuPrice + deliveryPrice).toLocaleString()}원 배달 결제하기
</Button>
<Button
size={'s'}
onClick={handleOrderPay}
className={cn('text-base font-bold', isUnderMinOrder && 'bg-gray-400 hover:bg-gray-400')}
disabled={isUnderMinOrder}
>
{(totalMenuPrice + deliveryPrice).toLocaleString()}원 배달 결제하기
</Button>
</div>
</div>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/pay/fail/_components/PayFail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const PayFail = () => {

useEffect(() => {
if (timer <= 0) {
router.push(ROUTE_PATHS.PAY)
router.replace(ROUTE_PATHS.PAY)
}
}, [timer])

Expand Down
10 changes: 9 additions & 1 deletion src/app/pay/success/_components/PaySuccess.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ const PaySuccess = () => {
const { mutate: payment } = usePostPayment()

useEffect(() => {
// 브라우저 히스토리 조작
if (window.history && window.history.pushState) {
window.history.pushState(null, '', window.location.href)
window.onpopstate = () => {
router.replace(ROUTE_PATHS.HOME)
}
}

if (orderId && paymentKey && amount) {
payment(
{
Expand Down Expand Up @@ -71,7 +79,7 @@ const PaySuccess = () => {
title="결제 실패"
message="결제 중 오류가 발생했습니다."
onClick={() => {
router.push(ROUTE_PATHS.PAY)
router.replace(ROUTE_PATHS.PAY)
}}
/>
),
Expand Down
20 changes: 9 additions & 11 deletions src/app/store/detail/[id]/_components/OrderButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,18 @@ export const OrderButton = ({ minimumOrderAmount }: { minimumOrderAmount: number
}

return (
<div className="sticky bottom-0 z-10 rounded-t-lg bg-white px-mobile_safe py-4 shadow-[0_-4px_6px_-2px_rgba(0,0,0,0.1)]">
{isUnderMinOrder && (
<p className="pb-2 text-center text-sm font-bold text-red-600">
{(minimumOrderAmount - totalPrice).toLocaleString()}원 더 담으면 배달 가능해요
</p>
)}
<Button
onClick={handleButtonClick}
<div className="sticky bottom-0 z-10 h-28 rounded-t-lg bg-white px-mobile_safe shadow-[0_-4px_6px_-2px_rgba(0,0,0,0.1)]">
<p
className={cn(
'text-base font-semibold',
isUnderMinOrder && 'bg-gray-400 hover:bg-gray-400'
'py-3 text-center text-sm font-semibold text-blue-600',
isUnderMinOrder && 'text-red-600'
)}
disabled={isUnderMinOrder}
>
{isUnderMinOrder
? `${(minimumOrderAmount - totalPrice).toLocaleString()}원 더 담으면 배달 가능해요`
: '배달비 무료!'}
</p>
<Button size={'s'} onClick={handleButtonClick} className={cn('text-base font-bold')}>
{totalPrice.toLocaleString()}원 주문하기
</Button>
</div>
Expand Down
Loading