Event creation

This commit is contained in:
Milan Paunovic
2024-08-26 13:42:28 +02:00
parent 64ae88a732
commit 96168316b5
22 changed files with 1129 additions and 1191 deletions

View File

@ -1,12 +1,69 @@
import React from 'react';
import {Drawer} from "expo-router/drawer";
import {useSignOut} from "@/hooks/firebase/useSignOut";
import {DrawerContentScrollView, DrawerItem, DrawerItemList} from "@react-navigation/drawer";
export default function TabLayout() {
return (
<Drawer
screenOptions={{
headerShown: true,
}}/>
);
const {mutateAsync: signOut} = useSignOut()
return (
<Drawer
initialRouteName={"index"}
screenOptions={{
headerShown: true,
}}
drawerContent={props => {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem label="Logout" 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="grocery"
options={{
drawerLabel: "Grocery",
title: "Grocery",
}}
/>
<Drawer.Screen
name="reminders"
options={{
drawerLabel: "Reminders",
title: "Reminders",
}}
/>
<Drawer.Screen
name="todos"
options={{
drawerLabel: "To-Do",
title: "To-Do",
}}
/>
</Drawer>
);
}

View File

@ -1,7 +1,123 @@
import {View} from "react-native-ui-lib";
import React, {useRef, useState} from "react";
import {LayoutChangeEvent} from "react-native";
import {Calendar} from "react-native-big-calendar";
import {Button, Picker, PickerModes, SegmentedControl, Text, View} from "react-native-ui-lib";
import {MaterialIcons} from "@expo/vector-icons";
import {AddEventDialog} from "@/components/pages/calendar/AddEventDialog";
import {useGetEvents} from "@/hooks/firebase/useGetEvents";
const modeMap = new Map([
[0, "day"],
[1, "week"],
[2, "month"]
]);
const months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
export default function Screen() {
const [calendarHeight, setCalendarHeight] = useState(0);
const [mode, setMode] = useState<"week" | "month" | "day">("week");
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
const calendarContainerRef = useRef(null);
const { data: events} = useGetEvents()
const onLayout = (event: LayoutChangeEvent) => {
const {height} = event.nativeEvent.layout;
setCalendarHeight(height);
};
const handleSegmentChange = (index: number) => {
const selectedMode = modeMap.get(index);
if (selectedMode) {
setMode(selectedMode as "week" | "month" | "day");
}
};
const handleMonthChange = (month: string) => {
const currentYear = selectedDate.getFullYear();
const currentDay = selectedDate.getDate();
const newMonthIndex = months.indexOf(month);
// Update the date with the new month while preserving the day and year
const updatedDate = new Date(currentYear, newMonthIndex, currentDay);
setSelectedDate(updatedDate);
};
console.log(events)
return (
<View/>
)
}
<View style={{flex: 1, height: "100%", padding: 10}}>
<View style={{height: 60, justifyContent: "space-evenly", alignItems: "flex-start"}}>
<Text>Welcome Dalia</Text>
<Text>Let's get your week started!</Text>
</View>
<View
style={{flex: 1, backgroundColor: "#fff", borderRadius: 30}}
ref={calendarContainerRef}
onLayout={onLayout}
>
<View style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingHorizontal: 10,
paddingVertical: 8,
borderRadius: 20,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
backgroundColor: "#f9f9f9",
marginBottom: 10,
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 5,
elevation: 3,
}}>
<Picker
value={months[selectedDate.getMonth()]} // Get the month from the date
placeholder={"Select Month"}
mode={PickerModes.SINGLE}
onChange={(itemValue) => handleMonthChange(itemValue as string)}
trailingAccessory={<MaterialIcons name={"keyboard-arrow-down"}/>}
>
{months.map((month) => (
<Picker.Item key={month} label={month} value={month}/>
))}
</Picker>
<View>
<SegmentedControl
segments={[
{label: "D"},
{label: "W"},
{label: "M"}
]}
onChangeIndex={handleSegmentChange}
initialIndex={[...modeMap.entries()].find(([_, value]) => value === mode)?.[0] || 1}
/>
</View>
</View>
{calendarHeight > 0 && (
<Calendar
mode={mode}
events={events ?? []}
height={calendarHeight}
activeDate={selectedDate}
onSwipeEnd={(newDate) => {
console.log(newDate)
setSelectedDate(newDate);
}}
/>
)}
</View>
<AddEventDialog/>
</View>
);
}

