diff --git a/app/(auth)/grocery/index.tsx b/app/(auth)/grocery/index.tsx
index 5c9d1e4..052a53e 100644
--- a/app/(auth)/grocery/index.tsx
+++ b/app/(auth)/grocery/index.tsx
@@ -1,6 +1,3 @@
-import { Text, View } from "react-native-ui-lib";
-import GroceryList from "@/components/pages/grocery/GroceryList";
-import AddGroceryItem from "@/components/pages/grocery/AddGroceryItem";
import { GroceryProvider } from "@/contexts/GroceryContext";
import React from "react";
import GroceryWrapper from "@/components/pages/grocery/GroceryWrapper";
diff --git a/components/pages/calendar/AddEventDialog.tsx b/components/pages/calendar/AddEventDialog.tsx
index 02be196..8f0b334 100644
--- a/components/pages/calendar/AddEventDialog.tsx
+++ b/components/pages/calendar/AddEventDialog.tsx
@@ -51,7 +51,7 @@ export const AddEventDialog = () => {
}}
onPress={handleOpenManualInputModal}
>
- Manually Input
+ Create New
+
+
diff --git a/components/pages/calendar/ManuallyAddEventModal.tsx b/components/pages/calendar/ManuallyAddEventModal.tsx
index 23970ed..8d26734 100644
--- a/components/pages/calendar/ManuallyAddEventModal.tsx
+++ b/components/pages/calendar/ManuallyAddEventModal.tsx
@@ -1,260 +1,320 @@
import {
- Avatar,
- Colors,
- DateTimePicker,
- LoaderScreen,
- Modal,
- Picker,
- Switch,
- Text,
- TextField,
- View
+ 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";
+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"},
+ { 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();
+export const ManuallyAddEventModal = ({
+ show,
+ close,
+}: {
+ show: boolean;
+ close: () => void;
+}) => {
+ const { user } = useAuthContext();
+ const insets = useSafeAreaInsets();
- const [title, setTitle] = useState("");
+ const [title, setTitle] = useState("");
- const [isAllDay, setIsAllDay] = useState(false);
- const [startTime, setStartTime] = useState(new Date());
- const [endTime, setEndTime] = useState(new Date())
+ 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 [startDate, setStartDate] = useState(new Date());
+ const [endDate, setEndDate] = useState(new Date());
- const [repeatInterval, setRepeatInterval] = useState([]);
+ const [repeatInterval, setRepeatInterval] = useState([]);
- const {mutateAsync: createEvent, isLoading, isError} = useCreateEvent()
+ const { mutateAsync: createEvent, isLoading, isError } = useCreateEvent();
- const formatDateTime = (date: Date) => {
- return date.toLocaleDateString('en-US', {
- weekday: 'long',
- month: 'short',
- day: 'numeric'
- });
- };
+ 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 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;
+ const handleSave = async () => {
+ let finalStartDate: Date;
+ let finalEndDate: Date;
- if (isAllDay) {
- finalStartDate = new Date(startDate);
- finalStartDate.setHours(0, 0, 0, 0);
+ 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 (
-
-
-
- )
+ 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 (
-
-
-
-
- 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}
-
-
-
-
-
-
+
+
+
);
+ }
+
+ 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/grocery/EditGroceryItem.tsx b/components/pages/grocery/EditGroceryItem.tsx
index 6e4bf68..2d8d6d1 100644
--- a/components/pages/grocery/EditGroceryItem.tsx
+++ b/components/pages/grocery/EditGroceryItem.tsx
@@ -1,28 +1,60 @@
-import { View, Text } from 'react-native'
-import React from 'react'
-import { TextField } from 'react-native-ui-lib'
-import CategoryDropdown from './CategoryDropdown'
-import { GroceryCategory } from '@/contexts/GroceryContext'
+import { View, Text } from "react-native";
+import React, { useEffect, useState } from "react";
+import { TextField } from "react-native-ui-lib";
+import {
+ GroceryCategory,
+ IGrocery,
+ useGroceryContext,
+} from "@/contexts/GroceryContext";
+import { TouchableWithoutFeedback } from "react-native-gesture-handler";
-const EditGroceryItem = (props: {title: string, setTitle: (value: string) => void, setCategory: (category: GroceryCategory) => void}) => {
- return (
-
- props.setTitle(value)}
- maxLength={25}
- />
-
-
- )
+interface IEditGrocery {
+ id?: number;
+ title: string;
+ setTitle: (value: string) => void;
+ setCategory?: (category: GroceryCategory) => void;
+ category: GroceryCategory;
+ setSubmit?: (value: boolean) => void;
+ updateCategory?: (id: number, changes: Partial) => void;
+ closeEdit?: (value: boolean) => void;
}
-export default EditGroceryItem
\ No newline at end of file
+const EditGroceryItem = ({ editGrocery }: { editGrocery: IEditGrocery }) => {
+ const { fuzzyMatchGroceryCategory } = useGroceryContext();
+
+ useEffect(() => {
+ if (editGrocery.setCategory)
+ editGrocery.setCategory(fuzzyMatchGroceryCategory(editGrocery.title));
+ }, [editGrocery.title]);
+
+ return (
+
+ {
+ editGrocery.setTitle(value);
+ }}
+ onSubmitEditing={() => {
+ if (editGrocery.setSubmit) editGrocery.setSubmit(true);
+ if (editGrocery.closeEdit) editGrocery.closeEdit(false);
+ if (editGrocery.updateCategory && editGrocery.id)
+ editGrocery.updateCategory(editGrocery.id, {
+ category: fuzzyMatchGroceryCategory(editGrocery.title), title: editGrocery.title
+ });
+ }}
+ maxLength={25}
+ />
+ {editGrocery.category}
+
+ );
+};
+
+export default EditGroceryItem;
diff --git a/components/pages/grocery/GroceryItem.tsx b/components/pages/grocery/GroceryItem.tsx
index ef12135..05e30c2 100644
--- a/components/pages/grocery/GroceryItem.tsx
+++ b/components/pages/grocery/GroceryItem.tsx
@@ -17,6 +17,7 @@ import {
import EditGroceryFrequency from "./EditGroceryFrequency";
import { TextInput } from "react-native";
import EditGroceryItem from "./EditGroceryItem";
+import { TouchableWithoutFeedback } from "react-native-gesture-handler";
const GroceryItem = ({
item,
@@ -31,6 +32,7 @@ const GroceryItem = ({
const [openFreqEdit, setOpenFreqEdit] = useState(false);
const [isEditingTitle, setIsEditingTitle] = useState(false);
const [newTitle, setNewTitle] = useState("");
+ const [category, setCategory] = useState(GroceryCategory.None);
const handleTitleChange = (newTitle: string) => {
updateGroceryItem(item.id, { title: newTitle });
@@ -46,6 +48,7 @@ const GroceryItem = ({
return (
- {/*
- }
- />*/}
{!isEditingTitle ? (
setIsEditingTitle(true)}>
{item.title}
- { /*
- {
- setIsEditingTitle(false);
- console.log(groceries);
- }}
- autoFocus
- style={{
- fontSize: 16,
- padding: 0,
- margin: 0,
- fontWeight: "bold",
- }}
- />
- */}
) : (
-
+
)}
diff --git a/components/pages/grocery/GroceryList.tsx b/components/pages/grocery/GroceryList.tsx
index e8ba6c9..25106e7 100644
--- a/components/pages/grocery/GroceryList.tsx
+++ b/components/pages/grocery/GroceryList.tsx
@@ -31,6 +31,7 @@ const GroceryList = () => {
GroceryCategory.Bakery
);
const [title, setTitle] = useState("");
+ const [submit, setSubmitted] = useState(false);
// Group approved groceries by category
const approvedGroceriesByCategory = approvedGroceries.reduce(
@@ -46,19 +47,27 @@ const GroceryList = () => {
);
useEffect(() => {
- if (title?.length > 2 && title?.length <= 25) {
- addGrocery({
- id: 0,
- title: title,
- category: category,
- approved: false,
- recurring: false,
- frequency: GroceryFrequency.Never,
- bought: false,
- });
-
- setIsAddingGrocery(false);
+ if(submit){
+ if (title?.length > 2 && title?.length <= 25) {
+ addGrocery({
+ id: 0,
+ title: title,
+ category: category,
+ approved: false,
+ recurring: false,
+ frequency: GroceryFrequency.Never,
+ bought: false,
+ });
+
+ setIsAddingGrocery(false);
+ setSubmitted(false);
+ setTitle("");
+ }
}
+ }, [submit]);
+
+ useEffect(() => {
+ /**/
}, [category]);
useEffect(() => {
@@ -67,7 +76,7 @@ const GroceryList = () => {
}, [groceries]);
return (
-
+
{
{isAddingGrocery && (
-
+
)}
{/* Render Approved Groceries Grouped by Category */}
diff --git a/components/pages/settings/UserSettings.tsx b/components/pages/settings/UserSettings.tsx
index 5e2f89f..809be4f 100644
--- a/components/pages/settings/UserSettings.tsx
+++ b/components/pages/settings/UserSettings.tsx
@@ -1,7 +1,12 @@
import { View, Text, TouchableOpacity } from "react-native-ui-lib";
import React, { useState } from "react";
import { Ionicons } from "@expo/vector-icons";
-import { ScrollView, StyleSheet } from "react-native";
+import {
+ KeyboardAvoidingView,
+ Platform,
+ ScrollView,
+ StyleSheet,
+} from "react-native";
import MyProfile from "./user_settings_views/MyProfile";
import MyGroup from "./user_settings_views/MyGroup";
import { useAuthContext } from "@/contexts/AuthContext";
@@ -9,51 +14,57 @@ import { useAuthContext } from "@/contexts/AuthContext";
const UserSettings = (props: { setSelectedPage: (page: number) => void }) => {
const [selectedView, setSelectedView] = useState(true);
return (
-
-
- props.setSelectedPage(0)}>
-
-
-
- Return to main settings
+
+
+ props.setSelectedPage(0)}>
+
+
+
+ Return to main settings
+
+
+
+
+
+ User Management
+
+ setSelectedView(true)}
+ centerV
+ centerH
+ style={
+ selectedView == true ? styles.btnSelected : styles.btnNot
+ }
+ >
+
+
+ My Profile
+
+
+
+ setSelectedView(false)}
+ centerV
+ centerH
+ style={
+ selectedView == false ? styles.btnSelected : styles.btnNot
+ }
+ >
+
+
+ My Group
+
+
+
+
+ {selectedView && }
+ {!selectedView && }
-
-
-
- User Management
-
-
- setSelectedView(true)}
- centerV
- centerH
- style={selectedView == true ? styles.btnSelected : styles.btnNot}
- >
-
-
- My Profile
-
-
-
- setSelectedView(false)}
- centerV
- centerH
- style={selectedView == false ? styles.btnSelected : styles.btnNot}
- >
-
-
- My Group
-
-
-
-
- {selectedView && }
- {!selectedView && }
-
);
};
diff --git a/components/pages/todos/ProgressCard.tsx b/components/pages/todos/ProgressCard.tsx
index 7bbf4bb..116dfd4 100644
--- a/components/pages/todos/ProgressCard.tsx
+++ b/components/pages/todos/ProgressCard.tsx
@@ -2,8 +2,10 @@ import { View, Text, Button } from "react-native-ui-lib";
import React from "react";
import { Fontisto } from "@expo/vector-icons";
import { ProgressBar } from "react-native-ui-lib/src/components/progressBar";
+import { useToDosContext } from "@/contexts/ToDosContext";
const ProgressCard = () => {
+ const { maxPoints } = useToDosContext();
return (
{
/>
0
- 1000
+ {maxPoints}
-