BaaS_Driver_Android_App/components/service/IssueSelectorModal.tsx

193 lines
4.9 KiB
TypeScript

import React, { useState } from "react";
import {
View,
Text,
TextInput,
ScrollView,
TouchableOpacity,
Modal,
StyleSheet,
} from "react-native";
import Checkbox from "expo-checkbox";
import { issueConfig } from "@/constants/config";
import CloseIcon from "@/assets/icons/close.svg";
interface IssueSelectorModalProps {
visible: boolean;
onClose: () => void;
onSelect: (selectedValues: string[]) => void;
}
export default function IssueSelectorModal({
visible,
onClose,
onSelect,
}: IssueSelectorModalProps) {
const [selectedValues, setSelectedValues] = useState<string[]>([]);
const [search, setSearch] = useState("");
const toggleValue = (value: string) => {
setSelectedValues((prev) =>
prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value]
);
};
const filteredConfig = issueConfig
.map((group) => ({
...group,
options: group.options.filter((option) =>
option.label.toLowerCase().includes(search.toLowerCase())
),
}))
.filter((group) => group.options.length > 0);
const clearSelection = () => setSelectedValues([]);
return (
<Modal visible={visible} animationType="slide">
<View style={styles.container}>
{/* Header */}
<View style={styles.headerBar}>
<Text>Select Issue</Text>
<TouchableOpacity onPress={onClose}>
<CloseIcon />
</TouchableOpacity>
</View>
<View style={styles.divider}></View>
<View style={styles.header}>
<TextInput
placeholder="Search"
placeholderTextColor="#939DAE"
value={search}
onChangeText={setSearch}
style={styles.searchBar}
/>
</View>
<View style={styles.counterBar}>
<Text
style={styles.counterText}
>{`${selectedValues.length}/23 Selected`}</Text>
<TouchableOpacity onPress={clearSelection}>
<Text style={styles.clearText}>Clear</Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.scrollArea}>
{filteredConfig.map((group) => (
<View key={group.category}>
<Text style={styles.category}>{group.category}</Text>
{group.options.map((option) => (
<TouchableOpacity
key={option.value}
style={styles.itemRow}
onPress={() => toggleValue(option.value)}
>
<Checkbox
value={selectedValues.includes(option.value)}
onValueChange={() => toggleValue(option.value)}
color={
selectedValues.includes(option.value)
? "#252A34"
: undefined
}
/>
<Text style={styles.itemLabel}>{option.label}</Text>
</TouchableOpacity>
))}
</View>
))}
</ScrollView>
<View>
<TouchableOpacity
style={styles.doneButton}
onPress={() => {
onSelect(selectedValues);
onClose();
}}
>
<Text style={styles.doneText}>Done</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
);
}
const styles = StyleSheet.create({
headerBar: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingHorizontal: 16,
paddingVertical: 12,
backgroundColor: "#F9F9F9",
},
container: { flex: 1, backgroundColor: "#fff" },
header: {
paddingHorizontal: 16,
paddingVertical: 12,
backgroundColor: "#FCFCFC",
},
searchBar: {
backgroundColor: "#fff",
borderColor: "#D8DDE6",
borderWidth: 1,
borderRadius: 4,
paddingHorizontal: 12,
height: 36,
fontSize: 14,
color: "#252A34",
},
counterBar: {
flexDirection: "row",
justifyContent: "space-between",
paddingHorizontal: 20,
paddingVertical: 12,
backgroundColor: "#FCFCFC",
},
divider: {
height: 1,
backgroundColor: "#E5E9F0",
},
counterText: {
fontSize: 14,
color: "#555",
fontWeight: "600",
},
clearText: {
fontSize: 14,
color: "#ADB4BD",
},
scrollArea: { paddingHorizontal: 0, backgroundColor: "#FCFCFC" },
category: {
fontSize: 14,
color: "#252A34",
paddingVertical: 12,
paddingHorizontal: 16,
backgroundColor: "#F9F9F9",
},
itemRow: {
flexDirection: "row",
alignItems: "center",
paddingVertical: 8,
paddingHorizontal: 16,
backgroundColor: "#FCFCFC",
},
itemLabel: {
marginLeft: 12,
fontSize: 12,
color: "#252A34",
},
doneButton: {
backgroundColor: "#00875F",
padding: 16,
alignItems: "center",
},
doneText: {
color: "#fff",
fontSize: 14,
fontWeight: "bold",
},
});