From 81dc9b9526f3c79ce1d9f34ee66184b2441919f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CKangShinGyu=E2=80=9D?= <“rkdtlseb@naver.com”> Date: Wed, 14 Oct 2026 14:22:43 +0900 Subject: [PATCH 1/7] =?UTF-8?q?fix(map):=20=EA=B2=BD=EB=A1=9C=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EB=B9=88=20=EB=A9=94=EB=AA=A8=20=EC=A4=84=EC=9D=98?= =?UTF-8?q?=20chevron=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx b/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx index 6bbba996..0d4429bd 100644 --- a/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx +++ b/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx @@ -268,7 +268,7 @@ function PlaceMemo({ place, addWhenEmpty, onEditMemo }: ) : null} {!memo && addMemo ? ( - // 메모가 있을 때와 같은 줄(구분선·아이콘·꺾쇠)을 흐리게 — 누르면 메모 시트 + // 메모가 있을 때와 같은 줄(구분선·아이콘)을 흐리게 — 펼칠 내용이 없어 꺾쇠는 두지 않는다. 누르면 메모 시트
) : null} From 497a45f747bed76d4eef530c1db22d16b02edd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CKangShinGyu=E2=80=9D?= <“rkdtlseb@naver.com”> Date: Wed, 14 Oct 2026 14:40:19 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat(plan):=20=EB=AA=A8=EB=B0=94=EC=9D=BC?= =?UTF-8?q?=20=EC=9E=A5=EC=86=8C=20=EC=B9=B4=EB=93=9C=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=9E=98=EB=A6=B0=20=EC=A3=BC=EC=86=8C=EB=A5=BC=20=EB=88=8C?= =?UTF-8?q?=EB=9F=AC=20=EC=A0=84=EC=B2=B4=20=EC=A3=BC=EC=86=8C=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile/MobilePlanPlaceCard.tsx | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx b/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx index 0d4429bd..2f4b88c7 100644 --- a/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx +++ b/src/app/(main)/plan/_components/mobile/MobilePlanPlaceCard.tsx @@ -1,6 +1,6 @@ "use client"; -import { useId, useState, type PointerEvent as ReactPointerEvent } from "react"; +import { useEffect, useId, useRef, useState, type PointerEvent as ReactPointerEvent } from "react"; import { ChevronDownIcon, @@ -10,6 +10,7 @@ import { TimeClockIcon, WriteIcon, } from "@/assets/icons"; +import { useOnClickOutside } from "@/hooks/useOnClickOutside"; import { formatScheduleTimeRange } from "@/lib/plan/scheduleTime"; import type { PlanPlace } from "@/lib/plan/types"; import { renderTextWithLinks } from "@/lib/text/renderTextWithLinks"; @@ -104,7 +105,7 @@ export function MobilePlanPlaceCard({

{place.title}

- {meta ?

{meta}

: null} + {meta ? : null}
@@ -139,6 +140,57 @@ export function MobilePlanPlaceCard({ ); } +/** 분류·주소 줄 — 좁은 화면에서 잘렸을 때만 눌러서 전체 주소를 아래 드롭다운으로 보여 준다 */ +function PlaceMeta({ place, meta }: Readonly<{ place: PlanPlace; meta: string }>) { + const wrapRef = useRef(null); + const textRef = useRef(null); + const addressId = useId(); + const [truncated, setTruncated] = useState(false); + const [open, setOpen] = useState(false); + useOnClickOutside(wrapRef, () => setOpen(false)); + + // 카드 폭(회전·넘겨 보기 칸)이 바뀌면 잘렸는지 다시 잰다 + useEffect(() => { + const el = textRef.current; + if (!el || typeof ResizeObserver === "undefined") return; + const measure = () => setTruncated(el.scrollWidth > el.clientWidth); + measure(); + const observer = new ResizeObserver(measure); + observer.observe(el); + return () => observer.disconnect(); + }, [meta]); + + const expandable = truncated && Boolean(place.subtitle); + return ( +
+

{meta}

+ {expandable ? ( + // 잘리지 않았으면 버튼을 두지 않아 이 줄을 눌러도 카드 본문(열기)이 눌린다 +
+ ); +} + function PlaceTimeAndExpense({ place, expenseSummary, addWhenEmpty, onEditTime, onOpenExpenses }: Pick) { const summaryId = useId(); From 8dff231a3e532bd437d9d7024807e392c6d37c78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CKangShinGyu=E2=80=9D?= <“rkdtlseb@naver.com”> Date: Wed, 14 Oct 2026 14:46:33 +0900 Subject: [PATCH 3/7] =?UTF-8?q?fix(map):=20=EA=B2=BD=EB=A1=9C=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20X=EB=A5=BC=20=EC=9D=BC=EC=B0=A8=20=ED=83=AD?= =?UTF-8?q?=EA=B3=BC=20=EA=B0=99=EC=9D=80=20=EC=A4=84=20=EC=98=A4=EB=A5=B8?= =?UTF-8?q?=EC=AA=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../map/_components/useMobileRouteView.tsx | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/app/(main)/map/_components/useMobileRouteView.tsx b/src/app/(main)/map/_components/useMobileRouteView.tsx index 51e30d53..eadc8e74 100644 --- a/src/app/(main)/map/_components/useMobileRouteView.tsx +++ b/src/app/(main)/map/_components/useMobileRouteView.tsx @@ -459,34 +459,34 @@ export function useMobileRouteView({
{/* 펼치면 X·일차 탭은 사라지고 카드가 그 자리까지 커진다 */}
-
+
+
-
{/* 접힘: 가장 긴 카드에 맞춰 모든 카드가 같은 높이 / 펼침: 지도의 70% */}
From 6fc4178115a8f65af2b4673a2aa2b815c18e1b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CKangShinGyu=E2=80=9D?= <“rkdtlseb@naver.com”> Date: Wed, 14 Oct 2026 14:52:13 +0900 Subject: [PATCH 4/7] =?UTF-8?q?fix(map):=20PC=20=EB=B6=81=EB=A7=88?= =?UTF-8?q?=ED=81=AC=20=ED=91=9C=EC=8B=9C=20=EB=B2=84=ED=8A=BC=EC=9D=84=20?= =?UTF-8?q?=ED=99=95=EB=8C=80=C2=B7=EC=B6=95=EC=86=8C(+/=E2=88=92)=20?= =?UTF-8?q?=EC=9C=84=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/map/Map.tsx | 75 +++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index c012f57c..88ccf57e 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -5,7 +5,9 @@ import { usePathname } from "next/navigation"; import { Bookmark } from "lucide-react"; import { AdvancedMarker, + ControlPosition, Map as GoogleMap, + MapControl, useMap, useMapsLibrary, type MapCameraChangedEvent, @@ -465,6 +467,27 @@ export default function TripMap({ clearPlanFocus(); }; + const bookmarkToggle = ( + + ); + return (
@@ -519,6 +542,13 @@ export default function TripMap({ )} {!routeView && } + + {/* PC는 확대·축소(+/−) 바로 위 — 같은 오른쪽 아래 컨트롤 자리에 넣으면 지도가 +/− 위로 쌓아 준다 */} + {routeView || isMobileDevice ? null : ( + +
{bookmarkToggle}
+
+ )} )}
@@ -537,36 +567,21 @@ export default function TripMap({ {!bootstrap.ready || routeView ? null : ( <> -
- {onOpenRouteView ? ( - - ) : null} - -
+ {isMobileDevice ? ( +
+ {onOpenRouteView ? ( + + ) : null} + {bookmarkToggle} +
+ ) : null} )}
From 18116565c84f6222aa46ea7f1cfa73463f94124b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CKangShinGyu=E2=80=9D?= <“rkdtlseb@naver.com”> Date: Wed, 14 Oct 2026 14:55:55 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix(plan):=20PC=20=EC=9D=BC=EC=A0=95=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EC=84=A0=ED=83=9D=20=EC=8B=9C=20=ED=8C=8C?= =?UTF-8?q?=EB=9E=80=20=EA=B7=B8=EB=A6=BC=EC=9E=90=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/plan/_components/itinerary/PlanPlaceCard.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/app/(main)/plan/_components/itinerary/PlanPlaceCard.tsx b/src/app/(main)/plan/_components/itinerary/PlanPlaceCard.tsx index eded7da1..842af452 100644 --- a/src/app/(main)/plan/_components/itinerary/PlanPlaceCard.tsx +++ b/src/app/(main)/plan/_components/itinerary/PlanPlaceCard.tsx @@ -311,9 +311,7 @@ export function PlanPlaceCard({ className={cn( "w-full select-none transition-colors", PLAN_PLACE_CARD_TW.article, - // 고른 카드는 계속 켜져 있으므로 배경은 그대로 두고 테두리와 옅게 번지는 파란 그림자로만 표시한다 - // (그림자 토큰이 없어 파랑 원시 토큰으로 지정) - focused && "border-primary shadow-[0_0_12px_var(--blue-200)]", + focused && "border-primary", dragDisabled ? "cursor-default" : "cursor-grab active:cursor-grabbing", From c54eb1b79ae5dc8238ebb0cc214d0a8da98d0d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CKangShinGyu=E2=80=9D?= <“rkdtlseb@naver.com”> Date: Wed, 14 Oct 2026 15:43:37 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat(rooms):=20=EC=97=AC=ED=96=89=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=EC=9D=98=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=20=EB=B2=84=ED=8A=BC=20=EC=A0=9C=EA=B1=B0,=20?= =?UTF-8?q?=EC=97=AC=ED=96=89=20=EC=82=AD=EC=A0=9C=EB=A5=BC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EA=B8=B0=20=EC=95=84=EB=9E=98=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/RoomTripSettingsSection.tsx | 4 +--- src/components/rooms/RoomTripEditDialog.tsx | 8 +++++-- src/components/rooms/RoomTripEditForm.tsx | 23 ++----------------- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/app/(main)/room-settings/_components/RoomTripSettingsSection.tsx b/src/app/(main)/room-settings/_components/RoomTripSettingsSection.tsx index 4eb531ec..a599c9e4 100644 --- a/src/app/(main)/room-settings/_components/RoomTripSettingsSection.tsx +++ b/src/app/(main)/room-settings/_components/RoomTripSettingsSection.tsx @@ -45,11 +45,9 @@ export function RoomTripDeleteButton() { export function RoomTripSettingsSection({ embedded = false, - onCancel, onSaved, }: { embedded?: boolean; - onCancel?: () => void; onSaved?: () => void; }) { const { roomId, roomSource, isLoading } = useCurrentRoomMembership(); @@ -75,7 +73,7 @@ export function RoomTripSettingsSection({ 여행 정보를 불러오지 못했어요.

) : ( - + )}
); diff --git a/src/components/rooms/RoomTripEditDialog.tsx b/src/components/rooms/RoomTripEditDialog.tsx index 164468c5..838c8471 100644 --- a/src/components/rooms/RoomTripEditDialog.tsx +++ b/src/components/rooms/RoomTripEditDialog.tsx @@ -8,9 +8,13 @@ import { SettingsDialog } from "@/components/settings/SettingsDialog"; export function RoomTripEditDialog({ onClose }: { onClose: () => void }) { return ( - }> +
- + +
+ {/* 여행 삭제는 적용하기 아래 모달 오른쪽 끝 — 방장이 아니면 버튼이 없어 줄째 숨긴다 */} +
+
); diff --git a/src/components/rooms/RoomTripEditForm.tsx b/src/components/rooms/RoomTripEditForm.tsx index 2d82f4c5..0131f340 100644 --- a/src/components/rooms/RoomTripEditForm.tsx +++ b/src/components/rooms/RoomTripEditForm.tsx @@ -28,7 +28,6 @@ import { type Props = { room: RoomTripFormSource; readOnly?: boolean; - onCancel?: () => void; onSaved?: () => void; }; @@ -36,7 +35,7 @@ export function RoomTripEditForm(props: Props) { return ; } -function RoomTripEditSession({ room, readOnly = false, onCancel, onSaved }: Props) { +function RoomTripEditSession({ room, readOnly = false, onSaved }: Props) { const saved = toTripFormValues(room); const [title, setTitle] = useState(saved.title); @@ -124,16 +123,6 @@ function RoomTripEditSession({ room, readOnly = false, onCancel, onSaved }: Prop onSaved, ]); - function handleCancel() { - const next = toTripFormValues(room); - setTitle(next.title); - setDestinations(next.destinations); - setStartDate(next.startDate); - setEndDate(next.endDate); - setShrinkConfirmOpen(false); - onCancel?.(); - } - function handleApply() { if (!canApply) return; @@ -176,15 +165,7 @@ function RoomTripEditSession({ room, readOnly = false, onCancel, onSaved }: Prop )} {!readOnly && ( - - - 취소 - + Date: Wed, 14 Oct 2026 15:52:16 +0900 Subject: [PATCH 7/7] =?UTF-8?q?refactor(rooms):=20=EC=A7=84=EC=9E=85=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=EA=B0=80=20=EC=97=86=EB=8A=94=20/room-settin?= =?UTF-8?q?gs=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/room-settings/page.tsx | 11 ----------- .../layout/MainSettingsPageLayout.tsx | 2 +- src/components/rooms/RoomTripEditDialog.tsx | 4 ++-- .../rooms}/RoomTripSettingsSection.tsx | 18 +++--------------- .../settings/SettingsActionButton.tsx | 2 +- src/lib/analytics/room-context.test.ts | 2 +- src/lib/analytics/room-context.ts | 2 +- src/lib/auth-session.test.ts | 1 - src/lib/auth-session.ts | 1 - src/lib/layout/mainChromeLayoutWidth.test.ts | 2 +- src/lib/layout/mainChromeLayoutWidth.ts | 4 +--- src/proxy.test.ts | 1 - src/proxy.ts | 2 -- 13 files changed, 11 insertions(+), 41 deletions(-) delete mode 100644 src/app/(main)/room-settings/page.tsx rename src/{app/(main)/room-settings/_components => components/rooms}/RoomTripSettingsSection.tsx (79%) diff --git a/src/app/(main)/room-settings/page.tsx b/src/app/(main)/room-settings/page.tsx deleted file mode 100644 index e002c4fa..00000000 --- a/src/app/(main)/room-settings/page.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { MainSettingsPageLayout } from "@/components/layout/MainSettingsPageLayout"; - -import { RoomTripSettingsSection } from "./_components/RoomTripSettingsSection"; - -export default function RoomSettingsPage() { - return ( - - - - ); -} diff --git a/src/components/layout/MainSettingsPageLayout.tsx b/src/components/layout/MainSettingsPageLayout.tsx index 220a1709..9c9cbd00 100644 --- a/src/components/layout/MainSettingsPageLayout.tsx +++ b/src/components/layout/MainSettingsPageLayout.tsx @@ -2,7 +2,7 @@ import type { ReactNode } from "react"; import { SetSectionMaxWidth } from "@/contexts/SectionWidthContext"; -/** member-settings·room-settings 등 s1 본문 폭 설정 탭 공통 레이아웃 */ +/** member-settings 등 s1 본문 폭 설정 탭 공통 레이아웃 */ export function MainSettingsPageLayout({ children }: { children: ReactNode }) { return (
diff --git a/src/components/rooms/RoomTripEditDialog.tsx b/src/components/rooms/RoomTripEditDialog.tsx index 838c8471..59025560 100644 --- a/src/components/rooms/RoomTripEditDialog.tsx +++ b/src/components/rooms/RoomTripEditDialog.tsx @@ -3,14 +3,14 @@ import { RoomTripDeleteButton, RoomTripSettingsSection, -} from "@/app/(main)/room-settings/_components/RoomTripSettingsSection"; +} from "@/components/rooms/RoomTripSettingsSection"; import { SettingsDialog } from "@/components/settings/SettingsDialog"; export function RoomTripEditDialog({ onClose }: { onClose: () => void }) { return (
- +
{/* 여행 삭제는 적용하기 아래 모달 오른쪽 끝 — 방장이 아니면 버튼이 없어 줄째 숨긴다 */}
diff --git a/src/app/(main)/room-settings/_components/RoomTripSettingsSection.tsx b/src/components/rooms/RoomTripSettingsSection.tsx similarity index 79% rename from src/app/(main)/room-settings/_components/RoomTripSettingsSection.tsx rename to src/components/rooms/RoomTripSettingsSection.tsx index a599c9e4..98473854 100644 --- a/src/app/(main)/room-settings/_components/RoomTripSettingsSection.tsx +++ b/src/components/rooms/RoomTripSettingsSection.tsx @@ -5,12 +5,11 @@ import { useRouter } from "next/navigation"; import { DeleteConfirmModal } from "@/app/home/_components/DeleteConfirmModal"; import { RoomTripEditForm } from "@/components/rooms/RoomTripEditForm"; -import { MainPageHeader } from "@/components/layout/MainPageHeader"; import { useCurrentRoomMembership } from "@/hooks/useCurrentRoomMembership"; import { isRoomMemberRole } from "@/lib/rooms"; import { useSessionStore } from "@/stores/session-store"; -/** 방장 전용 여행 삭제 — 제목 옆 작은 텍스트 버튼과 삭제 확인 */ +/** 방장 전용 여행 삭제 — 적용하기 아래 작은 텍스트 버튼과 삭제 확인 */ export function RoomTripDeleteButton() { const router = useRouter(); const { roomSource, isHost, isLoading } = useCurrentRoomMembership(); @@ -23,7 +22,6 @@ export function RoomTripDeleteButton() { <>