frontend: introduce a date picker component

Pedro Lucas Porcellis porcellis@eletrotupi.com 27 days ago 16e98ad4fc123f536ae1c082c199095289a3ee05
Parents: a8152cd
1 file(s) changed
  • frontend/components/ui/DatePickerField.tsx +90 -0
frontend/components/ui/DatePickerField.tsx
@@ -0,0 +1,90 @@
1 + import { useState, useEffect } from "react";
2 + import { View, Text, Pressable, StyleSheet, Platform } from "react-native";
3 + import DateTimePicker from "@react-native-community/datetimepicker";
4 + import { format } from "date-fns";
5 + import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
6 + import { Colors } from '@/constants/theme';
7 + import { Label } from '@/components/ui/Input';
8 +
9 + export default function DatePickerField({
10 + label,
11 + initialDate = new Date(),
12 + onChange,
13 + minimumDate,
14 + maximumDate,
15 + }) {
16 + const [date, setDate] = useState(initialDate);
17 + const [show, setShow] = useState(false);
18 +
19 + useEffect(() => {
20 + setDate(initialDate);
21 + }, [initialDate]);
22 +
23 + const openPicker = () => setShow(true);
24 +
25 + const handleChange = (event, selectedDate) => {
26 + setShow(false);
27 +
28 + if (selectedDate) {
29 + setDate(selectedDate);
30 + if (onChange) onChange(selectedDate);
31 + }
32 + };
33 +
34 + const formatted = format(date, "dd/MM/yyyy");
35 +
36 + return (
37 + <View>
38 + <Label text={label} />
39 +
40 + <Pressable onPress={openPicker}
41 + style={({ pressed }) => [styles.container, pressed && styles.pressed]}>
42 + <Text style={styles.dateText}>{formatted}</Text>
43 + <MaterialCommunityIcons name="calendar-outline" size={22} color="#6B7280" />
44 + </Pressable>
45 +
46 + {show && (
47 + <DateTimePicker
48 + value={date}
49 + mode="date"
50 + display={"default"}
51 + onChange={handleChange}
52 + minimumDate={minimumDate}
53 + maximumDate={maximumDate}
54 + />
55 + )}
56 + </View>
57 + );
58 + }
59 +
60 + const styles = StyleSheet.create({
61 + label: {
62 + fontWeight: '500',
63 + color: Colors.light.textSecondary,
64 + fontSize: 12,
65 + marginBottom: 8,
66 + letterSpacing: 0.5,
67 + textTransform: 'uppercase'
68 + },
69 + container: {
70 + flexDirection: "row",
71 + alignItems: "center",
72 + justifyContent: "space-between",
73 + backgroundColor: "#F3F4F6", // light gray pill
74 + paddingVertical: 14,
75 + paddingHorizontal: 16,
76 + borderRadius: 10,
77 + borderWidth: 0.5,
78 + borderColor: "#E5E7EB",
79 + minWidth: 220,
80 + },
81 + pressed: {
82 + opacity: 0.8,
83 + },
84 + dateText: {
85 + color: "#111827",
86 + fontSize: 16,
87 + fontWeight: "600",
88 + },
89 + });
90 +