View File

@ -1,70 +1,3 @@
import { Image, StyleSheet, Platform } from 'react-native';
import Screen from "@/app/(auth)/calendar";
import { HelloWave } from '@/components/HelloWave';
import ParallaxScrollView from '@/components/ParallaxScrollView';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
export default function HomeScreen() {
return (
<ParallaxScrollView
headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
headerImage={
<Image
source={require('@/assets/images/partial-react-logo.png')}
style={styles.reactLogo}
/>
}>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title">Welcome!</ThemedText>
<HelloWave />
</ThemedView>
<ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 1: Try it</ThemedText>
<ThemedText>
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
Press{' '}
<ThemedText type="defaultSemiBold">
{Platform.select({ ios: 'cmd + d', android: 'cmd + m' })}
</ThemedText>{' '}
to open developer tools.
</ThemedText>
</ThemedView>
<ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 2: Explore</ThemedText>
<ThemedText>
Tap the Explore tab to learn more about what's included in this starter app.
</ThemedText>
</ThemedView>
<ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
<ThemedText>
When you're ready, run{' '}
<ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '}
<ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '}
<ThemedText type="defaultSemiBold">app</ThemedText> to{' '}
<ThemedText type="defaultSemiBold">app-example</ThemedText>.
</ThemedText>
</ThemedView>
</ParallaxScrollView>
);
}
const styles = StyleSheet.create({
titleContainer: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
stepContainer: {
gap: 8,
marginBottom: 8,
},
reactLogo: {
height: 178,
width: 290,
bottom: 0,
left: 0,
position: 'absolute',
},
});
export default Screen

View File

@ -1,5 +0,0 @@
import {Stack} from "expo-router";
export default function StackLayout () {
return <Stack screenOptions={{headerShown: false}}/>
}

View File

@ -1,50 +0,0 @@
import React, { useEffect, useState } from "react";
import { Button, TextInput } from "react-native";
import { Checkbox, Picker, TextField, View, Text } from "react-native-ui-lib";
import { useCreateSubUser } from "@/hooks/firebase/useCreateSubUser";
import { UserProfile } from "@/hooks/firebase/types/profileTypes";
import { uuidv4 } from "@firebase/util";
import { useGetChildrenByParentId } from "@/hooks/firebase/useGetChildrenByParentId";
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
import SignInPage from "../../../components/pages/main/SignInPage";
import Entry from "@/components/pages/main/Entry";
import { useSignUp } from "@/hooks/firebase/useSignUp";
import { useSignOut } from "@/hooks/firebase/useSignOut";
const Screen: React.FC = () => {
const { user, profileType, profileData } = useAuthContext();
const { data: children } = useGetChildrenByParentId();
const { mutateAsync: createSubUser } = useCreateSubUser();
const { mutateAsync: signOut } = useSignOut();
const createNewSubUser = async (userProfile: UserProfile) => {
await createSubUser({ ...userProfile, email: `${uuidv4()}@test.com` });
// createSubUser({
// email,
// password,
// userType: profileType!,
// name: "",
// contact: "+381628334",
// ...child
// })
};
return (
<View>
{user ? (
<View paddingH-20 marginT-20>
{profileType === ProfileType.PARENT && <Text>Parent</Text>}
{profileType === ProfileType.CHILD && <Text>Child</Text>}
{profileType === ProfileType.CAREGIVER && <Text>Caregiver</Text>}
<Button title="Sign Out" onPress={async() => {await signOut()}} />
</View>
) : (
<Entry />
)}
</View>
);
};
export default Screen;

View File

