140 lines
3.8 KiB
TypeScript
140 lines
3.8 KiB
TypeScript
import React from "react";
|
|
import {
|
|
View,
|
|
Text,
|
|
TouchableOpacity,
|
|
Modal,
|
|
FlatList,
|
|
StyleSheet,
|
|
} from "react-native";
|
|
import { X, Check } from "lucide-react-native";
|
|
import { useThemeColor } from "@/hooks/useThemeColor";
|
|
import { useColorScheme } from "@/hooks/useColorScheme";
|
|
import { TabloMember } from "@/hooks/members";
|
|
|
|
type AssigneePickerProps = {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
members: TabloMember[];
|
|
selectedId: string | null;
|
|
onSelect: (memberId: string | null) => void;
|
|
};
|
|
|
|
export default function AssigneePicker({
|
|
visible,
|
|
onClose,
|
|
members,
|
|
selectedId,
|
|
onSelect,
|
|
}: AssigneePickerProps) {
|
|
const colorScheme = useColorScheme();
|
|
const isDark = colorScheme === "dark";
|
|
const bgColor = useThemeColor({ light: "#ffffff", dark: "#1f2937" }, "background");
|
|
const textColor = useThemeColor({ light: "#1f2937", dark: "#f9fafb" }, "text");
|
|
const subtextColor = useThemeColor({ light: "#6b7280", dark: "#9ca3af" }, "text");
|
|
const borderColor = isDark ? "#374151" : "#e5e7eb";
|
|
|
|
const handleSelect = (id: string | null) => {
|
|
onSelect(id);
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<Modal visible={visible} animationType="slide" transparent onRequestClose={onClose}>
|
|
<View style={styles.overlay}>
|
|
<View style={[styles.sheet, { backgroundColor: bgColor }]}>
|
|
<View style={[styles.header, { borderBottomColor: borderColor }]}>
|
|
<Text style={[styles.title, { color: textColor }]}>Assigné à</Text>
|
|
<TouchableOpacity onPress={onClose}>
|
|
<X size={22} color={textColor} />
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
<TouchableOpacity
|
|
style={[styles.row, { borderBottomColor: borderColor }]}
|
|
onPress={() => handleSelect(null)}
|
|
>
|
|
<View style={[styles.avatar, styles.avatarEmpty]} />
|
|
<Text style={[styles.name, { color: subtextColor }]}>Non assigné</Text>
|
|
{selectedId === null && <Check size={18} color="#3b82f6" />}
|
|
</TouchableOpacity>
|
|
|
|
<FlatList
|
|
data={members}
|
|
keyExtractor={(item) => item.id}
|
|
renderItem={({ item }) => (
|
|
<TouchableOpacity
|
|
style={[styles.row, { borderBottomColor: borderColor }]}
|
|
onPress={() => handleSelect(item.id)}
|
|
>
|
|
<View style={styles.avatar}>
|
|
<Text style={styles.avatarText}>
|
|
{item.name.charAt(0).toUpperCase()}
|
|
</Text>
|
|
</View>
|
|
<Text style={[styles.name, { color: textColor }]}>{item.name}</Text>
|
|
{selectedId === item.id && <Check size={18} color="#3b82f6" />}
|
|
</TouchableOpacity>
|
|
)}
|
|
/>
|
|
</View>
|
|
</View>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
overlay: {
|
|
flex: 1,
|
|
justifyContent: "flex-end",
|
|
backgroundColor: "rgba(0,0,0,0.4)",
|
|
},
|
|
sheet: {
|
|
borderTopLeftRadius: 20,
|
|
borderTopRightRadius: 20,
|
|
maxHeight: "60%",
|
|
paddingBottom: 34,
|
|
},
|
|
header: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
padding: 16,
|
|
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
},
|
|
title: {
|
|
fontSize: 17,
|
|
fontWeight: "700",
|
|
},
|
|
row: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
paddingVertical: 12,
|
|
paddingHorizontal: 16,
|
|
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
gap: 12,
|
|
},
|
|
avatar: {
|
|
width: 32,
|
|
height: 32,
|
|
borderRadius: 16,
|
|
backgroundColor: "#3b82f6",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
},
|
|
avatarEmpty: {
|
|
backgroundColor: "transparent",
|
|
borderWidth: 1.5,
|
|
borderColor: "#d1d5db",
|
|
borderStyle: "dashed",
|
|
},
|
|
avatarText: {
|
|
color: "#ffffff",
|
|
fontSize: 14,
|
|
fontWeight: "600",
|
|
},
|
|
name: {
|
|
flex: 1,
|
|
fontSize: 15,
|
|
},
|
|
});
|