185 lines
4.5 KiB
TypeScript
185 lines
4.5 KiB
TypeScript
import React, { useState } from "react";
|
|
import {
|
|
View,
|
|
Text,
|
|
TouchableOpacity,
|
|
StyleSheet,
|
|
Modal,
|
|
Platform,
|
|
ScrollView,
|
|
} from "react-native";
|
|
import { Ionicons } from "@expo/vector-icons";
|
|
import { TripStatus, TRIP_STATUS_CONFIG } from "./types";
|
|
|
|
interface StatusDropdownProps {
|
|
value: TripStatus | null;
|
|
onChange: (status: TripStatus | null) => void;
|
|
}
|
|
|
|
const STATUS_OPTIONS: Array<{ value: TripStatus | null; label: string }> = [
|
|
{ value: null, label: "Vui lòng chọn" },
|
|
{ value: "created", label: "Đã khởi tạo" },
|
|
{ value: "pending", label: "Chờ duyệt" },
|
|
{ value: "approved", label: "Đã duyệt" },
|
|
{ value: "in-progress", label: "Đang hoạt động" },
|
|
{ value: "completed", label: "Hoàn thành" },
|
|
{ value: "cancelled", label: "Đã hủy" },
|
|
];
|
|
|
|
export default function StatusDropdown({
|
|
value,
|
|
onChange,
|
|
}: StatusDropdownProps) {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
const selectedLabel =
|
|
STATUS_OPTIONS.find((opt) => opt.value === value)?.label || "Vui lòng chọn";
|
|
|
|
const handleSelect = (status: TripStatus | null) => {
|
|
onChange(status);
|
|
setIsOpen(false);
|
|
};
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<Text style={styles.label}>Trạng thái</Text>
|
|
<TouchableOpacity
|
|
style={styles.selector}
|
|
onPress={() => setIsOpen(true)}
|
|
activeOpacity={0.7}
|
|
>
|
|
<Text style={[styles.selectorText, !value && styles.placeholder]}>
|
|
{selectedLabel}
|
|
</Text>
|
|
<Ionicons name="ellipsis-horizontal" size={20} color="#6B7280" />
|
|
</TouchableOpacity>
|
|
|
|
<Modal
|
|
visible={isOpen}
|
|
transparent
|
|
animationType="fade"
|
|
onRequestClose={() => setIsOpen(false)}
|
|
>
|
|
<TouchableOpacity
|
|
style={styles.modalOverlay}
|
|
activeOpacity={1}
|
|
onPress={() => setIsOpen(false)}
|
|
>
|
|
<View style={styles.modalContent}>
|
|
<ScrollView>
|
|
{STATUS_OPTIONS.map((option, index) => (
|
|
<TouchableOpacity
|
|
key={index}
|
|
style={[
|
|
styles.option,
|
|
value === option.value && styles.selectedOption,
|
|
]}
|
|
onPress={() => handleSelect(option.value)}
|
|
>
|
|
<Text
|
|
style={[
|
|
styles.optionText,
|
|
value === option.value && styles.selectedOptionText,
|
|
]}
|
|
>
|
|
{option.label}
|
|
</Text>
|
|
{value === option.value && (
|
|
<Ionicons name="checkmark" size={20} color="#3B82F6" />
|
|
)}
|
|
</TouchableOpacity>
|
|
))}
|
|
</ScrollView>
|
|
</View>
|
|
</TouchableOpacity>
|
|
</Modal>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
marginBottom: 20,
|
|
},
|
|
label: {
|
|
fontSize: 16,
|
|
fontWeight: "600",
|
|
color: "#111827",
|
|
marginBottom: 8,
|
|
fontFamily: Platform.select({
|
|
ios: "System",
|
|
android: "Roboto",
|
|
default: "System",
|
|
}),
|
|
},
|
|
selector: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
backgroundColor: "#FFFFFF",
|
|
borderWidth: 1,
|
|
borderColor: "#D1D5DB",
|
|
borderRadius: 8,
|
|
paddingHorizontal: 16,
|
|
paddingVertical: 12,
|
|
},
|
|
selectorText: {
|
|
fontSize: 16,
|
|
color: "#111827",
|
|
fontFamily: Platform.select({
|
|
ios: "System",
|
|
android: "Roboto",
|
|
default: "System",
|
|
}),
|
|
},
|
|
placeholder: {
|
|
color: "#9CA3AF",
|
|
},
|
|
modalOverlay: {
|
|
flex: 1,
|
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
},
|
|
modalContent: {
|
|
backgroundColor: "#FFFFFF",
|
|
borderRadius: 12,
|
|
width: "80%",
|
|
maxHeight: "60%",
|
|
overflow: "hidden",
|
|
shadowColor: "#000",
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 4,
|
|
},
|
|
shadowOpacity: 0.3,
|
|
shadowRadius: 8,
|
|
elevation: 8,
|
|
},
|
|
option: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
paddingHorizontal: 20,
|
|
paddingVertical: 16,
|
|
borderBottomWidth: 1,
|
|
borderBottomColor: "#F3F4F6",
|
|
},
|
|
selectedOption: {
|
|
backgroundColor: "#EFF6FF",
|
|
},
|
|
optionText: {
|
|
fontSize: 16,
|
|
color: "#111827",
|
|
fontFamily: Platform.select({
|
|
ios: "System",
|
|
android: "Roboto",
|
|
default: "System",
|
|
}),
|
|
},
|
|
selectedOptionText: {
|
|
color: "#3B82F6",
|
|
fontWeight: "600",
|
|
},
|
|
});
|