@ -0,0 +1,5 @@
import {Stack} from "expo-router";
export default function Layout() {
return <Stack screenOptions={{title: "Login"}}/>
}

7
app/(unauth)/index.tsx Normal file
View File

@ -0,0 +1,7 @@
import Entry from "@/components/pages/main/Entry";
export default function Screen() {
return (
<Entry/>
)
}

View File

View File

@ -1,15 +1,16 @@
import { Link, Stack } from 'expo-router';
import {Link, Stack, usePathname} from 'expo-router';
import { StyleSheet } from 'react-native';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
export default function NotFoundScreen() {
const route = usePathname()
return (
<>
<Stack.Screen options={{ title: 'Oops!' }} />
<ThemedView style={styles.container}>
<ThemedText type="title">This screen doesn't exist.</ThemedText>
<ThemedText type="title">This screen doesn't exist. ({route})</ThemedText>
<Link href="/" style={styles.link}>
<ThemedText type="link">Go to home screen!</ThemedText>
</Link>

View File

@ -0,0 +1,89 @@
import React, {useState} from "react";
import {MaterialIcons} from "@expo/vector-icons";
import {Button, Card, Dialog, PanningProvider, Text, View} from "react-native-ui-lib";
import {TouchableOpacity} from "react-native";
import {ManuallyAddEventModal} from "@/components/pages/calendar/ManuallyAddEventModal";
export const AddEventDialog = () => {
const [show, setShow] = useState(false);
const [showManualInputModal, setShowManualInputModal] = useState(false);
const handleOpenManualInputModal = () => {
setShow(false);
setTimeout(() => {
setShowManualInputModal(true);
}, 500);
};
return (
<>
<Button
style={{
position: "absolute",
bottom: 20,
right: 20,
height: 60,
width: 60,
borderRadius: 30,
backgroundColor: "#fff",
alignItems: 'center',
justifyContent: 'center',
}}
enableShadow
iconSource={() => <MaterialIcons name="add" size={30}/>}
onPress={() => setShow(true)}
/>
<Dialog
visible={show}
onDismiss={() => setShow(false)}
panDirection={PanningProvider.Directions.DOWN}
center
>
<Card style={{padding: 20, justifyContent: 'center', alignItems: "center"}}>
<Text text60>Create a new event</Text>
<View style={{marginTop: 20, alignItems: 'center'}}>
<Button
style={{
marginBottom: 10,
backgroundColor: "#007bff",
}}
onPress={handleOpenManualInputModal}
>
<Text style={{color: "white"}}>Manually Input</Text>
</Button>
<Button
style={{
marginBottom: 10,
backgroundColor: "#007bff",
opacity: 0.5
}}
disabled
>
<Text style={{color: "white"}}>Scan an Image</Text>
</Button>
<Button
style={{
marginBottom: 10,
backgroundColor: "#007bff",
opacity: 0.5
}}
disabled
>
<Text style={{color: "white"}}>Paste in text</Text>
</Button>
</View>
<TouchableOpacity onPress={() => setShow(false)}>
<Text style={{marginTop: 20, color: "#007bff"}}>Go back</Text>
</TouchableOpacity>
</Card>
</Dialog>
<ManuallyAddEventModal show={showManualInputModal} close={() => setShowManualInputModal(false)}/>
</>
)
}

View File

@ -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<string>("");
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<PickerMultiValue>([]);
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<EventData> = {
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 (
<Modal
visible={show}
animationType="slide"
onRequestClose={close}
transparent={false}
>
<LoaderScreen message={'Saving event...'} color={Colors.grey40}/>
</Modal>
)
}
return (
<Modal
visible={show}
animationType="slide"
onRequestClose={close}
transparent={false}
>
<View style={{
flex: 1,
backgroundColor: "#fff",
paddingTop: insets.top, // Safe area inset for top
paddingBottom: insets.bottom, // Safe area inset for bottom
paddingLeft: insets.left, // Safe area inset for left
paddingRight: insets.right, // Safe area inset for right
}}>
<View style={{flexDirection: "row", justifyContent: "space-between", padding: 16}}>
<TouchableOpacity onPress={close}>
<Text style={{color: "#007bff"}}>Cancel</Text>
</TouchableOpacity>
<Text style={{fontWeight: "bold", fontSize: 16}}>Add event</Text>
<TouchableOpacity onPress={handleSave}>
<Text style={{color: "#007bff"}}>Save</Text>
</TouchableOpacity>
</View>
<ScrollView contentContainerStyle={{paddingHorizontal: 16, paddingTop: 10}}>
<View style={{marginVertical: 10}}>
<TextField
placeholder={'Title'}
floatingPlaceholder
value={title}
onChangeText={setTitle}
showCharCounter
maxLength={200}
fieldStyle={{
borderBottomWidth: 1,
borderBottomColor: 'black',
borderStyle: 'solid',
}}
/>
</View>
<View style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: 20
}}>
<View style={{flexDirection: "row", alignItems: "center"}}>
<MaterialIcons name="schedule" size={24} color="gray"/>
<Text style={{marginLeft: 10}}>All-day</Text>
</View>
<Switch
value={isAllDay}
onValueChange={(value) => setIsAllDay(value)}
/>
</View>
<View style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: 20
}}>
<DateTimePicker
mode="date"
dateFormatter={formatDateTime}
value={startDate}
onChange={setStartDate}
/>
{!isAllDay && (
<DateTimePicker
mode="time"
value={startTime}
onChange={setStartTime}
/>
)}
</View>
{!isAllDay && (
<View style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: 20
}}>
<DateTimePicker
mode="date"
dateFormatter={formatDateTime}
value={endDate}
onChange={setEndDate}
/>
<DateTimePicker
mode="time"
value={endTime}
onChange={setEndTime}
/>
</View>
)}
<View style={{flexDirection: "row", alignItems: "center", marginBottom: 20}}>
<MaterialIcons name="repeat" size={24} color="gray"/>
<Picker
value={repeatInterval}
//@ts-ignore
onChange={(items: PickerMultiValue) => setRepeatInterval(items)}
placeholder="Doest not repeat"
style={{marginLeft: 10, flex: 1}}
mode={Picker.modes.MULTI}
getLabel={getRepeatLabel}
>
{daysOfWeek.map((option) => (
<Picker.Item key={option.value} label={option.label} value={option.value}/>
))}
</Picker>
</View>
<View style={{flexDirection: "row", alignItems: "center", marginBottom: 20}}>
<MaterialIcons name="person-add" size={24} color="gray"/>
<TouchableOpacity style={{marginLeft: 10, flexDirection: "row", alignItems: "center", flex: 1}}>
<Avatar size={40} backgroundColor={Colors.yellow10}/>
<View style={{marginLeft: 10}}>
<Text>Other</Text>
<Text style={{color: "gray"}}>{user?.email}</Text>
</View>
</TouchableOpacity>
</View>
</ScrollView>
</View>
</Modal>
);
};

