gitshark

Clone repository

git clone https://git.vilip.de/git/vilip/taskflow.git
git clone git@git.vilip.de:vilip/taskflow.git

← Commits

✨ Add custom date feature

84ffbc62d23af26b0c191ccea9c9dcdc8894c997 · vvilip · 2025-11-06T21:51:49Z

Changes

3 files changed, +77 -7

MODIFY app/task/[id].tsx +52 -4
diff --git "a/app/task/\133id\135.tsx" "b/app/task/\133id\135.tsx"
index 550e19c..2fad44e 100644
--- "a/app/task/\133id\135.tsx"
+++ "b/app/task/\133id\135.tsx"
@@ -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
diff --git a/package-lock.json b/package-lock.json
index 15ed89c..5ce7661 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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
diff --git a/package.json b/package.json
index 479e04d..489e703 100644
--- a/package.json
+++ b/package.json
@@ -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",

Keyboard shortcuts

?Show this help
g hGo home
EscClose dialog