fixed settings paging, calendar style,

This commit is contained in:
ivic00
2024-10-29 20:15:20 +01:00
parent 8ba6f7aecf
commit 74d82e2029
9 changed files with 1934 additions and 1729 deletions

View File

@ -23,9 +23,16 @@ import NavToDosIcon from "@/assets/svgs/NavToDosIcon";
import NavBrainDumpIcon from "@/assets/svgs/NavBrainDumpIcon"; import NavBrainDumpIcon from "@/assets/svgs/NavBrainDumpIcon";
import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon"; import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon";
import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon"; import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon";
import { useAtom } from "jotai";
import {
settingsPageIndex,
userSettingsView,
} from "@/components/pages/calendar/atoms";
export default function TabLayout() { export default function TabLayout() {
const { mutateAsync: signOut } = useSignOut(); const { mutateAsync: signOut } = useSignOut();
const [pageIndex, setPageIndex] = useAtom(settingsPageIndex);
const [userView, setUserView] = useAtom(userSettingsView);
return ( return (
<Drawer <Drawer
@ -66,14 +73,22 @@ export default function TabLayout() {
title={"Calendar"} title={"Calendar"}
color="rgb(7, 184, 199)" color="rgb(7, 184, 199)"
bgColor={"rgb(231, 248, 250)"} bgColor={"rgb(231, 248, 250)"}
pressFunc={() => props.navigation.navigate("calendar")} pressFunc={() => {
props.navigation.navigate("calendar");
setPageIndex(0);
setUserView(true);
}}
icon={<NavCalendarIcon />} icon={<NavCalendarIcon />}
/> />
<DrawerButton <DrawerButton
color="#50be0c" color="#50be0c"
title={"Groceries"} title={"Groceries"}
bgColor={"#eef9e7"} bgColor={"#eef9e7"}
pressFunc={() => props.navigation.navigate("grocery")} pressFunc={() => {
props.navigation.navigate("grocery");
setPageIndex(0);
setUserView(true);
}}
icon={<NavGroceryIcon />} icon={<NavGroceryIcon />}
/> />
</View> </View>
@ -95,21 +110,33 @@ export default function TabLayout() {
color="#8005eb" color="#8005eb"
title={"To Do's"} title={"To Do's"}
bgColor={"#f3e6fd"} bgColor={"#f3e6fd"}
pressFunc={() => props.navigation.navigate("todos")} pressFunc={() => {
props.navigation.navigate("todos");
setPageIndex(0);
setUserView(true);
}}
icon={<NavToDosIcon />} icon={<NavToDosIcon />}
/> />
<DrawerButton <DrawerButton
color="#e0ca03" color="#e0ca03"
title={"Brain Dump"} title={"Brain Dump"}
bgColor={"#fffacb"} bgColor={"#fffacb"}
pressFunc={() => props.navigation.navigate("brain_dump")} pressFunc={() => {
props.navigation.navigate("brain_dump");
setPageIndex(0);
setUserView(true);
}}
icon={<NavBrainDumpIcon />} icon={<NavBrainDumpIcon />}
/> />
{/*<DrawerItem label="Logout" onPress={() => signOut()} />*/} {/*<DrawerItem label="Logout" onPress={() => signOut()} />*/}
</View> </View>
</View> </View>
<Button <Button
onPress={() => props.navigation.navigate("settings")} onPress={() => {
props.navigation.navigate("settings");
setPageIndex(0);
setUserView(true);
}}
label={"Manage Settings"} label={"Manage Settings"}
labelStyle={styles.label} labelStyle={styles.label}
iconSource={() => ( iconSource={() => (

View File

@ -1,125 +1,130 @@
import React, {memo} from "react"; import React, { memo } from "react";
import {Button, Picker, PickerModes, SegmentedControl, Text, View,} from "react-native-ui-lib"; import {
import {MaterialIcons} from "@expo/vector-icons"; Button,
import {modeMap, months} from "./constants"; Picker,
import {StyleSheet} from "react-native"; PickerModes,
import {useAtom} from "jotai"; SegmentedControl,
import {modeAtom, selectedDateAtom} from "@/components/pages/calendar/atoms"; Text,
import {isSameDay} from "date-fns"; View,
import {useAuthContext} from "@/contexts/AuthContext"; } from "react-native-ui-lib";
import { MaterialIcons } from "@expo/vector-icons";
import { modeMap, months } from "./constants";
import { StyleSheet } from "react-native";
import { useAtom } from "jotai";
import { modeAtom, selectedDateAtom } from "@/components/pages/calendar/atoms";
import { format, isSameDay } from "date-fns";
import { useAuthContext } from "@/contexts/AuthContext";
export const CalendarHeader = memo(() => { export const CalendarHeader = memo(() => {
const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
const [mode, setMode] = useAtom(modeAtom); const [mode, setMode] = useAtom(modeAtom);
const {profileData} = useAuthContext(); const { profileData } = useAuthContext();
const handleSegmentChange = (index: number) => { const handleSegmentChange = (index: number) => {
const selectedMode = modeMap.get(index); const selectedMode = modeMap.get(index);
if (selectedMode) { if (selectedMode) {
setTimeout(() => { setTimeout(() => {
setMode(selectedMode as "day" | "week" | "month"); setMode(selectedMode as "day" | "week" | "month");
}, 150); }, 150);
} }
}; };
const handleMonthChange = (month: string) => { const handleMonthChange = (month: string) => {
const currentDay = selectedDate.getDate(); const currentDay = selectedDate.getDate();
const currentYear = selectedDate.getFullYear(); const currentYear = selectedDate.getFullYear();
const newMonthIndex = months.indexOf(month); const newMonthIndex = months.indexOf(month);
const updatedDate = new Date(currentYear, newMonthIndex, currentDay); const updatedDate = new Date(currentYear, newMonthIndex, currentDay);
setSelectedDate(updatedDate); setSelectedDate(updatedDate);
}; };
const isSelectedDateToday = isSameDay(selectedDate, new Date()); const isSelectedDateToday = isSameDay(selectedDate, new Date());
return ( return (
<View <View
style={{ style={{
flexDirection: "row", flexDirection: "row",
justifyContent: "space-between", justifyContent: "space-between",
alignItems: "center", alignItems: "center",
paddingHorizontal: 10, paddingHorizontal: 10,
paddingVertical: 8, paddingVertical: 8,
borderRadius: 20, borderRadius: 20,
borderBottomLeftRadius: 0, borderBottomLeftRadius: 0,
borderBottomRightRadius: 0, borderBottomRightRadius: 0,
backgroundColor: "white", backgroundColor: "white",
marginBottom: 10, marginBottom: 10,
}} }}
>
<View row centerV gap-3>
<Text style={{ fontFamily: "Manrope_500Medium", fontSize: 17 }}>
{selectedDate.getFullYear()}
</Text>
<Picker
value={months[selectedDate.getMonth()]}
placeholder={"Select Month"}
style={{ fontFamily: "Manrope_500Medium", fontSize: 17, width: 85 }}
mode={PickerModes.SINGLE}
onChange={(itemValue) => handleMonthChange(itemValue as string)}
trailingAccessory={<MaterialIcons name={"keyboard-arrow-down"} />}
topBarProps={{
title: selectedDate.getFullYear().toString(),
titleStyle: { fontFamily: "Manrope_500Medium", fontSize: 17 },
}}
> >
<View row centerV gap-3> {months.map((month) => (
<Text style={{fontFamily: "Manrope_500Medium", fontSize: 17}}> <Picker.Item key={month} label={month} value={month} />
{selectedDate.getFullYear()} ))}
</Text> </Picker>
<Picker </View>
value={months[selectedDate.getMonth()]}
placeholder={"Select Month"}
style={{fontFamily: "Manrope_500Medium", fontSize: 17, width: 85}}
mode={PickerModes.SINGLE}
onChange={(itemValue) => handleMonthChange(itemValue as string)}
trailingAccessory={<MaterialIcons name={"keyboard-arrow-down"}/>}
topBarProps={{
title: selectedDate.getFullYear().toString(),
titleStyle: {fontFamily: "Manrope_500Medium", fontSize: 17},
}}
>
{months.map((month) => (
<Picker.Item key={month} label={month} value={month}/>
))}
</Picker>
</View>
<View row centerV> <View row centerV>
{!isSelectedDateToday && ( {!isSelectedDateToday && (
<Button <Button
size={"xSmall"} size={"xSmall"}
marginR-0 marginR-0
avoidInnerPadding avoidInnerPadding
style={{ style={{
borderRadius: 50, borderRadius: 50,
backgroundColor: "white", backgroundColor: "white",
borderWidth: 0.7, borderWidth: 0.7,
borderColor: "#dadce0", borderColor: "#dadce0",
height: 30, height: 30,
paddingHorizontal: 10 paddingHorizontal: 10,
}} }}
labelStyle={{ labelStyle={{
fontSize: 12, fontSize: 12,
color: "black", color: "black",
fontFamily: "Manrope_500Medium", fontFamily: "Manrope_500Medium",
}} }}
label={new Date().toLocaleDateString("en-US", { label={format(new Date(), "dd/MM/yyyy")}
timeZone: profileData?.timeZone || "", onPress={() => {
})} setSelectedDate(new Date());
onPress={() => { }}
setSelectedDate(new Date()); />
}} )}
/>
)}
<View> <View>
<SegmentedControl <SegmentedControl
segments={[{label: "D"}, {label: "W"}, {label: "M"}]} segments={[{ label: "D" }, { label: "W" }, { label: "M" }]}
backgroundColor="#ececec" backgroundColor="#ececec"
inactiveColor="#919191" inactiveColor="#919191"
activeBackgroundColor="#ea156c" activeBackgroundColor="#ea156c"
activeColor="white" activeColor="white"
outlineColor="white" outlineColor="white"
outlineWidth={3} outlineWidth={3}
segmentLabelStyle={styles.segmentslblStyle} segmentLabelStyle={styles.segmentslblStyle}
onChangeIndex={handleSegmentChange} onChangeIndex={handleSegmentChange}
initialIndex={mode === "day" ? 0 : mode === "week" ? 1 : 2} initialIndex={mode === "day" ? 0 : mode === "week" ? 1 : 2}
/> />
</View>
</View>
</View> </View>
); </View>
</View>
);
}); });
const styles = StyleSheet.create({ const styles = StyleSheet.create({
segmentslblStyle: { segmentslblStyle: {
fontSize: 12, fontSize: 12,
fontFamily: "Manrope_600SemiBold", fontFamily: "Manrope_600SemiBold",
}, },
}); });

View File

@ -1,255 +1,276 @@
import React, {useCallback, useEffect, useMemo, useState} from "react"; import React, { useCallback, useEffect, useMemo, useState } from "react";
import {Calendar} from "react-native-big-calendar"; import { Calendar } from "react-native-big-calendar";
import {ActivityIndicator, StyleSheet, View, ViewStyle} from "react-native"; import { ActivityIndicator, StyleSheet, View, ViewStyle } from "react-native";
import {useGetEvents} from "@/hooks/firebase/useGetEvents"; import { useGetEvents } from "@/hooks/firebase/useGetEvents";
import {useAtom, useSetAtom} from "jotai"; import { useAtom, useSetAtom } from "jotai";
import { import {
editVisibleAtom, editVisibleAtom,
eventForEditAtom, eventForEditAtom,
modeAtom, modeAtom,
selectedDateAtom, selectedDateAtom,
selectedNewEventDateAtom, selectedNewEventDateAtom,
} from "@/components/pages/calendar/atoms"; } from "@/components/pages/calendar/atoms";
import {useAuthContext} from "@/contexts/AuthContext"; import { useAuthContext } from "@/contexts/AuthContext";
import {CalendarEvent} from "@/components/pages/calendar/interfaces"; import { CalendarEvent } from "@/components/pages/calendar/interfaces";
import {Text} from "react-native-ui-lib"; import { Text } from "react-native-ui-lib";
interface EventCalendarProps { interface EventCalendarProps {
calendarHeight: number; calendarHeight: number;
// WAS USED FOR SCROLLABLE CALENDARS, PERFORMANCE WAS NOT OPTIMAL // WAS USED FOR SCROLLABLE CALENDARS, PERFORMANCE WAS NOT OPTIMAL
calendarWidth: number; calendarWidth: number;
} }
const getTotalMinutes = () => { const getTotalMinutes = () => {
const date = new Date(); const date = new Date();
return Math.abs(date.getUTCHours() * 60 + date.getUTCMinutes() - 200); return Math.abs(date.getUTCHours() * 60 + date.getUTCMinutes() - 200);
}; };
export const EventCalendar: React.FC<EventCalendarProps> = React.memo( export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
({calendarHeight}) => { ({ calendarHeight }) => {
const {data: events, isLoading} = useGetEvents(); const { data: events, isLoading } = useGetEvents();
const {profileData} = useAuthContext(); const { profileData } = useAuthContext();
const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
const [mode, setMode] = useAtom(modeAtom); const [mode, setMode] = useAtom(modeAtom);
const setEditVisible = useSetAtom(editVisibleAtom); const setEditVisible = useSetAtom(editVisibleAtom);
const setEventForEdit = useSetAtom(eventForEditAtom); const setEventForEdit = useSetAtom(eventForEditAtom);
const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom); const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom);
const [isRendering, setIsRendering] = useState(true); const [isRendering, setIsRendering] = useState(true);
const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes()); const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes());
const todaysDate = new Date() const todaysDate = new Date();
useEffect(() => { useEffect(() => {
if (events && mode) { if (events && mode) {
setIsRendering(true); setIsRendering(true);
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
setIsRendering(false); setIsRendering(false);
}, 300); }, 300);
return () => clearTimeout(timeout); return () => clearTimeout(timeout);
} }
}, [events, mode]); }, [events, mode]);
const handlePressEvent = useCallback( const handlePressEvent = useCallback(
(event: CalendarEvent) => { (event: CalendarEvent) => {
if (mode === "day" || mode === "week") { if (mode === "day" || mode === "week") {
setEditVisible(true); setEditVisible(true);
console.log({event}); console.log({ event });
setEventForEdit(event); setEventForEdit(event);
} else { } else {
setMode("day"); setMode("day");
setSelectedDate(event.start); setSelectedDate(event.start);
}
},
[setEditVisible, setEventForEdit, mode]
);
const handlePressCell = useCallback(
(date: Date) => {
if (mode === "day" || mode === "week") {
setSelectedNewEndDate(date);
} else {
setMode("day");
setSelectedDate(date);
}
},
[mode, setSelectedNewEndDate, setSelectedDate]
);
const handleSwipeEnd = useCallback(
(date: Date) => {
setSelectedDate(date);
},
[setSelectedDate]
);
const memoizedEventCellStyle = useCallback(
(event: CalendarEvent) => ({backgroundColor: event.eventColor}),
[]
);
const memoizedWeekStartsOn = useMemo(
() => (profileData?.firstDayOfWeek === "Mondays" ? 1 : 0),
[profileData]
);
const isSameDate = useCallback((date1: Date, date2: Date) => {
return (
date1.getDate() === date2.getDate() &&
date1.getMonth() === date2.getMonth() &&
date1.getFullYear() === date2.getFullYear()
);
}, []);
const dayHeaderColor = useMemo(() => {
return isSameDate(todaysDate, selectedDate) ? "white" : "#4d4d4d";
}, [selectedDate, mode]);
const dateStyle = useMemo(() => {
if (mode === "week") return undefined
return isSameDate(todaysDate, selectedDate) && mode === "day"
? styles.dayHeader
: styles.otherDayHeader;
}, [selectedDate, mode]);
const memoizedHeaderContentStyle = useMemo(() => {
if (mode === "day") {
return styles.dayModeHeader;
} else if (mode === "week") {
return styles.weekModeHeader;
} else if (mode === "month") {
return styles.monthModeHeader;
} else {
return {};
}
}, [mode]);
const memoizedEvents = useMemo(() => events ?? [], [events]);
const renderCustomDateForMonth = (date: Date) => {
const circleStyle = useMemo<ViewStyle>(
() => ({
position: "absolute",
width: 30,
height: 30,
justifyContent: "center",
alignItems: "center",
borderRadius: 15,
}),
[]
);
const defaultStyle = useMemo<ViewStyle>(
() => ({
...circleStyle,
}),
[circleStyle]
);
const currentDateStyle = useMemo<ViewStyle>(
() => ({
...circleStyle,
backgroundColor: "#4184f2",
}),
[circleStyle]
);
const renderDate = useCallback(
(date: Date) => {
const isCurrentDate = isSameDate(todaysDate, date);
const appliedStyle = isCurrentDate ? currentDateStyle : defaultStyle;
return (
<View style={{alignItems: "center"}}>
<View style={appliedStyle}>
<Text style={{color: isCurrentDate ? "white" : "black"}}>
{date.getDate()}
</Text>
</View>
</View>
);
},
[todaysDate, currentDateStyle, defaultStyle] // dependencies
);
return renderDate(date);
};
useEffect(() => {
setOffsetMinutes(getTotalMinutes());
}, [events, mode]);
if (isLoading || isRendering) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#0000ff"/>
</View>
);
} }
},
[setEditVisible, setEventForEdit, mode]
);
return ( const handlePressCell = useCallback(
<Calendar (date: Date) => {
bodyContainerStyle={styles.calHeader} if (mode === "day" || mode === "week") {
swipeEnabled setSelectedNewEndDate(date);
enableEnrichedEvents } else {
mode={mode} setMode("day");
events={memoizedEvents} setSelectedDate(date);
eventCellStyle={memoizedEventCellStyle} }
onPressEvent={handlePressEvent} },
weekStartsOn={memoizedWeekStartsOn} [mode, setSelectedNewEndDate, setSelectedDate]
height={calendarHeight} );
activeDate={todaysDate}
date={selectedDate} const handleSwipeEnd = useCallback(
onPressCell={handlePressCell} (date: Date) => {
headerContentStyle={memoizedHeaderContentStyle} setSelectedDate(date);
onSwipeEnd={handleSwipeEnd} },
scrollOffsetMinutes={offsetMinutes} [setSelectedDate]
dayHeaderStyle={dateStyle} );
dayHeaderHighlightColor={dayHeaderColor}
renderCustomDateForMonth={renderCustomDateForMonth} const memoizedEventCellStyle = useCallback(
showAdjacentMonths (event: CalendarEvent) => ({ backgroundColor: event.eventColor }),
/> []
); );
const memoizedWeekStartsOn = useMemo(
() => (profileData?.firstDayOfWeek === "Mondays" ? 1 : 0),
[profileData]
);
const isSameDate = useCallback((date1: Date, date2: Date) => {
return (
date1.getDate() === date2.getDate() &&
date1.getMonth() === date2.getMonth() &&
date1.getFullYear() === date2.getFullYear()
);
}, []);
const dayHeaderColor = useMemo(() => {
return isSameDate(todaysDate, selectedDate) ? "white" : "#4d4d4d";
}, [selectedDate, mode]);
const dateStyle = useMemo(() => {
if (mode === "week") return undefined;
return isSameDate(todaysDate, selectedDate) && mode === "day"
? styles.dayHeader
: styles.otherDayHeader;
}, [selectedDate, mode]);
const memoizedHeaderContentStyle = useMemo(() => {
if (mode === "day") {
return styles.dayModeHeader;
} else if (mode === "week") {
return styles.weekModeHeader;
} else if (mode === "month") {
return styles.monthModeHeader;
} else {
return {};
}
}, [mode]);
const memoizedEvents = useMemo(() => events ?? [], [events]);
const renderCustomDateForMonth = (date: Date) => {
const circleStyle = useMemo<ViewStyle>(
() => ({
position: "absolute",
width: 30,
height: 30,
justifyContent: "center",
alignItems: "center",
borderRadius: 15,
}),
[]
);
const defaultStyle = useMemo<ViewStyle>(
() => ({
...circleStyle,
}),
[circleStyle]
);
const currentDateStyle = useMemo<ViewStyle>(
() => ({
...circleStyle,
backgroundColor: "#4184f2",
}),
[circleStyle]
);
const renderDate = useCallback(
(date: Date) => {
const isCurrentDate = isSameDate(todaysDate, date);
const appliedStyle = isCurrentDate ? currentDateStyle : defaultStyle;
return (
<View style={{ alignItems: "center" }}>
<View style={appliedStyle}>
<Text style={{ color: isCurrentDate ? "white" : "black" }}>
{date.getDate()}
</Text>
</View>
</View>
);
},
[todaysDate, currentDateStyle, defaultStyle] // dependencies
);
return renderDate(date);
};
useEffect(() => {
setOffsetMinutes(getTotalMinutes());
}, [events, mode]);
if (isLoading || isRendering) {
return (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
} }
return (
<Calendar
bodyContainerStyle={styles.calHeader}
swipeEnabled
enableEnrichedEvents
mode={mode}
events={memoizedEvents}
eventCellStyle={memoizedEventCellStyle}
onPressEvent={handlePressEvent}
weekStartsOn={memoizedWeekStartsOn}
height={calendarHeight}
activeDate={todaysDate}
date={selectedDate}
onPressCell={handlePressCell}
headerContentStyle={memoizedHeaderContentStyle}
onSwipeEnd={handleSwipeEnd}
scrollOffsetMinutes={offsetMinutes}
theme={{
palette: {
nowIndicator: "#fd1575",
gray: {
"100": "#e8eaed",
"200": "#e8eaed",
"500": "#b7b7b7",
"800": "#919191",
},
},
typography: {
fontFamily: "PlusJakartaSans_500Medium",
sm: { fontFamily: "Manrope_600SemiBold", fontSize: 15 },
xl: {
fontFamily: "PlusJakartaSans_500Medium",
fontSize: 16,
},
moreLabel: {},
xs:{fontSize: 10}
},
}}
dayHeaderStyle={dateStyle}
dayHeaderHighlightColor={"white"}
renderCustomDateForMonth={renderCustomDateForMonth}
showAdjacentMonths
/>
);
}
); );
const styles = StyleSheet.create({ const styles = StyleSheet.create({
segmentslblStyle: { segmentslblStyle: {
fontSize: 12, fontSize: 12,
fontFamily: "Manrope_600SemiBold", fontFamily: "Manrope_600SemiBold",
}, },
calHeader: { calHeader: {
borderWidth: 0, borderWidth: 0,
}, },
dayModeHeader: { dayModeHeader: {
alignSelf: "flex-start", alignSelf: "flex-start",
justifyContent: "space-between", justifyContent: "space-between",
alignContent: "center", alignContent: "center",
width: 38, width: 38,
right: 42, right: 42,
height: 13, height: 13,
}, },
weekModeHeader: {}, weekModeHeader: {},
monthModeHeader: {}, monthModeHeader: {},
loadingContainer: { loadingContainer: {
flex: 1, flex: 1,
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
}, },
dayHeader: { dayHeader: {
backgroundColor: "#4184f2", backgroundColor: "#4184f2",
aspectRatio: 1, aspectRatio: 1,
borderRadius: 100, borderRadius: 100,
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
}, },
otherDayHeader: { otherDayHeader: {
backgroundColor: "transparent", backgroundColor: "transparent",
color: "#919191", color: "#919191",
aspectRatio: 1, aspectRatio: 1,
borderRadius: 100, borderRadius: 100,
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
}, },
}); });