View File

@ -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<string>("");
const [password, setPassword] = useState<string>("");
const SignInPage = (props: { setRegister: () => any }) => {
const [email, setEmail] = useState<string>("");
const [password, setPassword] = useState<string>("");
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 (
<View marginH-20>
<TextInput placeholder="Email" value={email} onChangeText={setEmail} />
<TextInput
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<Button label="Login" onPress={handleSignIn} />
<Text>Don't have an account?</Text>
<Button
onPress={props.setRegister}
label="Sign Up"
link
padding-0
margin-0
left
/>
</View>
);
return (
<View padding-10>
<TextField
placeholder="Email"
value={email}
onChangeText={setEmail}
style={{ marginBottom: 10 }}
floatingPlaceholder
/>
<TextField
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
style={{ marginBottom: 10 }}
floatingPlaceholder
/>
<Button label="Login" onPress={handleSignIn} style={{ marginBottom: 20 }} />
{isError && (
<Text center style={{ marginBottom: 20 }}>{`${error}`}</Text>
)}
<Text center style={{ marginBottom: 5 }}>Don't have an account?</Text>
<Button
onPress={props.setRegister}
label="Sign Up"
link
padding-0
margin-0
left
/>
</View>
);
};
export default SignInPage;

View File

@ -1,83 +1,96 @@
import { TextInput } from "react-native";
import React, { useState } from "react";
import { Checkbox, Button, View, Text } from "react-native-ui-lib";
import {Checkbox, Button, View, Text, TextField} from "react-native-ui-lib";
import { useSignUp } from "@/hooks/firebase/useSignUp";
import { ProfileType } from "@/contexts/AuthContext";
const SignUpPage = (props: { unsetRegister: () => any }) => {
const [email, setEmail] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [isParent, setIsParent] = useState<boolean>(true);
const [isChild, setIsChild] = useState<boolean>(false);
const [isCaregiver, setIsCaregiver] = useState<boolean>(false);
const [profileType, setProfileType] = useState<ProfileType>(
ProfileType.PARENT
);
const { mutateAsync: signUp } = useSignUp();
const [email, setEmail] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [isParent, setIsParent] = useState<boolean>(true);
const [isChild, setIsChild] = useState<boolean>(false);
const [isCaregiver, setIsCaregiver] = useState<boolean>(false);
const [profileType, setProfileType] = useState<ProfileType>(
ProfileType.PARENT
);
const { mutateAsync: signUp } = useSignUp();
const handleSignUp = async () => {
await signUp({ email, password });
};
const handleSignUp = async () => {
await signUp({ email, password });
};
return (
<View marginH-20>
<TextInput placeholder="Email" value={email} onChangeText={setEmail} />
<TextInput
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<Button label="Register" onPress={handleSignUp} />
<Text>Choose Profile Type:</Text>
<Checkbox
label="Parent"
value={isParent}
onValueChange={(value) => {
setIsParent(value);
setProfileType(ProfileType.PARENT);
if (value) {
setIsChild(false);
setIsCaregiver(false);
}
}}
/>
<Checkbox
label="Child"
value={isChild}
onValueChange={(value) => {
setIsChild(value);
setProfileType(ProfileType.CHILD);
if (value) {
setIsParent(false);
setIsCaregiver(false);
}
}}
/>
<Checkbox
label="Caregiver"
value={isCaregiver}
onValueChange={(value) => {
setIsCaregiver(value);
setProfileType(ProfileType.CAREGIVER);
if (value) {
setIsParent(false);
setIsChild(false);
}
}}
/>
<Text>
Already have an account?
<Button
label="Sign In"
margin-0
link
text200
onPress={props.unsetRegister}
/>
</Text>
</View>
);
return (
<View padding-10>
<TextField
placeholder="Email"
value={email}
onChangeText={setEmail}
style={{ marginBottom: 10 }}
floatingPlaceholder
/>
<TextField
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
style={{ marginBottom: 10 }}
floatingPlaceholder
/>
<Button
label="Register"
onPress={handleSignUp}
style={{ marginBottom: 10 }}
/>
<Text style={{ marginBottom: 10 }}>Choose Profile Type:</Text>
<Checkbox
label="Parent"
value={isParent}
onValueChange={(value) => {
setIsParent(value);
setProfileType(ProfileType.PARENT);
if (value) {
setIsChild(false);
setIsCaregiver(false);
}
}}
style={{ marginBottom: 10 }}
/>
<Checkbox
label="Child"
value={isChild}
onValueChange={(value) => {
setIsChild(value);
setProfileType(ProfileType.CHILD);
if (value) {
setIsParent(false);
setIsCaregiver(false);
}
}}
style={{ marginBottom: 10 }}
/>
<Checkbox
label="Caregiver"
value={isCaregiver}
onValueChange={(value) => {
setIsCaregiver(value);
setProfileType(ProfileType.CAREGIVER);
if (value) {
setIsParent(false);
setIsChild(false);
}
}}
/>
<Text center style={{ marginBottom: 5, marginTop: 10 }}>
Already have an account?
</Text>
<Button
label="Sign In"
margin-0
link
text200
onPress={props.unsetRegister}
/>
</View>
);
};
export default SignUpPage;

