/* BookingDetail.jsx — PW-004 Booking Request Detail */
const bdStyles = {
breadcrumb: {
fontSize: 12, color: KARE.n500, marginBottom: 8,
display: 'flex', alignItems: 'center', gap: 6,
},
bcLink: { color: KARE.n500, cursor: 'pointer' },
bcSep: { color: KARE.n300 },
bcCur: { color: KARE.n700, fontWeight: 500, fontFamily: "'Inter', sans-serif" },
head: {
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
marginBottom: 24, gap: 16,
},
title: { fontSize: 22, fontWeight: 700, color: KARE.n900, margin: 0, letterSpacing: -0.3 },
grid: { display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 24, alignItems: 'start' },
card: {
background: KARE.n000, borderRadius: 8, border: `1px solid ${KARE.n300}`,
padding: 24, boxShadow: KARE.shadowSm, marginBottom: 16,
},
cardTitle: {
fontSize: 16, fontWeight: 600, color: KARE.n900, margin: 0, marginBottom: 16,
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
},
row: {
display: 'grid', gridTemplateColumns: '120px 1fr',
padding: '10px 0', borderBottom: `1px solid ${KARE.n100}`,
fontSize: 13, alignItems: 'start',
},
rowLabel: { color: KARE.n500, fontWeight: 500 },
rowValue: { color: KARE.n900 },
caption: { fontSize: 12, color: KARE.n500, marginTop: 10, lineHeight: 1.5 },
infoBanner: {
marginTop: 14, padding: '10px 12px', borderRadius: 6,
background: KARE.infoBg, border: `1px solid rgba(2,132,199,0.15)`,
fontSize: 12, color: KARE.n700, display: 'flex', gap: 8, alignItems: 'flex-start',
},
};
const IMono = ({ children }) => (
{children}
);
const IInfo = ({ color = KARE.info }) => (
);
const ICar = () => (
);
function DetailRow({ label, children }) {
return (
);
}
/* -------- Booking info cards (shared) -------- */
function BookingInfoCards({ service = 'mobility' }) {
return (
<>
예약 정보
BKG-2026-0412-001
Mobility · Airport Pickup (Sedan)
2026-04-12 09:47 (KST)
3 persons (본인 + 동반자 2)
VCH-8831-22AB
본 예약은 Integrated Voucher × Partner 1건 단위이며 부분 취소가 불가능합니다. BD-029
{service === 'mobility' && (
픽업 정보
2026-04-28 16:30 (KST)
Incheon International Airport T2, Arrival Gate 6
Lotte Hotel Seoul (30 Eulji-ro, Jung-gu)
2 large + 1 carry-on
)}
사용자 정보
Nguyen Thi Lan
+84 90 555 0418
Vietnam · VN
개인의료정보(PHI)는 본 화면에서 제공되지 않습니다. 필요 시 KARE 운영팀으로 문의해주세요.
동반자 정보 · 2 persons
Nguyen Van Minh · Male · 45
Nguyen Mai Linh · Female · 16
동반자 서비스 적합성(예: 차량 탑승 정원, 수하물)은 파트너사 판단 후 안내 부탁드립니다. INFO-CMP-001
>
);
}
/* -------- Action panels -------- */
function ActionPanelRequested({ service = 'mobility' }) {
return (
처리 액션
{service === 'mobility' && (
추가 처리 (Mobility)
기사 배정 변경
)}
요청 이후 경과
2h 15m
);
}
function ActionPanelConfirmed() {
return (
승인 처리가 완료되었습니다. 고객에게 확정 알림이 발송되었습니다.
기사 배정 변경
);
}
function ActionPanelRejected({ serviceKind = 'mobility' }) {
const isPhysical = serviceKind === 'mobility' || serviceKind === 'stay';
return (
Rejected · 2026-04-13 09:02
DATE_UNAVAILABLE
해당 일자에 차량 가용 편성이 없어 배정이 어렵습니다. 전일 또는 익일 확인 부탁드립니다.
후속 처리
{isPhysical ? (
) : (
)}
);
}
function ActionPanelSuspended() {
return (
처리 액션
파트너사 정지 상태에서는 예약 처리가 불가능합니다.
);
}
function Timeline({ items }) {
return (
{items.map((it, i) => (
{i < items.length - 1 && (
)}
{it.label}
{it.date}
))}
);
}
/* -------- Page body -------- */
function BookingDetailBody({ variant = 'requested' }) {
const status = variant === 'suspended' ? 'requested' : variant;
return (
<>
예약 요청
/
BKG-2026-0412-001
예약 요청 상세
{variant === 'requested' &&
}
{variant === 'confirmed' &&
}
{variant === 'rejected' &&
}
{variant === 'suspended' &&
}
>
);
}
/* -------- Reject Modal (2 steps) -------- */
function ModalShell({ title, children, footer, width = 560 }) {
return (
{title}
×
{children}
{footer}
);
}
function RadioItem({ label, hint, selected }) {
return (
);
}
function RejectStep1() {
const reasons = [
{ id: 'FULLY_BOOKED', label: 'FULLY_BOOKED', hint: '해당 일자 예약이 모두 마감됨', selected: false },
{ id: 'DATE_UNAVAILABLE', label: 'DATE_UNAVAILABLE', hint: '요청 일자에 서비스 운영 불가', selected: true },
{ id: 'SERVICE_SUSPENDED', label: 'SERVICE_SUSPENDED', hint: '해당 서비스 한시적 운영 중단' },
{ id: 'CAPACITY_EXCEEDED', label: 'CAPACITY_EXCEEDED', hint: '인원 수가 최대 수용 인원 초과' },
{ id: 'OTHER', label: 'OTHER', hint: '기타 사유 (사유 입력 필수)' },
];
return (
거절 사유를 선택해주세요. 고객에게 안내되는 내용입니다.
{reasons.map(r => )}
);
}
function RejectStep2() {
return (
선택 사유: DATE_UNAVAILABLE
상세 사유 (선택, 10~500자 · OTHER 선택 시 필수)
한글, 영문 모두 입력 가능
98 / 500
);
}
function StepDot({ n, active, done }) {
const bg = done ? KARE.primary : active ? KARE.primary : KARE.n000;
const color = done || active ? KARE.n000 : KARE.n500;
const border = done || active ? KARE.primary : KARE.n300;
return (
{done ? '✓' : n}
);
}
/* -------- Variants -------- */
function BookingDetailRequested() {
return ;
}
function BookingDetailConfirmed() {
return ;
}
function BookingDetailRejected() {
return ;
}
function BookingDetailSuspended() {
const banner = (
파트너사가 정지되었습니다.
예약 처리 기능이 제한됩니다. 사유: 계약 만료 후 재계약 미완료.
);
return (
);
}
function BookingDetailRejectModal1() {
return (
>
}
>
);
}
function BookingDetailRejectModal2() {
return (
>
}
>
);
}
const btnPrimary = {
height: 40, padding: '0 18px', borderRadius: 6, border: 'none',
background: KARE.primary, color: KARE.n000,
fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: FONT,
};
const btnGhost = {
height: 40, padding: '0 16px', borderRadius: 6,
background: KARE.n000, border: `1px solid ${KARE.n300}`,
color: KARE.n700, fontSize: 14, fontWeight: 500, cursor: 'pointer', fontFamily: FONT,
};
const btnDanger = {
height: 40, padding: '0 18px', borderRadius: 6, border: 'none',
background: KARE.error, color: KARE.n000,
fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: FONT,
};
Object.assign(window, {
BookingDetailRequested, BookingDetailConfirmed,
BookingDetailRejected, BookingDetailSuspended,
BookingDetailRejectModal1, BookingDetailRejectModal2,
});