View File

@ -1,9 +1,11 @@
import { atom } from 'jotai'; import { atom } from "jotai";
import {CalendarEvent} from "@/components/pages/calendar/interfaces"; import { CalendarEvent } from "@/components/pages/calendar/interfaces";
export const editVisibleAtom = atom<boolean>(false); export const editVisibleAtom = atom<boolean>(false);
export const eventForEditAtom = atom<CalendarEvent | undefined>(undefined); export const eventForEditAtom = atom<CalendarEvent | undefined>(undefined);
export const isFamilyViewAtom = atom<boolean>(false); export const isFamilyViewAtom = atom<boolean>(false);
export const modeAtom = atom<"week" | "month" | "day">("week"); export const modeAtom = atom<"week" | "month" | "day">("week");
export const selectedDateAtom = atom<Date>(new Date()); export const selectedDateAtom = atom<Date>(new Date());
export const selectedNewEventDateAtom = atom<Date | undefined>(undefined); export const selectedNewEventDateAtom = atom<Date | undefined>(undefined);
export const settingsPageIndex = atom<number>(0);
export const userSettingsView = atom<boolean>(true);

File diff suppressed because it is too large Load Diff

View File

@ -4,30 +4,32 @@ import { Ionicons } from "@expo/vector-icons";
import { ToDosContextProvider } from "@/contexts/ToDosContext"; import { ToDosContextProvider } from "@/contexts/ToDosContext";
import ToDosList from "../todos/ToDosList"; import ToDosList from "../todos/ToDosList";
import { ScrollView } from "react-native-gesture-handler"; import { ScrollView } from "react-native-gesture-handler";
import { settingsPageIndex } from "../calendar/atoms";
import { useAtom } from "jotai";
const ChoreRewardSettings = () => {
const [pageIndex, setPageIndex] = useAtom(settingsPageIndex);
const ChoreRewardSettings = (props: {
setSelectedPage: (page: number) => void;
}) => {
return ( return (
<ToDosContextProvider> <ToDosContextProvider>
<View marginT-10 marginH-20> <TouchableOpacity onPress={() => setPageIndex(0)}>
<View row marginT-20 marginB-20 marginL-20 centerV>
<Ionicons
name="chevron-back"
size={14}
color="#979797"
style={{ paddingBottom: 3 }}
/>
<Text
style={{ fontFamily: "Poppins_400Regular", fontSize: 14.71 }}
color="#979797"
>
Return to main settings
</Text>
</View>
</TouchableOpacity>
<View marginH-20>
<ScrollView> <ScrollView>
<TouchableOpacity onPress={() => props.setSelectedPage(0)}>
<View row marginT-20 marginB-35 centerV>
<Ionicons
name="chevron-back"
size={14}
color="#979797"
style={{ paddingBottom: 3 }}
/>
<Text
style={{ fontFamily: "Poppins_400Regular", fontSize: 14.71 }}
color="#979797"
>
Return to main settings
</Text>
</View>
</TouchableOpacity>
<Text text60R marginB-20> <Text text60R marginB-20>
Chore Reward Settings Chore Reward Settings
</Text> </Text>

View File

@ -1,7 +1,7 @@
import {Button, Text, View} from "react-native-ui-lib"; import { Button, Text, View } from "react-native-ui-lib";
import React, {useState} from "react"; import React, { useState } from "react";
import {StyleSheet} from "react-native"; import { StyleSheet } from "react-native";
import {Octicons} from "@expo/vector-icons"; import { Octicons } from "@expo/vector-icons";
import CalendarSettingsPage from "./CalendarSettingsPage"; import CalendarSettingsPage from "./CalendarSettingsPage";
import ChoreRewardSettings from "./ChoreRewardSettings"; import ChoreRewardSettings from "./ChoreRewardSettings";
import UserSettings from "./UserSettings"; import UserSettings from "./UserSettings";
@ -9,120 +9,124 @@ import ProfileIcon from "@/assets/svgs/ProfileIcon";
import CalendarIcon from "@/assets/svgs/CalendarIcon"; import CalendarIcon from "@/assets/svgs/CalendarIcon";
import PrivacyPolicyIcon from "@/assets/svgs/PrivacyPolicyIcon"; import PrivacyPolicyIcon from "@/assets/svgs/PrivacyPolicyIcon";
import ArrowRightIcon from "@/assets/svgs/ArrowRightIcon"; import ArrowRightIcon from "@/assets/svgs/ArrowRightIcon";
import {ProfileType, useAuthContext} from "@/contexts/AuthContext"; import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
import { settingsPageIndex } from "../calendar/atoms";
import { useAtom } from "jotai";
const pageIndex = { const pageIndex = {
main: 0, main: 0,
user: 1, user: 1,
calendar: 2, calendar: 2,
chore: 3, chore: 3,
policy: 4, policy: 4,
}; };
const SettingsPage = () => { const SettingsPage = () => {
const {profileData} = useAuthContext() const { profileData } = useAuthContext();
const isntParent = profileData?.userType !== ProfileType.PARENT const [pageIndex, setPageIndex] = useAtom(settingsPageIndex);
const isntParent = profileData?.userType !== ProfileType.PARENT;
const [selectedPage, setSelectedPage] = useState<number>(0); return (
return ( <View flexG>
<View flexG> {pageIndex == 0 && (
{selectedPage == 0 && ( <View flexG centerH marginH-30 marginT-30>
<View flexG centerH marginH-30 marginT-30> <Button
<Button disabled={isntParent}
disabled={isntParent} backgroundColor="white"
backgroundColor="white" style={styles.mainBtn}
style={styles.mainBtn} children={
children={ <View row centerV width={"100%"}>
<View row centerV width={"100%"}> <ProfileIcon style={{ marginRight: 10 }} color="#07b9c8" />
<ProfileIcon style={{marginRight: 10}} color="#07b9c8"/> <Text
<Text style={[styles.label, isntParent && styles.disabledText]}> style={[
Manage My Profile styles.label,
</Text> isntParent ? styles.disabledText : { color: "#07b9c8" },
<ArrowRightIcon style={{marginLeft: "auto"}}/> ]}
</View> >
} Manage My Profile
onPress={() => setSelectedPage(pageIndex.user)} </Text>
/> <ArrowRightIcon style={{ marginLeft: "auto" }} />
<Button </View>
disabled={isntParent} }
backgroundColor="white" onPress={() => setPageIndex(1)}
style={styles.mainBtn} />
children={ <Button
<View row centerV width={"100%"}> disabled={isntParent}
<CalendarIcon style={{marginRight: 10}}/> backgroundColor="white"
<Text style={[styles.label, isntParent && styles.disabledText]}> style={styles.mainBtn}
Calendar Settings children={
</Text> <View row centerV width={"100%"}>
<ArrowRightIcon style={{marginLeft: "auto"}}/> <CalendarIcon style={{ marginRight: 10 }} />
</View> <Text
} style={[
onPress={() => { styles.label,
setSelectedPage(pageIndex.calendar); isntParent ? styles.disabledText : { color: "#FD1775" },
}} ]}
/> >
<Button Calendar Settings
disabled={isntParent} </Text>
backgroundColor="white" <ArrowRightIcon style={{ marginLeft: "auto" }} />
style={styles.mainBtn} </View>
children={ }
<View row centerV width={"100%"}> onPress={() => {
<Octicons setPageIndex(2);
name="gear" }}
size={24} />
color="#ff9900" <Button
style={{marginRight: 10}} disabled={isntParent}
/> backgroundColor="white"
<Text style={[styles.label, isntParent && styles.disabledText]}> style={styles.mainBtn}
To-Do Reward Settings children={
</Text> <View row centerV width={"100%"}>
<ArrowRightIcon style={{marginLeft: "auto"}}/> <Octicons
</View> name="gear"
} size={24}
onPress={() => setSelectedPage(pageIndex.chore)} color="#ff9900"
/> style={{ marginRight: 10 }}
<Button />
backgroundColor="white" <Text style={[styles.label, isntParent ? styles.disabledText : {color: "#ff9900"}]}>
style={styles.mainBtn} To-Do Reward Settings
children={ </Text>
<View row centerV width={"100%"}> <ArrowRightIcon style={{ marginLeft: "auto" }} />
<PrivacyPolicyIcon style={{marginRight: 10}}/> </View>
<Text style={styles.label}> }
Cally Privacy Policy onPress={() => setPageIndex(3)}
</Text> />
<ArrowRightIcon style={{marginLeft: "auto"}}/> <Button
</View> backgroundColor="white"
} style={styles.mainBtn}
/> children={
</View> <View row centerV width={"100%"}>
)} <PrivacyPolicyIcon style={{ marginRight: 10 }} />
{selectedPage == pageIndex.calendar && ( <Text style={[styles.label]} color={"#6C645B"}>Cally Privacy Policy</Text>
<CalendarSettingsPage setSelectedPage={setSelectedPage}/> <ArrowRightIcon style={{ marginLeft: "auto" }} />
)} </View>
{selectedPage == pageIndex.chore && ( }
<ChoreRewardSettings setSelectedPage={setSelectedPage}/> />
)}
{selectedPage == pageIndex.user && (
<UserSettings setSelectedPage={setSelectedPage}/>
)}
</View> </View>
); )}
{pageIndex == 2 && <CalendarSettingsPage />}
{pageIndex == 3 && <ChoreRewardSettings />}
{pageIndex == 1 && <UserSettings />}
</View>
);
}; };
export default SettingsPage; export default SettingsPage;
const styles = StyleSheet.create({ const styles = StyleSheet.create({
mainBtn: { mainBtn: {
width: 311, width: 311,
justifyContent: "flex-start", justifyContent: "flex-start",
marginBottom: 20, marginBottom: 20,
height: 57.61, height: 57.61,
}, },
label: { label: {
fontFamily: "Poppins_400Regular", fontFamily: "Poppins_400Regular",
fontSize: 14.71, fontSize: 14.71,
textAlignVertical: "center", textAlignVertical: "center",
}, },
disabledText: { disabledText: {
color: '#A9A9A9', // Example of a gray color for disabled text color: "#A9A9A9", // Example of a gray color for disabled text
}, },
}); });

View File

@ -4,70 +4,86 @@ import { Ionicons } from "@expo/vector-icons";
import { ScrollView, StyleSheet } from "react-native"; import { ScrollView, StyleSheet } from "react-native";
import MyProfile from "./user_settings_views/MyProfile"; import MyProfile from "./user_settings_views/MyProfile";
import MyGroup from "./user_settings_views/MyGroup"; import MyGroup from "./user_settings_views/MyGroup";
import { useAtom } from "jotai";
import { settingsPageIndex, userSettingsView } from "../calendar/atoms";
import { AuthContextProvider } from "@/contexts/AuthContext";
const UserSettings = (props: { setSelectedPage: (page: number) => void }) => { const UserSettings = () => {
const [selectedView, setSelectedView] = useState<boolean>(true); const [pageIndex, setPageIndex] = useAtom(settingsPageIndex);
const [userView, setUserView] = useAtom(userSettingsView);
return ( return (
<View flexG> <AuthContextProvider>
<ScrollView style={{ paddingBottom: 20, minHeight: "100%" }}> <View flexG>
<TouchableOpacity onPress={() => props.setSelectedPage(0)}> <ScrollView style={{ paddingBottom: 20, minHeight: "100%" }}>
<View row marginT-20 marginB-35 centerV> <TouchableOpacity
<Ionicons name="chevron-back" size={14} color="#979797" style={{paddingBottom: 3}} /> onPress={() => {
<Text setPageIndex(0);
style={{ fontFamily: "Poppins_400Regular", fontSize: 14.71 }} setUserView(true);
color="#979797" }}
> >
Return to main settings <View row marginT-20 marginB-20 marginL-20 centerV>
<Ionicons
name="chevron-back"
size={14}
color="#979797"
style={{ paddingBottom: 3 }}
/>
<Text
style={{ fontFamily: "Poppins_400Regular", fontSize: 14.71 }}
color="#979797"
>
Return to main settings
</Text>
</View>
</TouchableOpacity>
<View marginH-26 flexG style={{ minHeight: "90%" }}>
<Text text60R marginB-25>
User Management
</Text> </Text>
<View style={styles.buttonSwitch} spread row>
<TouchableOpacity
onPress={() => setUserView(true)}
centerV
centerH
style={userView == true ? styles.btnSelected : styles.btnNot}
>
<View>
<Text
style={styles.btnTxt}
color={userView ? "white" : "black"}
>
My Profile
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setUserView(false)}
centerV
centerH
style={userView == false ? styles.btnSelected : styles.btnNot}
>
<View>
<Text
style={styles.btnTxt}
color={!userView ? "white" : "black"}
>
My Group
</Text>
</View>
</TouchableOpacity>
</View>
{userView && <MyProfile />}
{!userView && <MyGroup />}
</View> </View>
</TouchableOpacity> </ScrollView>
<View marginH-20 flexG style={{ minHeight: "90%" }}>
<Text text60R marginB-25>
User Management
</Text>
<View style={styles.buttonSwitch} spread row>
<TouchableOpacity
onPress={() => setSelectedView(true)}
centerV
centerH
style={selectedView == true ? styles.btnSelected : styles.btnNot}
>
<View>
<Text
style={styles.btnTxt}
color={selectedView ? "white" : "black"}
>
My Profile
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setSelectedView(false)}
centerV
centerH
style={selectedView == false ? styles.btnSelected : styles.btnNot}
>
<View>
<Text
style={styles.btnTxt}
color={!selectedView ? "white" : "black"}
>
My Group
</Text>
</View>
</TouchableOpacity>
</View>
{selectedView && <MyProfile />}
{!selectedView && <MyGroup />}
</View>
</ScrollView>
{!selectedView && ( {!userView && (
<View> <View>
<Text>selview</Text> <Text>selview</Text>
</View> </View>
)} )}
</View> </View>
</AuthContextProvider>
); );
}; };

File diff suppressed because it is too large Load Diff