import { MaterialCommunityIcons } from "@expo/vector-icons"; import { useState } from "react"; import { Image, Text, TextInput, TouchableOpacity, View } from "react-native"; import ReactNativeModal from "react-native-modal"; import { CustomButton } from "@/components/custom-button"; import { driverPhotoUri } from "@/lib/driver-photo"; import { fetchAPI } from "@/lib/fetch"; import { useT } from "@/lib/i18n"; import { useTheme } from "@/lib/theme"; // The post-trip rating prompt, shared by both apps: a rider rates their driver // and a driver rates their rider through the same endpoint, which infers who // is rating from the caller's role on the ride. Both sides get the same sheet // so the two directions can't drift apart. type Props = { visible: boolean; rideId: number; /** Who is being rated — only used for the copy. */ subjectName?: string | null; subjectAvatar?: string | null; /** Rider-facing copy differs from driver-facing copy. */ audience: "rider" | "driver"; onDone: () => void; /** Called on "not now"; omit to make the rating unskippable. */ onSkip?: () => void; }; export const RatingSheet = ({ visible, rideId, subjectName, subjectAvatar, audience, onDone, onSkip, }: Props) => { const t = useT(); const { isDark } = useTheme(); const [stars, setStars] = useState(0); const [comment, setComment] = useState(""); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); const submit = async () => { if (stars < 1) return; setSubmitting(true); setError(null); try { await fetchAPI(`/(api)/ride/${rideId}/rate`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ rating: stars, comment: comment.trim() || null, }), }); onDone(); } catch (err) { console.log("[RATE_RIDE]: ", err); setError(t("rating.error")); } finally { setSubmitting(false); } }; return ( {subjectAvatar ? ( ) : null} {audience === "rider" ? t("rating.rateDriverTitle", { name: subjectName ?? "" }) : t("rating.rateRiderTitle", { name: subjectName ?? "" })} {t("rating.subtitle")} {[1, 2, 3, 4, 5].map((value) => ( setStars(value)} hitSlop={{ top: 8, bottom: 8, left: 4, right: 4 }} accessibilityLabel={t("rating.starLabel", { n: value })} > ))} {error ? ( {error} ) : null} {onSkip ? ( {t("rating.notNow")} ) : null} ); };