import { useState } from "react"; import { Text, TouchableOpacity, View } from "react-native"; import ReactNativeModal from "react-native-modal"; import { useT } from "@/lib/i18n"; // Cancelling asks *why* before it asks "are you sure". The reason codes are // fixed (lib/ride-lifecycle CANCELLATION_REASONS) rather than free text, so // the admin portal can count them — "driver never showed" and "I changed my // mind" are the same cancellation in the ledger otherwise, and only one of // them is a problem worth chasing. const RIDER_REASONS = [ "wait_too_long", "driver_no_show", "unreachable", "wrong_address", "changed_mind", "other", ] as const; const DRIVER_REASONS = [ "rider_no_show", "unreachable", "wrong_address", "vehicle_issue", "other", ] as const; type Props = { visible: boolean; audience: "rider" | "driver"; submitting?: boolean; onCancel: () => void; onConfirm: (reason: string) => void; }; export const CancelSheet = ({ visible, audience, submitting, onCancel, onConfirm, }: Props) => { const t = useT(); const [reason, setReason] = useState(null); const reasons = audience === "rider" ? RIDER_REASONS : DRIVER_REASONS; return ( {t("cancelSheet.title")} {audience === "rider" ? t("cancelSheet.subtitleRider") : t("cancelSheet.subtitleDriver")} {reasons.map((code) => { const selected = reason === code; return ( setReason(code)} className={`rounded-2xl border px-4 py-3 mb-2 ${ selected ? "border-primary-500 bg-primary-500/10" : "border-neutral-200 dark:border-neutral-800" }`} > {t(`cancelSheet.reasons.${code}`)} ); })} reason && onConfirm(reason)} disabled={!reason || submitting} className={`rounded-full py-3 items-center mt-3 bg-rose-500 ${ !reason || submitting ? "opacity-50" : "" }`} > {submitting ? t("cancelSheet.cancelling") : t("cancelSheet.confirm")} {t("cancelSheet.keepRide")} ); };