✨ Add custom date feature
Changes
3 files changed, +77 -7
MODIFY
app/task/[id].tsx
+52 -4
@@ -2,6 +2,7 @@
2
2
import { StyleSheet, Alert, ScrollView, TouchableOpacity, TextInput, Platform } from 'react-native';
3
3
import { SafeAreaView } from 'react-native-safe-area-context';
4
4
import { router, useLocalSearchParams } from 'expo-router';
5
+import DateTimePicker from '@react-native-community/datetimepicker';
5
6
import { ThemedView } from '@/components/themed-view';
6
7
import { ThemedText } from '@/components/themed-text';
7
8
import { Task, Priority, TaskStatus, Project, Tag } from '@/types/gtd';
@@ -33,6 +34,7 @@
33
34
const [projects, setProjects] = useState<Project[]>([]);
34
35
const [tags, setTags] = useState<Tag[]>([]);
35
36
const [loading, setLoading] = useState(!isNew);
37
+ const [showDatePicker, setShowDatePicker] = useState(false);
36
38
37
39
useEffect(() => {
38
40
loadData();
@@ -150,6 +152,19 @@
150
152
setTask({ ...task, dueDate: newDate });
151
153
};
152
154
155
+ const handleDateChange = (event: any, selectedDate?: Date) => {
156
+ setShowDatePicker(Platform.OS === 'ios');
157
+
158
+ if (selectedDate) {
159
+ selectedDate.setHours(23, 59, 59, 999);
160
+ setTask({ ...task, dueDate: selectedDate.getTime() });
161
+ }
162
+ };
163
+
164
+ const openDatePicker = () => {
165
+ setShowDatePicker(true);
166
+ };
167
+
153
168
return (
154
169
<SafeAreaView style={styles.container}>
155
170
<ThemedView style={[styles.header, { borderBottomColor: colors.border }]}>
@@ -265,11 +280,34 @@
265
280
task.dueDate && isDueDateToday(task.dueDate, 7) && styles.dateButtonTextActive
266
281
]}>Next Week</ThemedText>
267
282
</TouchableOpacity>
283
+ <TouchableOpacity
284
+ style={[
285
+ styles.dateButton,
286
+ { borderColor: colors.border },
287
+ ]}
288
+ onPress={openDatePicker}
289
+ >
290
+ <ThemedText style={styles.dateButtonText}>📅 Pick Date</ThemedText>
291
+ </TouchableOpacity>
268
292
</ThemedView>
269
293
{task.dueDate && (
270
- <ThemedText style={styles.selectedDate}>
271
- 📅 {formatDate(task.dueDate)}
272
- </ThemedText>
294
+ <ThemedView style={styles.selectedDateContainer}>
295
+ <ThemedText style={styles.selectedDate}>
296
+ 📅 {formatDate(task.dueDate)}
297
+ </ThemedText>
298
+ <TouchableOpacity onPress={() => setTask({ ...task, dueDate: undefined })}>
299
+ <ThemedText style={[styles.clearDateButton, { color: colors.danger }]}>Clear</ThemedText>
300
+ </TouchableOpacity>
301
+ </ThemedView>
302
+ )}
303
+ {showDatePicker && (
304
+ <DateTimePicker
305
+ value={task.dueDate ? new Date(task.dueDate) : new Date()}
306
+ mode="date"
307
+ display={Platform.OS === 'ios' ? 'spinner' : 'default'}
308
+ onChange={handleDateChange}
309
+ minimumDate={new Date()}
310
+ />
273
311
)}
274
312
</ThemedView>
275
313
@@ -417,9 +455,19 @@
417
455
fontWeight: '600',
418
456
},
419
457
selectedDate: {
420
- marginTop: 8,
421
458
fontSize: 14,
422
459
opacity: 0.6,
460
+ flex: 1,
461
+ },
462
+ selectedDateContainer: {
463
+ flexDirection: 'row',
464
+ alignItems: 'center',
465
+ justifyContent: 'space-between',
466
+ marginTop: 8,
467
+ },
468
+ clearDateButton: {
469
+ fontSize: 14,
470
+ fontWeight: '600',
423
471
},
424
472
statusContainer: {
425
473
flexDirection: 'row',
MODIFY
package-lock.json
+24 -3
@@ -10,6 +10,7 @@
10
10
"dependencies": {
11
11
"@expo/vector-icons": "^15.0.3",
12
12
"@react-native-async-storage/async-storage": "^2.2.0",
13
+ "@react-native-community/datetimepicker": "^8.5.0",
13
14
"@react-navigation/bottom-tabs": "^7.4.0",
14
15
"@react-navigation/elements": "^2.6.3",
15
16
"@react-navigation/native": "^7.1.8",
@@ -1467,7 +1468,6 @@
1467
1468
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
1468
1469
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
1469
1470
"license": "MIT",
1470
- "peer": true,
1471
1471
"engines": {
1472
1472
"node": ">=6.9.0"
1473
1473
}
@@ -2887,6 +2887,29 @@
2887
2887
"react-native": "^0.0.0-0 || >=0.65 <1.0"
2888
2888
}
2889
2889
},
2890
+ "node_modules/@react-native-community/datetimepicker": {
2891
+ "version": "8.5.0",
2892
+ "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-8.5.0.tgz",
2893
+ "integrity": "sha512-RMWll1aPppMtzdJz4we4poNzVj9WUw5URHID7D2ICjGZq3KjrwwexvBnzp75EIYE/ihHXCn/OvYKe73fws9Y/g==",
2894
+ "license": "MIT",
2895
+ "dependencies": {
2896
+ "invariant": "^2.2.4"
2897
+ },
2898
+ "peerDependencies": {
2899
+ "expo": ">=52.0.0",
2900
+ "react": "*",
2901
+ "react-native": "*",
2902
+ "react-native-windows": "*"
2903
+ },
2904
+ "peerDependenciesMeta": {
2905
+ "expo": {
2906
+ "optional": true
2907
+ },
2908
+ "react-native-windows": {
2909
+ "optional": true
2910
+ }
2911
+ }
2912
+ },
2890
2913
"node_modules/@react-native/assets-registry": {
2891
2914
"version": "0.81.5",
2892
2915
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz",
@@ -10623,7 +10646,6 @@
10623
10646
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.3.tgz",
10624
10647
"integrity": "sha512-GP8wsi1u3nqvC1fMab/m8gfFwFyldawElCcUSBJQgfrXeLmsPPUOpDw44lbLeCpcwUuLa05WTVePdTEwCLTUZg==",
10625
10648
"license": "MIT",
10626
- "peer": true,
10627
10649
"dependencies": {
10628
10650
"react-native-is-edge-to-edge": "^1.2.1",
10629
10651
"semver": "7.7.2"
@@ -10712,7 +10734,6 @@
10712
10734
"resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.1.tgz",
10713
10735
"integrity": "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==",
10714
10736
"license": "MIT",
10715
- "peer": true,
10716
10737
"dependencies": {
10717
10738
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
10718
10739
"@babel/plugin-transform-class-properties": "^7.0.0-0",
MODIFY
package.json
+1 -0
@@ -13,6 +13,7 @@
13
13
"dependencies": {
14
14
"@expo/vector-icons": "^15.0.3",
15
15
"@react-native-async-storage/async-storage": "^2.2.0",
16
+ "@react-native-community/datetimepicker": "^8.5.0",
16
17
"@react-navigation/bottom-tabs": "^7.4.0",
17
18
"@react-navigation/elements": "^2.6.3",
18
19
"@react-navigation/native": "^7.1.8",