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

Feature/#121 order api #125

Merged
merged 7 commits into from
Oct 12, 2024
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
43 changes: 0 additions & 43 deletions src/app/api/order/route.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { render, screen } from '@testing-library/react'
import OrderCancelDialog from './OrderCancelDialog'
import userEvent from '@testing-library/user-event'
import { useCancelOrder } from '@/features/orderStatus/hooks/useCancelOrder'
import { useCancelOrder } from '@/features/order/hooks/useCancelOrder'

jest.mock('../../../../features/orderStatus/hooks/useCancelOrder.ts')
jest.mock('../../../../features/order/hooks/useCancelOrder.ts')

describe('OrderCancelDialog', () => {
const mockHandleCancelOrder = jest.fn()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import { useCancelOrder } from '@/features/orderStatus/hooks/useCancelOrder'
import { useCancelOrder } from '@/features/order/hooks/useCancelOrder'

const OrderCancelDialog = () => {
const { handleCancelOrder } = useCancelOrder()
Expand Down
2 changes: 1 addition & 1 deletion src/app/order-status/[orderId]/_components/OrderDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Menu } from '@/features/orderStatus/types'
import React from 'react'
import OrderMenuItem from './OrderMenuItem'
import { Menu } from '@/features/order/types'

interface OrderDetailProps {
orderId: number
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Menu } from '@/features/orderStatus/types'
import { Menu } from '@/features/order/types'
import React from 'react'

interface OrderMenuItemProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { render, screen } from '@testing-library/react'
import OrderStatusTrack from './OrderStatusTrack'
import { useStreamOrderStatus } from '@/features/orderStatus/hooks/useStreamOrderStatus'
import { useCancelOrder } from '@/features/orderStatus/hooks/useCancelOrder'
import { useStreamOrderStatus } from '@/features/order/hooks/useStreamOrderStatus'
import { useCancelOrder } from '@/features/order/hooks/useCancelOrder'

jest.mock('../../../../features/orderStatus/hooks/useStreamOrderStatus.ts')
jest.mock('../../../../features/orderStatus/hooks/useCancelOrder.ts')
jest.mock('../../../../features/order/hooks/useStreamOrderStatus.ts')
jest.mock('../../../../features/order/hooks/useCancelOrder.ts')

describe('OrderStatusTrack', () => {
const mockHandleCancelOrder = jest.fn()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { OrderStatus } from '@/features/orderStatus/types'
import { Dot } from 'lucide-react'
import React from 'react'
import { useStreamOrderStatus } from '@/features/orderStatus/hooks/useStreamOrderStatus'
import { useStreamOrderStatus } from '@/features/order/hooks/useStreamOrderStatus'
import { OrderStatusItemList } from '@/constants/order'
import OrderStatusItem from './OrderStatusItem'
import OrderCancelDialog from './OrderCancelDialog'
import { OrderStatus } from '@/features/order/types'

interface OrderDetailProps {
orderId: number
Expand Down
7 changes: 3 additions & 4 deletions src/app/order-status/[orderId]/_components/OrderTrackMap.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useStreamDeliveryLocation } from '@/features/orderStatus/hooks/useStreamDeliveryLocation'
import { Address } from '@/features/orderStatus/types'
import { Car, CircleUser, Store as StoreIcon } from 'lucide-react'
import { useStreamDeliveryLocation } from '@/features/order/hooks/useStreamDeliveryLocation'
import React from 'react'
import { CustomOverlayMap, Map } from 'react-kakao-maps-sdk'
import { Map } from 'react-kakao-maps-sdk'
import OrderTrackItem from './OrderTrackItem'
import { Address } from '@/features/order/types'

interface OrderTrackMapProps {
storeAdress: Address
Expand Down
2 changes: 1 addition & 1 deletion src/app/order-status/[orderId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { useOrderStatus } from '@/features/orderStatus/hooks/useOrderStatus'
import { useOrderStatus } from '@/features/order/hooks/useOrderStatus'
import { X } from 'lucide-react'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
Expand Down
30 changes: 11 additions & 19 deletions src/app/order/_components/OrderCard.test.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
import { render, screen } from '@testing-library/react'
import OrderCard from './OrderCard'

// Order 타입을 가져옵니다.
interface Order {
id: number
storeName: string
date: string
deliveryStatus: 'Delivered' | 'Pending'
menuItems: { name: string; quantity: number }[]
totalAmount: number
}
import { Order } from '@/features/order/types'

describe('OrderCard', () => {
const mockOrder: Order = {
id: 1,
storeId: 1,
orderId: 1,
storeName: 'Test Store',
date: '2024-09-03',
deliveryStatus: 'Delivered', // 'Delivered'로 정확히 지정합니다.
menuItems: [
{ name: 'Item 1', quantity: 2 },
{ name: 'Item 2', quantity: 1 },
orderTime: '2024-09-03',
orderStatus: 'delivered',
menus: [
{ menuName: 'Item 1', menuCount: 2, menuPrice: 10000, optionGroups: [], menuId: 1 },
{ menuName: 'Item 2', menuCount: 1, menuPrice: 10000, optionGroups: [], menuId: 2 },
],
totalAmount: 30000,
orderPrice: 30000,
}

test('주문 정보가 올바르게 렌더링된다', () => {
Expand All @@ -31,7 +23,7 @@ describe('OrderCard', () => {
expect(screen.getByText('Test Store')).toBeInTheDocument()

// 주문 날짜가 올바르게 표시되는지 확인합니다.
expect(screen.getByText('2024-09-03')).toBeInTheDocument()
expect(screen.getByText(/2024\. 9\. 3\./i)).toBeInTheDocument()

// 배달 상태가 올바르게 표시되는지 확인합니다.
expect(screen.getByText('배달 완료')).toBeInTheDocument()
Expand All @@ -51,7 +43,7 @@ describe('OrderCard', () => {
})

test('배달 상태가 "배달 중"일 때 올바르게 표시되는지 확인한다', () => {
const pendingOrder: Order = { ...mockOrder, deliveryStatus: 'Pending' }
const pendingOrder: Order = { ...mockOrder, orderStatus: 'pending' }
render(<OrderCard order={pendingOrder} />)

expect(screen.getByText('배달 중')).toBeInTheDocument()
Expand Down
25 changes: 11 additions & 14 deletions src/app/order/_components/OrderCard.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
'use client'
import { Order } from '@/features/order/types'
import { formatDate } from '@/util/formatDate'
import Link from 'next/link'
import * as React from 'react'
interface Order {
id: number
storeName: string
date: string
deliveryStatus: 'Delivered' | 'Pending'
menuItems: { name: string; quantity: number }[]
totalAmount: number
}

export default function OrderCard({ order }: { order: Order }) {
const orderDate = new Date(order.orderTime)

return (
<div className="flex flex-col rounded-lg border p-4">
<h3 className="text-2xl font-bold">{order.storeName}</h3>
<span className="text-xs text-gray-500">{order.date}</span>
<span className="text-xs text-gray-500">{formatDate(orderDate)}</span>
<div className="mb-2 text-gray-600">
{order.deliveryStatus === 'Delivered' ? '배달 완료' : '배달 중'}
{order.orderStatus === 'delivered' ? '배달 완료' : '배달 중'}
</div>
<div className="mb-2 text-sm">
{order.menuItems.map((item, index) => (
{order.menus.map((item, index) => (
<div key={index}>
{item.name} x {item.quantity}
{item.menuName} x {item.menuCount}
</div>
))}
</div>
<span className="font-semibold">합계 금액: {order.totalAmount.toLocaleString()}원</span>
<span className="font-semibold">합계 금액: {order.orderPrice.toLocaleString()}원</span>
<Link
href={`/order/${order.id}/add-review`}
href={`/order/${order.orderId}/add-review`}
className="my-4 bg-[#0FA5FA] p-2 text-center text-white hover:underline"
>
리뷰쓰기
Expand Down
23 changes: 5 additions & 18 deletions src/app/order/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,25 @@
import LoadingSpinner from '@/components/common/LoadingSpinner'
import OrderCard from '@/app/order/_components/OrderCard'
import Tabs from '@/app/order/_components/Tabs'
import useOrderData from '@/mocks/handlers/order'
import useOrder from '@/features/order/hooks/useOrder'
import { Order } from '@/features/order/types'
import { useState } from 'react'

interface Order {
id: number
storeName: string
date: string
deliveryStatus: 'Delivered' | 'Pending'
menuItems: { name: string; quantity: number }[]
totalAmount: number
}

const OrderPage: React.FC = () => {
const [activeTab, setActiveTab] = useState<'past' | 'preparing'>('past')
const { useOrderQuery } = useOrderData()
const { data: orders, error: orderError, isLoading: orderLoading } = useOrderQuery()
const { orders } = useOrder()

const handleTabClick = (tab: 'past' | 'preparing') => {
setActiveTab(tab)
}
if (orderLoading) return <LoadingSpinner />
if (orderError instanceof Error) return <div>에러 발생</div>

return (
<div className="flex h-screen flex-col">
<Tabs activeTab={activeTab} onTabClick={handleTabClick} />

<div className="flex-1 overflow-y-auto p-4 pb-[4.5rem]">
{activeTab === 'past' ? (
<div className="space-y-4">
{orders.map((order: Order) => (
<OrderCard key={order.id} order={order} />
))}
{orders?.map((order: Order) => <OrderCard key={order.orderId} order={order} />)}
</div>
) : (
<div className="text-center text-gray-500">준비중인 주문이 없습니다.</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import axiosInst from '@/util/axiosInst'
import { Order } from '../types'
import { Order, OrderDetail } from '../types'

export const getOrderList = async () => {
const res = await axiosInst.get<{
response: {
orders: Order[]
}
statusCode: number
msg: string
}>(`/order`)

console.log(res)

return res.data
}

export const getOrderStatus = async (orderId: string) => {
const res = await axiosInst.get<{
response: Order
response: OrderDetail
statusCode: number
msg: string
}>(`/order/${orderId}`)
Expand Down
17 changes: 17 additions & 0 deletions src/features/order/hooks/useOrder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useQuery } from '@tanstack/react-query'
import React from 'react'
import { getOrderList } from '../api'

const useOrder = () => {
const { data, isLoading } = useQuery({
queryKey: ['orders'],
queryFn: getOrderList,
})

return {
orders: data?.response.orders,
isLoading,
}
}

export default useOrder
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useQuery } from '@tanstack/react-query'
import { getOrderStatus } from '../api'
import { useParams } from 'next/navigation'
import { getOrderStatus } from '../api'

export const useOrderStatus = () => {
const params = useParams<{ orderId: string }>()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect } from 'react'
import { OrderStatus } from '../types'
import { useOrderStatusStore } from '@/store/orderStatus'
import { BASE_URL } from '@/constants/api'
import { EventSourcePolyfill } from 'event-source-polyfill'
import { OrderStatus } from '../types'

interface UseStreamOrderStatusProps {
orderId: number
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
import { MenuType } from '@/features/cart/types'

export interface Order {
orderId: number
orderTime: string
orderStatus: OrderStatus
storeId: number
storeName: string
menus: MenuType[]
orderPrice: number
}

// 주문 상태 타입 정의
export type OrderStatus =
| 'pending'
Expand Down Expand Up @@ -45,7 +57,7 @@ export interface Store {
}

// 주문 타입 정의
export interface Order {
export interface OrderDetail {
orderId: number
orderTime: string
orderStatus: OrderStatus
Expand Down
18 changes: 0 additions & 18 deletions src/mocks/handlers/order.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { BASE_URL } from '@/constants/api'
import { delay, http, HttpResponse } from 'msw'
import { useQuery } from '@tanstack/react-query'

const encoder = new TextEncoder()

Expand Down Expand Up @@ -250,20 +249,3 @@ export const orderHandlers = [
return HttpResponse.json(mockPostOrderResponse)
}),
]

export default function useOrderData() {
const useOrderQuery = () =>
useQuery({
queryKey: ['orders'],
queryFn: async () =>
await fetch(`/api/order`, {
method: 'GET',
}).then((res) => res.json()),
})

return {
useOrderQuery,
}
}

// order api 작성
2 changes: 1 addition & 1 deletion src/store/orderStatus/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OrderStatus } from '@/features/orderStatus/types'
import { OrderStatus } from '@/features/order/types'
import { create } from 'zustand'

interface OrderStatusStore {
Expand Down
7 changes: 7 additions & 0 deletions src/util/formatDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const formatDate = (date: Date) => {
const year = date.getFullYear()
const month = date.getMonth() + 1 // 월은 0부터 시작하므로 1을 더해야 함
const day = date.getDate()

return `${year}. ${month}. ${day}.`
}
Loading