From 80a553695b76f087c6f69fb20edff44db6b36683 Mon Sep 17 00:00:00 2001 From: ivic00 <102467664+ivic00@users.noreply.github.com> Date: Mon, 2 Sep 2024 22:47:15 +0200 Subject: [PATCH] add To Dos --- app/(auth)/todos/index.tsx | 23 ++++++++--- components/pages/todos/ToDoItem.tsx | 36 +++++++++++++++++ components/pages/todos/ToDosList.tsx | 51 ++++++++++++++++++++++++ components/shared/HeaderTemplate.tsx | 18 +++++++++ contexts/ToDosContext.tsx | 59 ++++++++++++++++++++++++++++ package-lock.json | 33 ++++++++++------ package.json | 1 + yarn.lock | 5 +++ 8 files changed, 210 insertions(+), 16 deletions(-) create mode 100644 components/pages/todos/ToDoItem.tsx create mode 100644 components/pages/todos/ToDosList.tsx create mode 100644 components/shared/HeaderTemplate.tsx create mode 100644 contexts/ToDosContext.tsx diff --git a/app/(auth)/todos/index.tsx b/app/(auth)/todos/index.tsx index 7d92969..6e92221 100644 --- a/app/(auth)/todos/index.tsx +++ b/app/(auth)/todos/index.tsx @@ -1,7 +1,20 @@ -import {View} from "react-native-ui-lib"; +import ToDoItem from "@/components/pages/todos/ToDoItem"; +import ToDosList from "@/components/pages/todos/ToDosList"; +import HeaderTemplate from "@/components/shared/HeaderTemplate"; +import { useAuthContext } from "@/contexts/AuthContext"; +import { ToDosContextProvider, useToDosContext } from "@/contexts/ToDosContext"; +import { ScrollView } from "react-native-gesture-handler"; +import { View } from "react-native-ui-lib"; export default function Screen() { - return ( - - ) -} \ No newline at end of file + return ( + + + + + + + + + ); +} diff --git a/components/pages/todos/ToDoItem.tsx b/components/pages/todos/ToDoItem.tsx new file mode 100644 index 0000000..ae9b0c3 --- /dev/null +++ b/components/pages/todos/ToDoItem.tsx @@ -0,0 +1,36 @@ +import { View, Text, Checkbox } from "react-native-ui-lib"; +import React from "react"; +import { IToDo } from "@/contexts/ToDosContext"; +import { Ionicons } from "@expo/vector-icons"; + +const ToDoItem = (props: { item: IToDo }) => { + return ( + + + {props.item.title} + + + + + + + {props.item.points && props.item.points > 0 ? ( + + + {props.item.points} points + + ) : ( + + )} + + + + ); +}; + +export default ToDoItem; diff --git a/components/pages/todos/ToDosList.tsx b/components/pages/todos/ToDosList.tsx new file mode 100644 index 0000000..6d71473 --- /dev/null +++ b/components/pages/todos/ToDosList.tsx @@ -0,0 +1,51 @@ +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"; + +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[] }); + }; + +const ToDosList = () => { + const { toDos } = useToDosContext(); + const groupedToDos = groupToDosByDate(toDos); + + return ( + + {Object.keys(groupedToDos).map((dateKey) => ( + + + {dateKey} + + {groupedToDos[dateKey].map((item) => ( + + ))} + + ))} + + ); +}; + +export default ToDosList; + +/*const groupToDosByDate = (toDos: IToDo[]) => { + return toDos.reduce((groups, toDo) => { + const dateKey + }) +}*/ diff --git a/components/shared/HeaderTemplate.tsx b/components/shared/HeaderTemplate.tsx new file mode 100644 index 0000000..bf24e60 --- /dev/null +++ b/components/shared/HeaderTemplate.tsx @@ -0,0 +1,18 @@ +import { View, Text } from "react-native-ui-lib"; +import React from "react"; +import { useAuthContext } from "@/contexts/AuthContext"; + +const HeaderTemplate = (props: { message: string }) => { + const { user, profileData } = useAuthContext(); + return ( + + + + Welcome, {user?.email}! + {props.message} + + + ); +}; + +export default HeaderTemplate; diff --git a/contexts/ToDosContext.tsx b/contexts/ToDosContext.tsx new file mode 100644 index 0000000..b4d32a5 --- /dev/null +++ b/contexts/ToDosContext.tsx @@ -0,0 +1,59 @@ +import { createContext, FC, ReactNode, useContext, useState } from "react"; +export interface IToDo { + id: number; + title: string; + done: boolean; + date: Date; + points?: number; +} +interface IToDosContext { + toDos: IToDo[]; + updateToDo: (id: number, changes: Partial) => void; +} + +const ToDosContext = createContext(undefined!); + +export const ToDosContextProvider: FC<{ children: ReactNode }> = ({ + children, +}) => { + const [toDos, setToDos] = useState([ + { id: 0, title: "Pay: Credit card", done: false, date: new Date() }, + { id: 1, title: "Monthly Log story", done: false, date: new Date() }, + { id: 2, title: "Write: Arcade Highlights", done: false, date: new Date() }, + { + id: 3, + title: "Dressup: Cat", + done: false, + date: new Date(Date.now() + 86400000), + points: 40, + }, + { + id: 4, + title: "Trim: Nails", + done: false, + date: new Date(Date.now() + 86400000), + }, + { + id: 5, + title: "Monthly Log", + done: false, + date: new Date(Date.now() + 2 * 86400000), + }, + { + id: 6, + title: "Do it", + done: false, + date: new Date(Date.now() + 3 * 86400000), + }, + ]); + + const updateToDo = (id: number, changes: Partial) => {}; + + return ( + + {children} + + ); +}; + +export const useToDosContext = () => useContext(ToDosContext)!; diff --git a/package-lock.json b/package-lock.json index 4b433f4..64b6edf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@react-native-firebase/functions": "^20.4.0", "@react-navigation/drawer": "^6.7.2", "@react-navigation/native": "^6.0.2", + "date-fns": "^3.6.0", "expo": "~51.0.24", "expo-build-properties": "~0.12.4", "expo-constants": "~16.0.2", @@ -10562,19 +10563,13 @@ } }, "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" - }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" } }, "node_modules/dayjs": { @@ -19598,6 +19593,22 @@ "color-string": "^1.6.0" } }, + "node_modules/react-native-ui-lib/node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/react-native-ui-lib/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", diff --git a/package.json b/package.json index 7d15aba..4d21ab1 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@react-native-firebase/functions": "^20.4.0", "@react-navigation/drawer": "^6.7.2", "@react-navigation/native": "^6.0.2", + "date-fns": "^3.6.0", "expo": "~51.0.24", "expo-build-properties": "~0.12.4", "expo-constants": "~16.0.2", diff --git a/yarn.lock b/yarn.lock index 0333403..3f91f3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4640,6 +4640,11 @@ date-fns@^2.29.3: dependencies: "@babel/runtime" "^7.21.0" +date-fns@^3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz" + integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== + dayjs@^1.11.10, dayjs@^1.8.15: version "1.11.13" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz"