diff --git a/src/features/chat/api/room.ts b/src/features/chat/api/room.ts index 21dbfd4..ef1cf3e 100644 --- a/src/features/chat/api/room.ts +++ b/src/features/chat/api/room.ts @@ -4,12 +4,12 @@ import type { ChatProduct, ChatRole, SaleStatus, TradeStatus } from '../model/ty import type { ChatRoomDetailResponse, ProductStatus } from './dto'; // 채팅방 생성 또는 조회 (아이템 상세 페이지 채팅하기 버튼). -// 판매자가 받은 구매 제안 상세에서 열 땐 purchaseOfferId를 함께 보내 제안자↔소유자 방을 잡는다. export const createOrGetChatRoom = (itemId: number, purchaseOfferId?: number) => - api.post<{ chatRoomId: number }>('/chats', { - itemId, - ...(purchaseOfferId != null && { purchaseOfferId }), - }); + api.post<{ chatRoomId: number }>('/chats', { itemId, purchaseOfferId }); + +// 채팅방 생성 또는 조회 (거래 상세 페이지 채팅하기 버튼). +export const createOrGetChatRoomByTrade = (tradeId: number) => + api.post<{ chatRoomId: number }>(`/chats/trades/${tradeId}`); // 채팅방 상세 조회 (프로덕트 바 데이터) export const getChatRoom = (chatRoomId: number) => { diff --git a/src/features/ootd/ui/OotdTagEditor.tsx b/src/features/ootd/ui/OotdTagEditor.tsx index 94832a2..7958655 100644 --- a/src/features/ootd/ui/OotdTagEditor.tsx +++ b/src/features/ootd/ui/OotdTagEditor.tsx @@ -8,6 +8,8 @@ import { getItemDetail } from '@/features/mypage/api/itemsApi'; import type { ItemDetailResponse } from '@/features/mypage/model/items'; import { getDaysAgo } from '@/features/mypage/lib/daysAgo'; import { resolveFileUrl } from '@/shared/lib/resolveFileUrl'; +import { Toast } from '@/shared/components'; +import { useToast } from '@/shared/hooks/useToast'; import TagLoading from '@/pages/camera/component/TagLoading'; import TagResultSheet, { MIDDLE as RESULT_SHEET_DEFAULT_H, @@ -43,6 +45,7 @@ type Props = { className?: string; }; +const MAX_TAGS = 5; // 한 게시물에 붙일 수 있는 최대 태그 수 const BOX_W = 0.26; const BOX_H = 0.22; const clamp = (v: number, min: number, max: number) => Math.min(Math.max(v, min), max); @@ -140,6 +143,7 @@ const OotdTagEditor = ({ const [query, setQuery] = useState(''); const [newItemOpen, setNewItemOpen] = useState(false); const [showBox, setShowBox] = useState(true); + const { message: toastMessage, show: showToast, hide: hideToast } = useToast(); const activeBox = boxes.find((b) => b.id === activeBoxId) ?? null; const tagCount = boxes.filter((b) => b.itemId).length; // 아이템 부착된 박스 = 완성 태그 @@ -266,6 +270,11 @@ const OotdTagEditor = ({ // 이미지 빈 곳 탭 → 그 위치에 박스 생성 + 활성화 + 분석 API 호출 const handleAreaClick = (e: MouseEvent) => { if ((e.target as HTMLElement).dataset.tagArea !== 'true') return; // 박스/버튼 클릭은 무시 + // 완성 태그가 최대치면 새 박스 생성 차단 (기존 태그 편집/이동은 그대로) + if (tagCount >= MAX_TAGS) { + showToast(`태그는 최대 ${MAX_TAGS}개까지 추가할 수 있어요.`); + return; + } const rect = e.currentTarget.getBoundingClientRect(); const cx = (e.clientX - rect.left) / rect.width; const cy = (e.clientY - rect.top) / rect.height; @@ -401,6 +410,8 @@ const OotdTagEditor = ({ onSubmit={handleRegister} /> )} + + ); }; diff --git a/src/pages/mypage/AddressFormPage.tsx b/src/pages/mypage/AddressFormPage.tsx index 58473d9..ba261b6 100644 --- a/src/pages/mypage/AddressFormPage.tsx +++ b/src/pages/mypage/AddressFormPage.tsx @@ -36,7 +36,7 @@ const AddressFormPage = () => { if (isEditMode && isPending) { return ( -
+
navigate(-1)} />

불러오는 중...

@@ -47,7 +47,7 @@ const AddressFormPage = () => { if (isEditMode && !target) { return ( -
+
navigate(-1)} />

배송지 정보를 찾을 수 없습니다. @@ -123,7 +123,7 @@ const AddressForm = ({ addressId, initial, onDone }: AddressFormProps) => { }; return ( -

+
diff --git a/src/pages/mypage/AddressManagePage.tsx b/src/pages/mypage/AddressManagePage.tsx index f7b44d7..2872c2e 100644 --- a/src/pages/mypage/AddressManagePage.tsx +++ b/src/pages/mypage/AddressManagePage.tsx @@ -23,7 +23,7 @@ const AddressManagePage = () => { }; return ( -
+