[feat] solution: 추천 일정 카드에 출발지(업소명·출발 시각) 한 줄을 얹는다
This commit is contained in:
parent
6760b38fec
commit
8a2964ebf7
@ -18,6 +18,7 @@ import {
|
||||
type PlannedStop,
|
||||
} from '@o2o/shared';
|
||||
import {useLocalGuide} from '@/hooks/useLocalGuide';
|
||||
import {useBuilderStore} from '@/stores/builder';
|
||||
import {SectionBody, SectionFrame, Rail} from '../../primitives';
|
||||
import type {SectionRenderProps} from '../../types';
|
||||
import {
|
||||
@ -36,6 +37,7 @@ export function ItineraryTickets(props: SectionRenderProps) {
|
||||
const {section, isSelected, onSelect} = props;
|
||||
const parsed = parseSectionData<ItineraryItem>(section.type, section.data);
|
||||
const guide = useLocalGuide();
|
||||
const placeName = useBuilderStore((s) => s.storeName);
|
||||
// 사장님이 적은 것이 언제나 이긴다 — 서버가 만든 건 비었을 때의 기본값이다.
|
||||
const items = parsed.items.length > 0 ? parsed.items : guide.itineraries;
|
||||
const live = currentSeasons();
|
||||
@ -105,6 +107,13 @@ export function ItineraryTickets(props: SectionRenderProps) {
|
||||
|
||||
{itineraryDays(item).map((entry, dayIndex) => (
|
||||
<div key={`${entry.label}-${dayIndex}`} className="space-y-1.5">
|
||||
{/* ★ 출발지 — 첫날에만. 일정 데이터에는 없다(프롬프트가 정거장으로
|
||||
못 넣게 막는다) — 빌더가 이미 아는 상호명을 그 자리에서 얹는다. */}
|
||||
{dayIndex === 0 && placeName && (
|
||||
<p className="text-[11px] opacity-50">
|
||||
{placeName}에서 출발 · {entry.day.from}
|
||||
</p>
|
||||
)}
|
||||
{entry.label && (
|
||||
<p className="text-[11px] font-bold" style={{color: ITEM_ACCENT}}>
|
||||
{entry.label}
|
||||
|
||||
@ -51,12 +51,15 @@ function DayCard({
|
||||
startTime,
|
||||
stops,
|
||||
first,
|
||||
placeName,
|
||||
}: {
|
||||
item: ItineraryItem;
|
||||
badge: string;
|
||||
startTime?: string;
|
||||
stops: PlannerStop[];
|
||||
first: boolean;
|
||||
/** 업소 상호명 — 출발지 표시용. 일정 데이터에는 없다(프롬프트가 정거장으로 못 넣게 막는다). */
|
||||
placeName: string;
|
||||
}) {
|
||||
const day = planDay({name: item.name, startTime, stops});
|
||||
|
||||
@ -102,6 +105,9 @@ function DayCard({
|
||||
{/* ★ why·audience 는 첫 장만 — 다 채우면 같은 문구가 이틀·사흘 반복된다. */}
|
||||
{first && item.audience && <p className="text-[12px] opacity-60">{item.audience}</p>}
|
||||
{first && item.why && <p className="text-[13px] leading-relaxed opacity-80">{item.why}</p>}
|
||||
{/* ★ 출발지 — 첫 장만(위 audience·why 와 같은 규칙). day.from 은 planDay 가 계산한
|
||||
출발 시각(item.startTime)이라 시간표의 첫 줄과 정확히 이어진다. */}
|
||||
{first && <p className="text-[11px] opacity-50">{placeName}에서 출발 · {day.from}</p>}
|
||||
</div>
|
||||
|
||||
<RouteMap stops={day.stops.map((planned) => planned.stop)} />
|
||||
@ -231,6 +237,7 @@ export function ItinerarySection() {
|
||||
key={active}
|
||||
tab={tab}
|
||||
items={items.filter((item) => (item.duration?.trim() || NO_DURATION) === tab)}
|
||||
placeName={payload.place.name}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
@ -254,7 +261,15 @@ export function ItinerarySection() {
|
||||
* ★ `audience`("차 없이 오는 손님")는 카드에만 둔다. 줄에도 적으면 같은 문구가 위아래로
|
||||
* 두 번 나오고, 코스가 하나일 때는 줄이 아예 없어서 그 문구만 사라진다.
|
||||
*/
|
||||
function DurationRail({tab, items}: {tab: string; items: ItineraryItem[]}) {
|
||||
function DurationRail({
|
||||
tab,
|
||||
items,
|
||||
placeName,
|
||||
}: {
|
||||
tab: string;
|
||||
items: ItineraryItem[];
|
||||
placeName: string;
|
||||
}) {
|
||||
/** 코스별 시작 위치와 길이. 레일 인덱스 ↔ 코스를 잇는 유일한 표다. */
|
||||
const courses = useMemo(() => {
|
||||
let cursor = 0;
|
||||
@ -311,6 +326,7 @@ function DurationRail({tab, items}: {tab: string; items: ItineraryItem[]}) {
|
||||
startTime={day.startTime}
|
||||
stops={day.stops}
|
||||
first={dayIndex === 0}
|
||||
placeName={placeName}
|
||||
/>
|
||||
)),
|
||||
)}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user