diff --git a/xtablo-expo/components/tasks/AssigneePicker.tsx b/xtablo-expo/components/tasks/AssigneePicker.tsx new file mode 100644 index 0000000..9c2ec23 --- /dev/null +++ b/xtablo-expo/components/tasks/AssigneePicker.tsx @@ -0,0 +1,140 @@ +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 ( + + + + + Assigné à + + + + + + handleSelect(null)} + > + + Non assigné + {selectedId === null && } + + + item.id} + renderItem={({ item }) => ( + handleSelect(item.id)} + > + + + {item.name.charAt(0).toUpperCase()} + + + {item.name} + {selectedId === item.id && } + + )} + /> + + + + ); +} + +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, + }, +}); diff --git a/xtablo-expo/components/tasks/EtapePicker.tsx b/xtablo-expo/components/tasks/EtapePicker.tsx new file mode 100644 index 0000000..da5dc1b --- /dev/null +++ b/xtablo-expo/components/tasks/EtapePicker.tsx @@ -0,0 +1,114 @@ +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 { Etape } from "@/types/tasks.types"; + +type EtapePickerProps = { + visible: boolean; + onClose: () => void; + etapes: Etape[]; + selectedId: string | null; + onSelect: (etapeId: string | null) => void; +}; + +export default function EtapePicker({ + visible, + onClose, + etapes, + selectedId, + onSelect, +}: EtapePickerProps) { + 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 ( + + + + + Étape + + + + + + handleSelect(null)} + > + Sans Étape + {selectedId === null && } + + + item.id} + renderItem={({ item }) => ( + handleSelect(item.id)} + > + {item.title} + {selectedId === item.id && } + + )} + /> + + + + ); +} + +const styles = StyleSheet.create({ + overlay: { + flex: 1, + justifyContent: "flex-end", + backgroundColor: "rgba(0,0,0,0.4)", + }, + sheet: { + borderTopLeftRadius: 20, + borderTopRightRadius: 20, + maxHeight: "50%", + 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: 14, + paddingHorizontal: 16, + borderBottomWidth: StyleSheet.hairlineWidth, + }, + name: { + flex: 1, + fontSize: 15, + }, +});