From c3058e4464e90a26c7861739ef0d3799e103d6ef Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:16:18 +0200 Subject: [PATCH 01/31] added header, mock reminders --- app/(auth)/reminders/index.tsx | 51 +++++++- components/pages/reminders/remindersList.tsx | 119 +++++++++++++++++++ 2 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 components/pages/reminders/remindersList.tsx diff --git a/app/(auth)/reminders/index.tsx b/app/(auth)/reminders/index.tsx index 7d92969..39a18c8 100644 --- a/app/(auth)/reminders/index.tsx +++ b/app/(auth)/reminders/index.tsx @@ -1,7 +1,46 @@ -import {View} from "react-native-ui-lib"; - +import { Card, Text, View } from "react-native-ui-lib"; +import { StyleSheet } from "react-native"; +import RemindersList from "@/components/pages/reminders/remindersList"; export default function Screen() { - return ( - - ) -} \ No newline at end of file + return ( + + + + + Good Morning, + + + Hello Ryanae! + + + + 😇 + + + + + ); +} + +const styles = StyleSheet.create({ + banner: { + backgroundColor: "#f68d51", + height: "27%", + }, + greetingContainer: { + marginLeft: "8%", + paddingTop: 15, + paddingBottom: 20, + flex: 1, + flexDirection: "column", + justifyContent: "space-between", + }, + footerContainer: { + height: 70, + backgroundColor: "#f9b076", + marginTop: "auto", + borderTopLeftRadius: 30, + marginLeft: "8%", + paddingLeft: "5%", + }, +}); diff --git a/components/pages/reminders/remindersList.tsx b/components/pages/reminders/remindersList.tsx new file mode 100644 index 0000000..78c2023 --- /dev/null +++ b/components/pages/reminders/remindersList.tsx @@ -0,0 +1,119 @@ +import { useState } from "react"; +import { StyleSheet } from "react-native"; +import { + Button, + Card, + Checkbox, + Icon, + ListItem, + Text, + View, +} from "react-native-ui-lib"; + +interface Reminder { + title: string; + date: string; + time: string; + done: boolean; +} + +const RemindersList = () => { + const [reminders, setReminders] = useState([ + { + title: "Shaving Time", + date: "26/02/2023", + time: "09:30", + done: true, + }, + { + title: "Gonna get a food order", + date: "27/02/2023", + time: "10:30", + done: false, + }, + ]); + return ( + + + Reminders + + + + {reminders.map((reminder, index) => ( + + + + + + {reminder.title} + + {reminder.date} {reminder.time} + + + + { + const updatedReminders = reminders.map((item, i) => + i === index ? { ...item, done: !item.done } : item + ); + setReminders(updatedReminders); + }} + /> + + + ))} + + + ); +}; + +const styles = StyleSheet.create({ + header: { + flex: 1, + flexDirection: "row", + }, + listContainer: { + marginLeft: "8%", + marginTop: "4%", + marginRight: "4%", + }, + button: { + backgroundColor: "white", + color: "black", + borderColor: "lightgray", + borderWidth: 1, + borderRadius: 5, + }, + buttonText: { + margin: 0, + }, + card: { + display: "flex", + justifyContent: "space-between", + }, + cardList: { + marginTop: 10, + }, + icon: { + borderRadius: 50, + height: 45, + width: 45, + backgroundColor: "#fcf4eb", + marginRight: 10 + }, +}); +export default RemindersList; From 33421b2ef450eef6dcbecd262475afb677d43b40 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Sat, 3 Aug 2024 19:44:02 +0200 Subject: [PATCH 02/31] added new reminder modal --- .../pages/reminders/addReminderModal.tsx | 246 ++++++++++++++++++ components/pages/reminders/remindersList.tsx | 32 +-- components/ui/ButtonOutlined.tsx | 34 +++ package-lock.json | 24 ++ package.json | 1 + 5 files changed, 321 insertions(+), 16 deletions(-) create mode 100644 components/pages/reminders/addReminderModal.tsx create mode 100644 components/ui/ButtonOutlined.tsx diff --git a/components/pages/reminders/addReminderModal.tsx b/components/pages/reminders/addReminderModal.tsx new file mode 100644 index 0000000..11bec90 --- /dev/null +++ b/components/pages/reminders/addReminderModal.tsx @@ -0,0 +1,246 @@ +import { StyleSheet } from "react-native"; +import React, { useState } from "react"; +import { + Dialog, + Text, + PanningProvider, + TextField, + Button, + View, + Checkbox, + Switch, + Picker, +} from "react-native-ui-lib"; +import ButtonOutlined from "@/components/ui/ButtonOutlined"; +import AntDesign from "@expo/vector-icons/AntDesign"; +import Feather from "@expo/vector-icons/Feather"; +import Ionicons from "@expo/vector-icons/Ionicons"; +import { DateTimePicker } from "react-native-ui-lib"; +import { TouchableOpacity } from "react-native-gesture-handler"; + +interface ReminderModalProps { + visible: boolean; + onClose: () => void; + /*onSave: (reminderText: string) => void;*/ +} + +interface reminderOptions { + label: string; + value: string; +} + +const AddReminderModal = (props: ReminderModalProps) => { + const { visible, onClose /*, onSave*/ } = props; + const [reminderTitle, setReminderTitle] = useState(""); + const [time, setTime] = useState(new Date()); + const [autoRepeat, setAutoRepeat] = useState(false); + const [reminder, setReminder] = useState({ + label: "Remind me just in time", + value: "just-in-time", + }); + + const reminderOptions = [ + { label: "Remind me just in time", value: "just-in-time" }, + { label: "Remind me 5 minutes before", value: "5-min-before" }, + { label: "Remind me 10 minutes before", value: "10-min-before" }, + { label: "Remind me 15 minutes before", value: "15-min-before" }, + { label: "Remind me 30 minutes before", value: "30-min-before" }, + { label: "Remind me 1 hour before", value: "1-hr-before" }, + { label: "Remind me 1 day before", value: "1-day-before" }, + ]; + + const handleDateTimeChange = (selectedTime: Date) => { + setTime(selectedTime); + }; + + return ( + + + New Reminder + + + + Profiles + {}} + > + + + + setReminderTitle(text)} + placeholder="Reminder Title" + text70L + /> + + + + + Reminder Time + + + + + + + + + + + + + { + setReminder({ label: item.label, value: item.value }); + }} + useDialog + fieldType="form" + placeholder="Select a reminder" + items={reminderOptions} + trailingAccessory={ + + } + > + + + + + + + Auto Repeat + setAutoRepeat(value)} + /> + + + + + + {}} + > + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingVertical: 10, + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between' + }, + inner: { + paddingHorizontal: 20, + display: "flex", + flexDirection: "column", + }, + title: { + fontSize: 20, + fontWeight: "400", + textAlign: "center", + }, + divider: { + width: "100%", + height: 1, + backgroundColor: "#E0E0E0", + marginVertical: 10, + }, + iconTitle: { + padding: 10, + borderRadius: 10, + borderWidth: 1, + borderColor: "#E0E0E0", + display: "flex", + flexDirection: "row", + }, + inputsBetween: { + paddingVertical: 12, + paddingHorizontal: 15, + marginVertical: 5, + borderRadius: 10, + borderWidth: 1, + borderColor: "#E0E0E0", + display: "flex", + alignItems: "center", + flexDirection: "row", + justifyContent: "space-between", + }, + inputsStart: { + paddingVertical: 12, + paddingHorizontal: 15, + marginVertical: 5, + borderRadius: 10, + borderWidth: 1, + borderColor: "#E0E0E0", + display: "flex", + alignItems: "center", + flexDirection: "row", + justifyContent: "flex-start", + }, +}); + +export default AddReminderModal; diff --git a/components/pages/reminders/remindersList.tsx b/components/pages/reminders/remindersList.tsx index 78c2023..f61ddac 100644 --- a/components/pages/reminders/remindersList.tsx +++ b/components/pages/reminders/remindersList.tsx @@ -1,14 +1,8 @@ import { useState } from "react"; import { StyleSheet } from "react-native"; -import { - Button, - Card, - Checkbox, - Icon, - ListItem, - Text, - View, -} from "react-native-ui-lib"; +import { Button, Card, Checkbox, Text, View } from "react-native-ui-lib"; +import AddReminderModal from "./addReminderModal"; +import ButtonOutlined from "@/components/ui/ButtonOutlined"; interface Reminder { title: string; @@ -18,6 +12,7 @@ interface Reminder { } const RemindersList = () => { + const [isModalVisible, setIsModalVisible] = useState(false); const [reminders, setReminders] = useState([ { title: "Shaving Time", @@ -32,8 +27,13 @@ const RemindersList = () => { done: false, }, ]); + return ( + setIsModalVisible(false)} + /> { }} > Reminders - + setIsModalVisible(true)} + /> {reminders.map((reminder, index) => ( - + {reminder.title} @@ -113,7 +113,7 @@ const styles = StyleSheet.create({ height: 45, width: 45, backgroundColor: "#fcf4eb", - marginRight: 10 + marginRight: 10, }, }); export default RemindersList; diff --git a/components/ui/ButtonOutlined.tsx b/components/ui/ButtonOutlined.tsx new file mode 100644 index 0000000..298b257 --- /dev/null +++ b/components/ui/ButtonOutlined.tsx @@ -0,0 +1,34 @@ +import { StyleSheet, View } from "react-native"; +import React from "react"; +import { Text, Button } from "react-native-ui-lib"; + +interface ButtonProps { + title: string; + size: keyof typeof Button.sizes; + onPress: () => void; +} + +const ButtonOutlined = (props: ButtonProps) => { + const { size, onPress, title } = props; + return ( + + ); +}; +export default ButtonOutlined; +const styles = StyleSheet.create({ + button: { + backgroundColor: "white", + color: "black", + borderColor: "lightgray", + borderWidth: 1, + borderRadius: 5, + padding: 0, + marginHorizontal: 0 + }, + buttonText: { + }, +}); diff --git a/package-lock.json b/package-lock.json index 18d0d5d..eccf16f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@expo/vector-icons": "^14.0.2", "@react-native-community/blur": "^4.4.0", + "@react-native-community/datetimepicker": "^8.2.0", "@react-native-firebase/app": "^20.3.0", "@react-native-firebase/auth": "^20.3.0", "@react-native-firebase/crashlytics": "^20.3.0", @@ -7011,6 +7012,29 @@ "node": ">=8" } }, + "node_modules/@react-native-community/datetimepicker": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-8.2.0.tgz", + "integrity": "sha512-qrUPhiBvKGuG9Y+vOqsc56RPFcHa1SU2qbAMT0hfGkoFIj3FodE0VuPVrEa8fgy7kcD5NQmkZIKgHOBLV0+hWg==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4" + }, + "peerDependencies": { + "expo": ">=50.0.0", + "react": "*", + "react-native": "*", + "react-native-windows": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "react-native-windows": { + "optional": true + } + } + }, "node_modules/@react-native-firebase/app": { "version": "20.3.0", "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-20.3.0.tgz", diff --git a/package.json b/package.json index e48a3ef..90dc306 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dependencies": { "@expo/vector-icons": "^14.0.2", "@react-native-community/blur": "^4.4.0", + "@react-native-community/datetimepicker": "^8.2.0", "@react-native-firebase/app": "^20.3.0", "@react-native-firebase/auth": "^20.3.0", "@react-native-firebase/crashlytics": "^20.3.0", From 3955a85bc7a780a90f308e841d4e62b95a1de362 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Sun, 4 Aug 2024 19:06:19 +0200 Subject: [PATCH 03/31] changes to reminders modal --- .../pages/reminders/addReminderModal.tsx | 71 ++++++++++++------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/components/pages/reminders/addReminderModal.tsx b/components/pages/reminders/addReminderModal.tsx index 11bec90..be8a690 100644 --- a/components/pages/reminders/addReminderModal.tsx +++ b/components/pages/reminders/addReminderModal.tsx @@ -7,7 +7,6 @@ import { TextField, Button, View, - Checkbox, Switch, Picker, } from "react-native-ui-lib"; @@ -34,10 +33,7 @@ const AddReminderModal = (props: ReminderModalProps) => { const [reminderTitle, setReminderTitle] = useState(""); const [time, setTime] = useState(new Date()); const [autoRepeat, setAutoRepeat] = useState(false); - const [reminder, setReminder] = useState({ - label: "Remind me just in time", - value: "just-in-time", - }); + const [reminder, setReminder] = useState("just-in-time"); const reminderOptions = [ { label: "Remind me just in time", value: "just-in-time" }, @@ -59,7 +55,6 @@ const AddReminderModal = (props: ReminderModalProps) => { onDismiss={onClose} panDirection={PanningProvider.Directions.RIGHT} containerStyle={{ borderRadius: 12, backgroundColor: "white" }} - height="70%" > New Reminder @@ -78,7 +73,7 @@ const AddReminderModal = (props: ReminderModalProps) => { title={"+ Add"} size={Button.sizes.xSmall} onPress={() => {}} - > + /> { /> { - setReminder({ label: item.label, value: item.value }); - }} + value={reminder} + onChange={(item) => setReminder(item)} useDialog fieldType="form" placeholder="Select a reminder" - items={reminderOptions} trailingAccessory={ { color="black" /> } - > + > + {reminderOptions.map((option) => ( + + ))} + @@ -171,14 +171,27 @@ const AddReminderModal = (props: ReminderModalProps) => { /> - - - - {}} - > + + + + + + + + + + setShow(false)}> + Go back + + + + + setShowManualInputModal(false)}/> + + ) +} \ No newline at end of file diff --git a/components/pages/calendar/ManuallyAddEventModal.tsx b/components/pages/calendar/ManuallyAddEventModal.tsx new file mode 100644 index 0000000..23970ed --- /dev/null +++ b/components/pages/calendar/ManuallyAddEventModal.tsx @@ -0,0 +1,260 @@ +import { + Avatar, + Colors, + DateTimePicker, + LoaderScreen, + Modal, + Picker, + Switch, + Text, + TextField, + View +} from "react-native-ui-lib"; +import {ScrollView, TouchableOpacity} from "react-native-gesture-handler"; +import {useSafeAreaInsets} from "react-native-safe-area-context"; +import {useState} from "react"; +import {MaterialIcons} from "@expo/vector-icons"; +import {PickerMultiValue} from "react-native-ui-lib/src/components/picker/types"; +import {useAuthContext} from "@/contexts/AuthContext"; +import {useCreateEvent} from "@/hooks/firebase/useCreateEvent"; +import {EventData} from "@/hooks/firebase/types/eventData"; + +const daysOfWeek = [ + {label: "Monday", value: "monday"}, + {label: "Tuesday", value: "tuesday"}, + {label: "Wednesday", value: "wednesday"}, + {label: "Thursday", value: "thursday"}, + {label: "Friday", value: "friday"}, + {label: "Saturday", value: "saturday"}, + {label: "Sunday", value: "sunday"}, +]; + +export const ManuallyAddEventModal = ({show, close}: { show: boolean, close: () => void }) => { + const {user} = useAuthContext() + const insets = useSafeAreaInsets(); + + const [title, setTitle] = useState(""); + + const [isAllDay, setIsAllDay] = useState(false); + const [startTime, setStartTime] = useState(new Date()); + const [endTime, setEndTime] = useState(new Date()) + + const [startDate, setStartDate] = useState(new Date()); + const [endDate, setEndDate] = useState(new Date()) + + const [repeatInterval, setRepeatInterval] = useState([]); + + const {mutateAsync: createEvent, isLoading, isError} = useCreateEvent() + + const formatDateTime = (date: Date) => { + return date.toLocaleDateString('en-US', { + weekday: 'long', + month: 'short', + day: 'numeric' + }); + }; + + const combineDateAndTime = (date: Date, time: Date): Date => { + const combined = new Date(date); + combined.setHours(time.getHours()); + combined.setMinutes(time.getMinutes()); + combined.setSeconds(0); + combined.setMilliseconds(0); + return combined; + }; + + const handleSave = async () => { + let finalStartDate: Date; + let finalEndDate: Date; + + if (isAllDay) { + finalStartDate = new Date(startDate); + finalStartDate.setHours(0, 0, 0, 0); + + finalEndDate = new Date(startDate); + finalEndDate.setHours(23, 59, 59, 999); + } else { + finalStartDate = combineDateAndTime(startDate, startTime); + finalEndDate = combineDateAndTime(endDate, endTime); + } + + const eventData: Partial = { + title, + startDate: finalStartDate, + endDate: finalEndDate, + repeatDays: repeatInterval.map(x => x.toString()), + allDay: isAllDay + }; + + await createEvent(eventData) + + close(); + }; + + const getRepeatLabel = () => { + const selectedDays = repeatInterval + const allDays = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"]; + const workDays = ["monday", "tuesday", "wednesday", "thursday", "friday"]; + + const isEveryWorkDay = workDays.every(day => selectedDays.includes(day)); + + const isEveryDay = allDays.every(day => selectedDays.includes(day)); + + if (isEveryDay) { + return "Every day"; + } else if (isEveryWorkDay && !selectedDays.includes("saturday") && !selectedDays.includes("sunday")) { + return "Every work day"; + } else { + return selectedDays + .map(item => daysOfWeek.find(day => day.value === item)?.label) + .join(", "); + } + }; + + if (isLoading && !isError) { + return ( + + + + ) + } + + return ( + + + + + Cancel + + Add event + + Save + + + + + + + + + + + + + All-day + + setIsAllDay(value)} + /> + + + + + {!isAllDay && ( + + )} + + + {!isAllDay && ( + + + + + )} + + + + setRepeatInterval(items)} + placeholder="Doest not repeat" + style={{marginLeft: 10, flex: 1}} + mode={Picker.modes.MULTI} + getLabel={getRepeatLabel} + + > + {daysOfWeek.map((option) => ( + + ))} + + + + + + + + + Other + {user?.email} + + + + + + + ); +}; diff --git a/components/pages/main/SignInPage.tsx b/components/pages/main/SignInPage.tsx index 186f89c..4842ee4 100644 --- a/components/pages/main/SignInPage.tsx +++ b/components/pages/main/SignInPage.tsx @@ -1,41 +1,49 @@ -import { View, Text, Button } from "react-native-ui-lib"; -import { TextInput } from "react-native"; +import { View, Text, Button, TextField } from "react-native-ui-lib"; import React, { useState } from "react"; import { useSignIn } from "@/hooks/firebase/useSignIn"; -const SignInPage = (props: { - setRegister: () => any; -}) => { - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); +const SignInPage = (props: { setRegister: () => any }) => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); - const { mutateAsync: signIn } = useSignIn(); + const { mutateAsync: signIn, error, isError } = useSignIn(); - const handleSignIn = async () => { - await signIn({email, password}); - } + const handleSignIn = async () => { + await signIn({ email, password }); + }; - return ( - - - - + ); +}; + +export default DrawerButton; From f08b6ea997370bb24ab49206410337e541299e44 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Thu, 5 Sep 2024 19:27:44 +0200 Subject: [PATCH 24/31] changes to todo --- app/(auth)/_layout.tsx | 77 ++++++++++---- app/(auth)/todos/index.tsx | 7 +- assets/svgs/brain_dump-menu.svg | 6 ++ assets/svgs/calendar-menu.svg | 3 + assets/svgs/chores-menu.svg | 6 ++ assets/svgs/groceries-menu.svg | 6 ++ assets/svgs/reminders-menu.svg | 3 + assets/svgs/todos-menu.svg | 3 + components/pages/todos/AddChore.tsx | 103 ++++++++++++++++++ components/pages/todos/ToDoItem.tsx | 8 +- components/shared/DrawerButton.tsx | 23 +++- package-lock.json | 157 +++++++++++++++++++++++++++- package.json | 2 + yarn.lock | 89 +++++++++++++++- 14 files changed, 458 insertions(+), 35 deletions(-) create mode 100644 assets/svgs/brain_dump-menu.svg create mode 100644 assets/svgs/calendar-menu.svg create mode 100644 assets/svgs/chores-menu.svg create mode 100644 assets/svgs/groceries-menu.svg create mode 100644 assets/svgs/reminders-menu.svg create mode 100644 assets/svgs/todos-menu.svg create mode 100644 components/pages/todos/AddChore.tsx diff --git a/app/(auth)/_layout.tsx b/app/(auth)/_layout.tsx index 3d90044..23ac759 100644 --- a/app/(auth)/_layout.tsx +++ b/app/(auth)/_layout.tsx @@ -6,7 +6,7 @@ import { DrawerItem, DrawerItemList, } from "@react-navigation/drawer"; -import { Button, View, Text } from "react-native-ui-lib"; +import { Button, View, Text, ButtonSize } from "react-native-ui-lib"; import { StyleSheet } from "react-native"; import Feather from "@expo/vector-icons/Feather"; import DrawerButton from "@/components/shared/DrawerButton"; @@ -14,6 +14,7 @@ import { AntDesign, FontAwesome6, MaterialCommunityIcons, + Octicons, } from "@expo/vector-icons"; export default function TabLayout() { @@ -24,15 +25,24 @@ export default function TabLayout() { initialRouteName={"index"} screenOptions={{ headerShown: true, - drawerStyle: { width: "90%", backgroundColor: "#f9f8f7" }, + drawerStyle: { + width: "90%", + backgroundColor: "#f9f8f7", + height: "100%", + }, }} drawerContent={(props) => { return ( - + Welcome to Kali - + } /> - props.navigation.navigate("brain_dump")} - icon={} - /> - } - /> + />*/} } /> - signOut()} /> + props.navigation.navigate("brain_dump")} + icon={} + /> + {/* signOut()} />*/} + + setIsVisible(false)} + containerStyle={{ + backgroundColor: "white", + width: "100%", + alignSelf: "stretch", + padding: 0, + margin: 0, + }} + visible={isVisible} + > + + + + setPoints(value)} + minimumValue={0} + step={10} + maximumValue={100} + /> + + 0 + 50 + 100 + + + + + ); +}; + +export default AddChore; + +const styles = StyleSheet.create({ + divider: { height: 1, backgroundColor: "#e4e4e4", marginVertical: 15 }, + gradient: { + height: "25%", + position: "absolute", + bottom: 0, + width: "100%", + }, + buttonContainer: { + position: "absolute", + bottom: 25, + width: "100%", + }, + button: { + backgroundColor: "rgb(253, 23, 117)", + paddingVertical: 20, + }, +}); diff --git a/components/pages/todos/ToDoItem.tsx b/components/pages/todos/ToDoItem.tsx index ae9b0c3..f37edc4 100644 --- a/components/pages/todos/ToDoItem.tsx +++ b/components/pages/todos/ToDoItem.tsx @@ -5,13 +5,13 @@ import { Ionicons } from "@expo/vector-icons"; const ToDoItem = (props: { item: IToDo }) => { return ( - - - {props.item.title} + + + {props.item.title} - + {props.item.points && props.item.points > 0 ? ( diff --git a/components/shared/DrawerButton.tsx b/components/shared/DrawerButton.tsx index 6535ebe..b83f6e8 100644 --- a/components/shared/DrawerButton.tsx +++ b/components/shared/DrawerButton.tsx @@ -12,7 +12,7 @@ const DrawerButton = (props: IDrawerButtonProps) => { + style={{ + aspectRatio: 1, + borderRadius: 15, + marginBottom: 12, + flexDirection: "column", + justifyContent: "space-between", + paddingVertical: 15, + + // Shadow for iOS + shadowColor: "#000", + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.3, + shadowRadius: 10, // This will create a blurry shadow + + // Shadow for Android + elevation: 1, + }} + > ); }; diff --git a/package-lock.json b/package-lock.json index 64b6edf..87d5e43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,9 +39,11 @@ "react-native-big-calendar": "^4.14.0", "react-native-calendars": "^1.1306.0", "react-native-gesture-handler": "~2.16.1", + "react-native-linear-gradient": "^2.8.3", "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.5", "react-native-screens": "3.31.1", + "react-native-svg": "^15.6.0", "react-native-ui-lib": "^7.27.0", "react-native-web": "~0.19.10", "react-query": "^3.39.3" @@ -9414,6 +9416,12 @@ "node": ">= 0.8" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, "node_modules/bower": { "version": "1.8.14", "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.14.tgz", @@ -10447,6 +10455,56 @@ "hyphenate-style-name": "^1.0.3" } }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -10847,6 +10905,32 @@ "node": ">=8" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, "node_modules/domexception": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", @@ -10861,6 +10945,35 @@ "node": ">=12" } }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -10969,7 +11082,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -17342,6 +17454,12 @@ "integrity": "sha512-c2YOUbp33+6thdCUi34xIyOU/a7bvGKj/3DB1iaPMTuPHf/Q2d5s4sn1FaCOO43XkXggnb08y5W2PU8UNYNLKQ==", "license": "MIT" }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -18354,6 +18472,18 @@ "node": ">=4" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", @@ -19485,6 +19615,16 @@ "react": "^16.6.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-native-linear-gradient": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz", + "integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-reanimated": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.10.1.tgz", @@ -19548,6 +19688,21 @@ "react-native": "*" } }, + "node_modules/react-native-svg": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.6.0.tgz", + "integrity": "sha512-TUtR+h+yi1ODsd8FHdom1TpjfWOmnaK5pri5rnSBXnMqpzq8o2zZfonHTjPX+nS3wb/Pu2XsoARgYaHNjVWXhQ==", + "license": "MIT", + "dependencies": { + "css-select": "^5.1.0", + "css-tree": "^1.1.3", + "warn-once": "0.1.1" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-swipe-gestures": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz", diff --git a/package.json b/package.json index 4d21ab1..7686b34 100644 --- a/package.json +++ b/package.json @@ -46,9 +46,11 @@ "react-native-big-calendar": "^4.14.0", "react-native-calendars": "^1.1306.0", "react-native-gesture-handler": "~2.16.1", + "react-native-linear-gradient": "^2.8.3", "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.5", "react-native-screens": "3.31.1", + "react-native-svg": "^15.6.0", "react-native-ui-lib": "^7.27.0", "react-native-web": "~0.19.10", "react-query": "^3.39.3" diff --git a/yarn.lock b/yarn.lock index 3f91f3c..86b8ffd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3904,6 +3904,11 @@ body-parser@1.20.2: type-is "~1.6.18" unpipe "1.0.0" +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + bower-auto-release@^1.1.358: version "1.1.358" resolved "https://registry.npmjs.org/bower-auto-release/-/bower-auto-release-1.1.358.tgz" @@ -4565,6 +4570,30 @@ css-in-js-utils@^3.1.0: dependencies: hyphenate-style-name "^1.0.3" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + cssom@^0.5.0: version "0.5.0" resolved "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz" @@ -4823,6 +4852,20 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + domexception@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz" @@ -4830,6 +4873,22 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dotenv-expand@~11.0.6: version "11.0.6" resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.6.tgz" @@ -4901,7 +4960,7 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -entities@^4.4.0: +entities@^4.2.0, entities@^4.4.0: version "4.5.0" resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== @@ -7633,6 +7692,11 @@ md5hex@^1.0.0: resolved "https://registry.npmjs.org/md5hex/-/md5hex-1.0.0.tgz" integrity sha512-c2YOUbp33+6thdCUi34xIyOU/a7bvGKj/3DB1iaPMTuPHf/Q2d5s4sn1FaCOO43XkXggnb08y5W2PU8UNYNLKQ== +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" @@ -8170,6 +8234,13 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + nullthrows@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz" @@ -8894,6 +8965,11 @@ react-native-helmet-async@2.0.4: react-fast-compare "^3.2.2" shallowequal "^1.1.0" +react-native-linear-gradient@^2.8.3: + version "2.8.3" + resolved "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz" + integrity sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA== + react-native-reanimated@*, "react-native-reanimated@>= 1.0.0", react-native-reanimated@>=2.0.0, react-native-reanimated@~3.10.1: version "3.10.1" resolved "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.10.1.tgz" @@ -8931,6 +9007,15 @@ react-native-screens@*, "react-native-screens@>= 3.0.0", react-native-screens@3. react-freeze "^1.0.0" warn-once "^0.1.0" +react-native-svg@^15.6.0: + version "15.6.0" + resolved "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.6.0.tgz" + integrity sha512-TUtR+h+yi1ODsd8FHdom1TpjfWOmnaK5pri5rnSBXnMqpzq8o2zZfonHTjPX+nS3wb/Pu2XsoARgYaHNjVWXhQ== + dependencies: + css-select "^5.1.0" + css-tree "^1.1.3" + warn-once "0.1.1" + react-native-swipe-gestures@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz" @@ -10591,7 +10676,7 @@ walker@^1.0.7, walker@^1.0.8: dependencies: makeerror "1.0.12" -warn-once@^0.1.0: +warn-once@^0.1.0, warn-once@0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz" integrity sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q== From 8d85cbdaadcc0bda41c19337e2b34232d792a4d0 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Thu, 5 Sep 2024 22:09:28 +0200 Subject: [PATCH 25/31] edit todos --- components/pages/todos/AddChore.tsx | 125 ++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 15 deletions(-) diff --git a/components/pages/todos/AddChore.tsx b/components/pages/todos/AddChore.tsx index d0e321e..b3b931e 100644 --- a/components/pages/todos/AddChore.tsx +++ b/components/pages/todos/AddChore.tsx @@ -9,18 +9,28 @@ import { TextField, Dialog, Slider, + NumberInput, + NumberInputData, + DateTimePicker, } from "react-native-ui-lib"; -import { AntDesign } from "@expo/vector-icons"; +import { AntDesign, Feather, Ionicons } from "@expo/vector-icons"; import LinearGradient from "react-native-linear-gradient"; import { PanningDirectionsEnum } from "react-native-ui-lib/src/components/panningViews/panningProvider"; const AddChore = () => { const [isVisible, setIsVisible] = useState(false); const [points, setPoints] = useState(10); + const [choreDate, setChoreDate] = useState(new Date()); - useEffect(() => { - console.log(points); - }, [points]); + const handleChange = (text: string) => { + const numericValue = parseInt(text, 10); + + if (!isNaN(numericValue) && numericValue >= 0 && numericValue <= 100) { + setPoints(numericValue); + } else if (text === "") { + setPoints(0); + } + }; return ( { panDirection={PanningDirectionsEnum.DOWN} onDismiss={() => setIsVisible(false)} containerStyle={{ + borderRadius: 10, backgroundColor: "white", width: "100%", alignSelf: "stretch", @@ -60,20 +71,104 @@ const AddChore = () => { placeholderTextColor="#2d2d30" text60R marginT-15 + marginL-30 /> - - setPoints(value)} - minimumValue={0} - step={10} - maximumValue={100} + + + + { + setChoreDate(date); + }} + /> + + + + + + + + + + + Assignees + + + + + ); +}; + +export default ProgressCard; diff --git a/components/pages/todos/ToDoItem.tsx b/components/pages/todos/ToDoItem.tsx index f6d37c9..9207cc0 100644 --- a/components/pages/todos/ToDoItem.tsx +++ b/components/pages/todos/ToDoItem.tsx @@ -8,15 +8,25 @@ const ToDoItem = (props: { item: IToDo }) => { return ( - {props.item.title} + + {props.item.title} + { @@ -29,7 +39,9 @@ const ToDoItem = (props: { item: IToDo }) => { centerV height={2} width={"100%"} - backgroundColor="#e7e7e7" + style={{ + backgroundColor: props.item.done ? '#b8b8b8' : "#e7e7e7", + }} centerH /> diff --git a/components/pages/todos/ToDosList.tsx b/components/pages/todos/ToDosList.tsx index 3f5e5f0..1571c3f 100644 --- a/components/pages/todos/ToDosList.tsx +++ b/components/pages/todos/ToDosList.tsx @@ -2,50 +2,77 @@ import { View, Text } from "react-native-ui-lib"; import React from "react"; import { IToDo, useToDosContext } from "@/contexts/ToDosContext"; import ToDoItem from "./ToDoItem"; -import { format, isToday, isTomorrow } from "date-fns"; -import { ScrollView } from "react-native-gesture-handler"; +import { format, isToday, isTomorrow } from "date-fns"; const groupToDosByDate = (toDos: IToDo[]) => { - return toDos.reduce((groups, toDo) => { - const dateKey = isToday(toDo.date) - ? "Today • " + format(toDo.date, "EEE MMM dd") - : isTomorrow(toDo.date) - ? "Tomorrow • " + format(toDo.date, "EEE MMM dd") - : format(toDo.date, "EEE MMM dd"); - - if (!groups[dateKey]) { - groups[dateKey] = []; - } - - groups[dateKey].push(toDo); - return groups; - }, {} as { [key: string]: IToDo[] }); - }; + return toDos.reduce((groups, toDo) => { + let dateKey; + + if (toDo.date === null) { + dateKey = "No Date"; + } else if (isToday(toDo.date)) { + dateKey = "Today • " + format(toDo.date, "EEE MMM dd"); + } else if (isTomorrow(toDo.date)) { + dateKey = "Tomorrow • " + format(toDo.date, "EEE MMM dd"); + } else { + dateKey = format(toDo.date, "EEE MMM dd"); + } + + if (!groups[dateKey]) { + groups[dateKey] = []; + } + + groups[dateKey].push(toDo); + return groups; + }, {} as { [key: string]: IToDo[] }); +}; const ToDosList = () => { const { toDos } = useToDosContext(); const groupedToDos = groupToDosByDate(toDos); + const noDateToDos = groupedToDos["No Date"] || []; + const datedToDos = Object.keys(groupedToDos).filter((key) => key !== "No Date"); + return ( - {Object.keys(groupedToDos).map((dateKey) => ( - - - {dateKey} - - {groupedToDos[dateKey].map((item) => ( - - ))} + + {noDateToDos.length > 0 && ( + + {noDateToDos + .sort((a, b) => Number(a.done) - Number(b.done)) + .map((item) => ( + + ))} - ))} + )} + + {datedToDos.map((dateKey) => { + const sortedToDos = [ + ...groupedToDos[dateKey].filter((toDo) => !toDo.done), + ...groupedToDos[dateKey].filter((toDo) => toDo.done), + ]; + + return ( + + + {dateKey} + + {sortedToDos.map((item) => ( + + ))} + + ); + })} ); }; export default ToDosList; - -/*const groupToDosByDate = (toDos: IToDo[]) => { - return toDos.reduce((groups, toDo) => { - const dateKey - }) -}*/ diff --git a/contexts/GroceryContext.tsx b/contexts/GroceryContext.tsx index d658cba..b68340c 100644 --- a/contexts/GroceryContext.tsx +++ b/contexts/GroceryContext.tsx @@ -56,6 +56,7 @@ interface IGroceryContext { updateGroceryItem: (id: number, changes: Partial) => void; isAddingGrocery: boolean; setIsAddingGrocery: (value: boolean) => void; + addGrocery: (grocery: IGrocery) => void; } const GroceryContext = createContext(undefined); @@ -103,6 +104,17 @@ export const GroceryProvider: React.FC<{ children: React.ReactNode }> = ({ }, ]); + const addGrocery = (grocery: IGrocery) => { + setGroceries((prevGroceries) => [ + ...prevGroceries, + { + ...grocery, + id: prevGroceries.length ? prevGroceries[prevGroceries.length - 1].id + 1 : 0, + }, + ]); + }; + + const updateGroceryItem = (id: number, changes: Partial) => { setGroceries((prevGroceries) => prevGroceries.map((grocery) => @@ -113,7 +125,7 @@ export const GroceryProvider: React.FC<{ children: React.ReactNode }> = ({ return ( {children} diff --git a/contexts/ToDosContext.tsx b/contexts/ToDosContext.tsx index 0da2ac5..aeee412 100644 --- a/contexts/ToDosContext.tsx +++ b/contexts/ToDosContext.tsx @@ -1,12 +1,22 @@ import { createContext, FC, ReactNode, useContext, useState } from "react"; + export interface IToDo { id: number; title: string; done: boolean; - date: Date; + date: Date | null; points?: number; rotate: boolean; + repeatType: string; } + +export const repeatOptions = [ + { label: "None", value: "None" }, + { label: "Every week", value: "Every week" }, + { label: "Once a month", value: "Once a month" }, + { label: "Once a year", value: "Once a year" }, +]; + interface IToDosContext { toDos: IToDo[]; updateToDo: (id: number, changes: Partial) => void; @@ -25,6 +35,7 @@ export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ done: false, date: new Date(), rotate: true, + repeatType: "Every week" }, { id: 1, @@ -32,6 +43,7 @@ export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ done: false, date: new Date(), rotate: false, + repeatType: "Every week" }, { id: 2, @@ -39,6 +51,7 @@ export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ done: false, date: new Date(), rotate: true, + repeatType: "Every week" }, { id: 3, @@ -47,6 +60,7 @@ export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ date: new Date(Date.now() + 86400000), points: 40, rotate: false, + repeatType: "Every week" }, { id: 4, @@ -54,6 +68,7 @@ export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ done: false, date: new Date(Date.now() + 86400000), rotate: false, + repeatType: "Once a Month" }, { id: 5, @@ -61,6 +76,7 @@ export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ done: false, date: new Date(Date.now() + 2 * 86400000), rotate: true, + repeatType: "Once a Month" }, { id: 6, @@ -68,6 +84,23 @@ export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ done: false, date: new Date(Date.now() + 3 * 86400000), rotate: false, + repeatType: "Once a year" + }, + { + id: 7, + title: "Buy Nautica Voyage", + done: false, + date: null, + rotate: false, + repeatType: "None" + }, + { + id: 8, + title: "Sell Dan's Xbox", + done: false, + date: null, + rotate: false, + repeatType: "None" }, ]); From ac7e8392730bd2cfbcd9484fda18d641748b99b5 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:41:23 +0200 Subject: [PATCH 28/31] brain_dump and settings --- app/(auth)/_layout.tsx | 10 +- app/(auth)/brain_dump/index.tsx | 17 ++- app/(auth)/settings/_layout.tsx | 5 + app/(auth)/settings/index.tsx | 6 + components/pages/brain_dump/BrainDumpPage.tsx | 54 ++++++++ components/pages/brain_dump/DumpItem.tsx | 30 +++++ components/pages/brain_dump/DumpList.tsx | 27 ++++ components/pages/brain_dump/MoveBrainDump.tsx | 124 ++++++++++++++++++ components/pages/settings/SettingsPage.tsx | 51 +++++++ contexts/DumpContext.tsx | 100 ++++++++++++++ 10 files changed, 418 insertions(+), 6 deletions(-) create mode 100644 app/(auth)/settings/_layout.tsx create mode 100644 app/(auth)/settings/index.tsx create mode 100644 components/pages/brain_dump/BrainDumpPage.tsx create mode 100644 components/pages/brain_dump/DumpItem.tsx create mode 100644 components/pages/brain_dump/DumpList.tsx create mode 100644 components/pages/brain_dump/MoveBrainDump.tsx create mode 100644 components/pages/settings/SettingsPage.tsx create mode 100644 contexts/DumpContext.tsx diff --git a/app/(auth)/_layout.tsx b/app/(auth)/_layout.tsx index 23ac759..867d5fd 100644 --- a/app/(auth)/_layout.tsx +++ b/app/(auth)/_layout.tsx @@ -105,10 +105,11 @@ export default function TabLayout() {