View File

@ -67,7 +67,7 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) =>
useEffect(() => {
if (ready && user) {
replace({pathname: "/(auth)"})
replace({pathname: "/(auth)/calendar"})
} else if (ready && !user) {
replace({pathname: "/(unauth)"})
}

View File

@ -0,0 +1,13 @@
export interface EventData {
title: string,
startDate: Date,
endDate: Date,
allDay: boolean,
repeatDays: string[],
creatorId: string[],
userIds: string[],
timeZone?: string,
surpriseEvent?: boolean,
notes?: string,
reminders?: string[]
}

View File

@ -0,0 +1,25 @@
import {useAuthContext} from "@/contexts/AuthContext";
import {useMutation, useQueryClient} from "react-query";
import firestore from "@react-native-firebase/firestore";
import {EventData} from "@/hooks/firebase/types/eventData";
export const useCreateEvent = () => {
const {user: currentUser} = useAuthContext()
const queryClients = useQueryClient()
return useMutation({
mutationKey: ["createEvent"],
mutationFn: async (eventData: Partial<EventData>) => {
try {
await firestore()
.collection("Events")
.add({...eventData, creatorId: currentUser?.uid})
} catch (e) {
console.error(e)
}
},
onSuccess: () => {
queryClients.invalidateQueries("events")
}
})
}

View File

@ -0,0 +1,31 @@
import {useQuery} from "react-query";
import firestore from "@react-native-firebase/firestore";
import {ReactElement} from "react";
import {useAuthContext} from "@/contexts/AuthContext";
import {ICalendarEventBase} from "react-native-big-calendar";
export const useGetEvents = () => {
const {user} = useAuthContext()
return useQuery({
queryKey: ["events", user?.uid],
queryFn: async () => {
const snapshot = await firestore()
.collection("Events")
.where("creatorId", "==", user?.uid)
.get();
const events: ICalendarEventBase[] = snapshot.docs.map((doc) => {
const data = doc.data();
return {
title: data.title,
start: new Date(data.startDate.seconds * 1000),
end: new Date(data.endDate.seconds * 1000),
hideHours: data.allDay,
};
});
return events;
}
})
}

View File

@ -14,18 +14,12 @@ export const useUpdateUserData = () => {
if (user) {
try {
console.log("yall don't even");
console.log(newUserData)
await firestore()
.collection("Profiles")
.doc(user.uid)
.set(newUserData);
console.log("wtf")
const profileData = await firestore().collection("Profiles").doc(user?.uid!).get()
console.log("wtf222")
console.log(profileData)
setProfileData(profileData.data() as UserProfile)
} catch (e) {
console.error(e)

View File

@ -959,18 +959,18 @@ PODS:
- EXJSONUtils (0.13.1)
- EXManifests (0.14.3):
- ExpoModulesCore
- Expo (51.0.29):
- Expo (51.0.30):
- ExpoModulesCore
- expo-dev-client (4.0.23):
- expo-dev-client (4.0.24):
- EXManifests
- expo-dev-launcher
- expo-dev-menu
- expo-dev-menu-interface
- EXUpdatesInterface
- expo-dev-launcher (4.0.25):
- expo-dev-launcher (4.0.26):
- DoubleConversion
- EXManifests
- expo-dev-launcher/Main (= 4.0.25)
- expo-dev-launcher/Main (= 4.0.26)
- expo-dev-menu
- expo-dev-menu-interface
- ExpoModulesCore
@ -996,7 +996,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- expo-dev-launcher/Main (4.0.25):
- expo-dev-launcher/Main (4.0.26):
- DoubleConversion
- EXManifests
- expo-dev-launcher/Unsafe
@ -1025,7 +1025,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- expo-dev-launcher/Unsafe (4.0.25):
- expo-dev-launcher/Unsafe (4.0.26):
- DoubleConversion
- EXManifests
- expo-dev-menu
@ -1053,10 +1053,10 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- expo-dev-menu (5.0.19):
- expo-dev-menu (5.0.20):
- DoubleConversion
- expo-dev-menu/Main (= 5.0.19)
- expo-dev-menu/ReactNativeCompatibles (= 5.0.19)
- expo-dev-menu/Main (= 5.0.20)
- expo-dev-menu/ReactNativeCompatibles (= 5.0.20)
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
@ -1077,7 +1077,7 @@ PODS:
- ReactCommon/turbomodule/core
- Yoga
- expo-dev-menu-interface (1.8.3)
- expo-dev-menu/Main (5.0.19):
- expo-dev-menu/Main (5.0.20):
- DoubleConversion
- EXManifests
- expo-dev-menu-interface
@ -1103,7 +1103,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- expo-dev-menu/ReactNativeCompatibles (5.0.19):
- expo-dev-menu/ReactNativeCompatibles (5.0.20):
- DoubleConversion
- glog
- hermes-engine
@ -1124,7 +1124,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- expo-dev-menu/SafeAreaView (5.0.19):
- expo-dev-menu/SafeAreaView (5.0.20):
- DoubleConversion
- ExpoModulesCore
- glog
@ -1146,7 +1146,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- expo-dev-menu/Vendored (5.0.19):
- expo-dev-menu/Vendored (5.0.20):
- DoubleConversion
- expo-dev-menu/SafeAreaView
- glog
@ -1178,7 +1178,7 @@ PODS:
- ExpoModulesCore
- ExpoKeepAwake (13.0.2):
- ExpoModulesCore
- ExpoModulesCore (1.12.21):
- ExpoModulesCore (1.12.22):
- DoubleConversion
- glog
- hermes-engine
@ -3009,17 +3009,17 @@ SPEC CHECKSUMS:
EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59
EXJSONUtils: 30c17fd9cc364d722c0946a550dfbf1be92ef6a4
EXManifests: c1fab4c3237675e7b0299ea8df0bcb14baca4f42
Expo: 2c1f878fb356a11e8c32eb391f97eb7abfb21e55
expo-dev-client: 924e474dc9eccf507260a22c5a8301bed0497453
expo-dev-launcher: 5f27c01458fd729684cc49a345f4c9ca052f4864
expo-dev-menu: 9ff772f6918e5fdfd73f31cc7534b853925f3d47
Expo: 61b2953ad6afa979729f639c5992c182e8eb9040
expo-dev-client: 44e9bb8afbf444bc380c606475030fe8929de203
expo-dev-launcher: 012fd9aea425d902b5404e75e58d0bacf8e2542f
expo-dev-menu: 045ace71676316ecac9bff8c2ac34fa4d8ef8392
expo-dev-menu-interface: be32c09f1e03833050f0ee290dcc86b3ad0e73e4
ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875
ExpoFileSystem: 80bfe850b1f9922c16905822ecbf97acd711dc51
ExpoFont: e7f2275c10ca8573c991e007329ad6bf98086485
ExpoHead: fcb28a68ed4ba28f177394d2dfb8a0a8824cd103
ExpoKeepAwake: 3b8815d9dd1d419ee474df004021c69fdd316d08
ExpoModulesCore: 620690a98d712d142e0acce5933419b05a63214a
ExpoModulesCore: 470e4a326c045a3b78c172e3e62d922e3df52a41
ExpoSystemUI: d4f065a016cae6721b324eb659cdee4d4cf0cb26
ExpoWebBrowser: 7595ccac6938eb65b076385fd23d035db9ecdc8e
EXSplashScreen: d8b3c547b9b18a41d80c6f6b274c4c26664febd4

View File

@ -42,6 +42,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.3",
"react-native-big-calendar": "^4.14.0",
"react-native-calendars": "^1.1306.0",
"react-native-gesture-handler": "~2.16.1",
"react-native-reanimated": "~3.10.1",

1286
yarn.lock

File diff suppressed because it is too large Load Diff