mirror of
https://github.com/urosran/cally.git
synced 2025-11-26 08:24:55 +00:00
433 lines
13 KiB
TypeScript
433 lines
13 KiB
TypeScript
import React from "react";
|
|
import { Drawer } from "expo-router/drawer";
|
|
import { useSignOut } from "@/hooks/firebase/useSignOut";
|
|
import {
|
|
DrawerContentScrollView,
|
|
DrawerNavigationOptions,
|
|
DrawerNavigationProp,
|
|
} from "@react-navigation/drawer";
|
|
import {
|
|
Button,
|
|
ButtonSize,
|
|
Text,
|
|
TouchableOpacity,
|
|
View,
|
|
} from "react-native-ui-lib";
|
|
import { ImageBackground, Pressable, StyleSheet } from "react-native";
|
|
import DrawerButton from "@/components/shared/DrawerButton";
|
|
import NavGroceryIcon from "@/assets/svgs/NavGroceryIcon";
|
|
import NavToDosIcon from "@/assets/svgs/NavToDosIcon";
|
|
import NavBrainDumpIcon from "@/assets/svgs/NavBrainDumpIcon";
|
|
import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon";
|
|
import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon";
|
|
import ViewSwitch from "@/components/pages/(tablet_pages)/ViewSwitch";
|
|
import { useSetAtom } from "jotai";
|
|
import {
|
|
isFamilyViewAtom,
|
|
settingsPageIndex,
|
|
toDosPageIndex,
|
|
userSettingsView,
|
|
} from "@/components/pages/calendar/atoms";
|
|
import Ionicons from "@expo/vector-icons/Ionicons";
|
|
import * as Device from "expo-device";
|
|
import { DeviceType } from "expo-device";
|
|
import FeedbackNavIcon from "@/assets/svgs/FeedbackNavIcon";
|
|
import DrawerIcon from "@/assets/svgs/DrawerIcon";
|
|
import { RouteProp } from "@react-navigation/core";
|
|
import RefreshButton from "@/components/shared/RefreshButton";
|
|
import { useCalSync } from "@/hooks/useCalSync";
|
|
import {useIsFetching} from "@tanstack/react-query";
|
|
import { CalendarHeader } from "@/components/pages/calendar/CalendarHeader";
|
|
|
|
type DrawerParamList = {
|
|
index: undefined;
|
|
calendar: undefined;
|
|
todos: undefined;
|
|
};
|
|
|
|
type NavigationProp = DrawerNavigationProp<DrawerParamList>;
|
|
|
|
interface ViewSwitchProps {
|
|
navigation: NavigationProp;
|
|
}
|
|
|
|
interface HeaderRightProps {
|
|
routeName: keyof DrawerParamList;
|
|
navigation: NavigationProp;
|
|
}
|
|
|
|
const MemoizedViewSwitch = React.memo<ViewSwitchProps>(({ navigation }) => (
|
|
<ViewSwitch navigation={navigation} />
|
|
));
|
|
|
|
const HeaderRight = React.memo<HeaderRightProps>(
|
|
({ routeName, navigation }) => {
|
|
const showViewSwitch = ["calendar", "todos", "index"].includes(routeName);
|
|
|
|
if (Device.deviceType !== DeviceType.TABLET || !showViewSwitch) {
|
|
return null;
|
|
}
|
|
|
|
return <MemoizedViewSwitch navigation={navigation} />;
|
|
}
|
|
);
|
|
export default function TabLayout() {
|
|
const { mutateAsync: signOut } = useSignOut();
|
|
const setIsFamilyView = useSetAtom(isFamilyViewAtom);
|
|
const setPageIndex = useSetAtom(settingsPageIndex);
|
|
const setUserView = useSetAtom(userSettingsView);
|
|
const setToDosIndex = useSetAtom(toDosPageIndex);
|
|
const { resyncAllCalendars, isSyncing } = useCalSync();
|
|
|
|
const isFormatting = useIsFetching({queryKey: ['formattedEvents']}) > 0;
|
|
const isFetching = useIsFetching({queryKey: ['events']}) > 0;
|
|
|
|
const isLoading = isSyncing || isFormatting || isFetching;
|
|
|
|
const onRefresh = React.useCallback(async () => {
|
|
try {
|
|
await resyncAllCalendars();
|
|
} catch (error) {
|
|
console.error("Refresh failed:", error);
|
|
}
|
|
}, [resyncAllCalendars]);
|
|
|
|
const screenOptions = ({
|
|
navigation,
|
|
route,
|
|
}: {
|
|
navigation: DrawerNavigationProp<DrawerParamList>;
|
|
route: RouteProp<DrawerParamList>;
|
|
}): DrawerNavigationOptions => ({
|
|
lazy: true,
|
|
headerShown: true,
|
|
headerTitleAlign:
|
|
Device.deviceType === DeviceType.TABLET ? "left" : "center",
|
|
headerTitle: ({ children }) => {
|
|
const isCalendarRoute = ["calendar", "index"].includes(route.name);
|
|
|
|
if (isCalendarRoute && Device.deviceType !== DeviceType.TABLET) {
|
|
return <View centerV><CalendarHeader /></View>;
|
|
}
|
|
|
|
return (
|
|
<Text
|
|
style={{
|
|
fontFamily: "Manrope_600SemiBold",
|
|
fontSize: Device.deviceType === DeviceType.TABLET ? 22 : 17,
|
|
}}
|
|
>
|
|
{children}
|
|
</Text>
|
|
);
|
|
},
|
|
headerTitleStyle: {
|
|
fontFamily: "Manrope_600SemiBold",
|
|
fontSize: Device.deviceType === DeviceType.TABLET ? 22 : 17,
|
|
},
|
|
headerLeft: () => (
|
|
<Pressable
|
|
onPress={() => {
|
|
navigation.toggleDrawer()
|
|
}}
|
|
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
style={({ pressed }) => [
|
|
{
|
|
marginLeft: 16,
|
|
opacity: pressed ? 0.4 : 1
|
|
}
|
|
]}
|
|
|
|
>
|
|
<DrawerIcon />
|
|
</Pressable>
|
|
),
|
|
headerRight: () => {
|
|
const showViewSwitch = ["calendar", "todos", "index"].includes(
|
|
route.name
|
|
);
|
|
const isCalendarPage = ["calendar", "index"].includes(route.name);
|
|
|
|
if (Device.deviceType !== DeviceType.TABLET || !showViewSwitch) {
|
|
return isCalendarPage ? (
|
|
<View marginR-8 >
|
|
<RefreshButton onRefresh={onRefresh} isSyncing={isLoading} />
|
|
</View>
|
|
) : null;
|
|
}
|
|
|
|
return (
|
|
<View marginR-16 row centerV>
|
|
{Device.deviceType === DeviceType.TABLET && isCalendarPage && <View flex-1 center><CalendarHeader />
|
|
</View>}
|
|
{isCalendarPage && (
|
|
<View marginR-16><RefreshButton onRefresh={onRefresh} isSyncing={isLoading} /></View>
|
|
)}
|
|
<MemoizedViewSwitch navigation={navigation} />
|
|
</View>
|
|
);
|
|
},
|
|
drawerStyle: {
|
|
width: Device.deviceType === DeviceType.TABLET ? "30%" : "90%",
|
|
backgroundColor: "#f9f8f7",
|
|
height: "100%",
|
|
},
|
|
});
|
|
|
|
return (
|
|
<Drawer
|
|
initialRouteName={"index"}
|
|
detachInactiveScreens
|
|
screenOptions={screenOptions}
|
|
drawerContent={(props) => {
|
|
return (
|
|
<DrawerContentScrollView {...props} style={{}}>
|
|
<View centerV marginH-30 marginT-20 marginB-20 row>
|
|
<ImageBackground
|
|
source={require("../../assets/images/splash.png")}
|
|
style={{
|
|
backgroundColor: "transparent",
|
|
height: 51.43,
|
|
aspectRatio: 1,
|
|
marginRight: 8,
|
|
}}
|
|
/>
|
|
<Text style={styles.title}>Welcome to Cally</Text>
|
|
</View>
|
|
<View
|
|
style={{
|
|
flexDirection: "row",
|
|
paddingHorizontal: 30,
|
|
}}
|
|
>
|
|
<View style={{ flex: 1, paddingRight: 5 }}>
|
|
<DrawerButton
|
|
title={"Calendar"}
|
|
color="rgb(7, 184, 199)"
|
|
bgColor={"rgb(231, 248, 250)"}
|
|
pressFunc={() => {
|
|
props.navigation.navigate("calendar");
|
|
setPageIndex(0);
|
|
setToDosIndex(0);
|
|
setUserView(true);
|
|
setIsFamilyView(false);
|
|
}}
|
|
icon={<NavCalendarIcon />}
|
|
/>
|
|
<DrawerButton
|
|
color="#50be0c"
|
|
title={"Groceries"}
|
|
bgColor={"#eef9e7"}
|
|
pressFunc={() => {
|
|
props.navigation.navigate("grocery");
|
|
setPageIndex(0);
|
|
setToDosIndex(0);
|
|
setUserView(true);
|
|
setIsFamilyView(false);
|
|
}}
|
|
icon={<NavGroceryIcon />}
|
|
/>
|
|
<DrawerButton
|
|
color="#ea156d"
|
|
title={"Feedback"}
|
|
bgColor={"#fdedf4"}
|
|
pressFunc={() => {
|
|
props.navigation.navigate("feedback");
|
|
setPageIndex(0);
|
|
setToDosIndex(0);
|
|
setUserView(true);
|
|
setIsFamilyView(false);
|
|
}}
|
|
icon={<FeedbackNavIcon />}
|
|
/>
|
|
</View>
|
|
<View style={{ flex: 1, paddingRight: 0 }}>
|
|
{/*<DrawerButton
|
|
color="#fd1775"
|
|
title={"My Reminders"}
|
|
bgColor={"#ffe8f2"}
|
|
pressFunc={() => props.navigation.navigate("reminders")}
|
|
icon={
|
|
<FontAwesome6
|
|
name="clock-rotate-left"
|
|
size={28}
|
|
color="#fd1775"
|
|
/>
|
|
}
|
|
/>*/}
|
|
<DrawerButton
|
|
color="#8005eb"
|
|
title={"To Dos"}
|
|
bgColor={"#f3e6fd"}
|
|
pressFunc={() => {
|
|
props.navigation.navigate("todos");
|
|
setPageIndex(0);
|
|
setToDosIndex(0);
|
|
setUserView(true);
|
|
setIsFamilyView(false);
|
|
}}
|
|
icon={<NavToDosIcon />}
|
|
/>
|
|
<DrawerButton
|
|
color="#e0ca03"
|
|
title={"Brain Dump"}
|
|
bgColor={"#fffacb"}
|
|
pressFunc={() => {
|
|
props.navigation.navigate("brain_dump");
|
|
setPageIndex(0);
|
|
setToDosIndex(0);
|
|
setUserView(true);
|
|
setIsFamilyView(false);
|
|
}}
|
|
icon={<NavBrainDumpIcon />}
|
|
/>
|
|
<DrawerButton
|
|
color="#e0ca03"
|
|
title={"Notifications"}
|
|
bgColor={"#ffdda1"}
|
|
pressFunc={() => {
|
|
props.navigation.navigate("notifications");
|
|
setPageIndex(0);
|
|
setToDosIndex(0);
|
|
setUserView(true);
|
|
setIsFamilyView(false);
|
|
}}
|
|
icon={
|
|
<Ionicons
|
|
name="notifications-outline"
|
|
size={24}
|
|
color={"#ffa200"}
|
|
/>
|
|
}
|
|
/>
|
|
</View>
|
|
</View>
|
|
<Button
|
|
onPress={() => {
|
|
props.navigation.navigate("settings");
|
|
setPageIndex(0);
|
|
setToDosIndex(0);
|
|
setUserView(true);
|
|
setIsFamilyView(false);
|
|
}}
|
|
label={"Manage Settings"}
|
|
labelStyle={styles.label}
|
|
iconSource={() => (
|
|
<View
|
|
backgroundColor="#ededed"
|
|
width={60}
|
|
height={60}
|
|
style={{ borderRadius: 50 }}
|
|
marginR-10
|
|
centerV
|
|
centerH
|
|
>
|
|
<NavSettingsIcon />
|
|
</View>
|
|
)}
|
|
backgroundColor="white"
|
|
color="#464039"
|
|
paddingV-30
|
|
marginH-30
|
|
borderRadius={18.55}
|
|
style={{ elevation: 0 }}
|
|
/>
|
|
|
|
<Button
|
|
size={ButtonSize.large}
|
|
marginH-10
|
|
marginT-12
|
|
paddingV-15
|
|
style={{
|
|
marginTop: 50,
|
|
backgroundColor: "transparent",
|
|
borderWidth: 1.3,
|
|
borderColor: "#fd1775",
|
|
}}
|
|
label="Sign out of Cally"
|
|
color="#fd1775"
|
|
labelStyle={styles.signOut}
|
|
onPress={() => signOut()}
|
|
/>
|
|
</DrawerContentScrollView>
|
|
);
|
|
}}
|
|
>
|
|
<Drawer.Screen
|
|
name="index"
|
|
options={{
|
|
drawerLabel: "Calendar",
|
|
title: "Calendar",
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="calendar"
|
|
options={{
|
|
drawerLabel: "Calendar",
|
|
title: "Calendar",
|
|
drawerItemStyle: { display: "none" },
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="brain_dump"
|
|
options={{
|
|
drawerLabel: "Brain Dump",
|
|
title: "Brain Dump",
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="settings"
|
|
options={{
|
|
drawerLabel: "Settings",
|
|
title: "Settings",
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="grocery"
|
|
options={{
|
|
drawerLabel: "Groceries",
|
|
title: "Groceries",
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="reminders"
|
|
options={{
|
|
drawerLabel: "Reminders",
|
|
title: "Reminders",
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="todos"
|
|
options={{
|
|
drawerLabel: "To-Do",
|
|
title:
|
|
Device.deviceType === DeviceType.TABLET
|
|
? "Family To Dos"
|
|
: "To Dos",
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="notifications"
|
|
options={{
|
|
drawerLabel: "Notifications",
|
|
title: "Notifications",
|
|
}}
|
|
/>
|
|
<Drawer.Screen
|
|
name="feedback"
|
|
options={{ drawerLabel: "Feedback", title: "Feedback" }}
|
|
/>
|
|
</Drawer>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
signOut: { fontFamily: "Poppins_500Medium", fontSize: 15 },
|
|
label: { fontFamily: "Poppins_400Medium", fontSize: 15 },
|
|
title: {
|
|
fontSize: 26.13,
|
|
fontFamily: "Manrope_600SemiBold",
|
|
color: "#262627",
|
|
},
|
|
});
|