Merge branch 'dev'

# Conflicts:
#	app/(auth)/calendar/index.tsx
#	yarn.lock
This commit is contained in:
Milan Paunovic
2024-09-29 23:04:17 +02:00
16 changed files with 967 additions and 565 deletions

View File

@ -1,130 +1,160 @@
import React, {useRef, useState} from "react"; import React, { useRef, useState } from "react";
import {LayoutChangeEvent} from "react-native"; import { LayoutChangeEvent, StyleSheet } from "react-native";
import {Calendar} from "react-native-big-calendar"; import { Calendar } from "react-native-big-calendar";
import {Picker, PickerModes, SegmentedControl, Text, View} from "react-native-ui-lib"; import {
import {MaterialIcons} from "@expo/vector-icons"; Picker,
import {AddEventDialog} from "@/components/pages/calendar/AddEventDialog"; PickerModes,
import {useGetEvents} from "@/hooks/firebase/useGetEvents"; SegmentedControl,
import {useAuthContext} from "@/contexts/AuthContext"; 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";
import { useAuthContext } from "@/contexts/AuthContext";
import HeaderTemplate from "@/components/shared/HeaderTemplate";
import CalendarViewSwitch from "@/components/pages/calendar/CalendarViewSwitch";
import {ManuallyAddEventModal} from "@/components/pages/calendar/ManuallyAddEventModal"; import {ManuallyAddEventModal} from "@/components/pages/calendar/ManuallyAddEventModal";
const modeMap = new Map([ const modeMap = new Map([
[0, "day"], [0, "day"],
[1, "week"], [1, "week"],
[2, "month"] [2, "month"],
]); ]);
const months = [ const months = [
"January", "February", "March", "April", "May", "June", "January",
"July", "August", "September", "October", "November", "December" "February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
]; ];
export default function Screen() { export default function Screen() {
const {profileData} = useAuthContext(); const {profileData} = useAuthContext();
const [calendarHeight, setCalendarHeight] = useState(0); const [calendarHeight, setCalendarHeight] = useState(0);
const [mode, setMode] = useState<"week" | "month" | "day">("week"); const [mode, setMode] = useState<"week" | "month" | "day">("week");
const [selectedDate, setSelectedDate] = useState<Date>(new Date()); const [selectedDate, setSelectedDate] = useState<Date>(new Date());
const [selectedNewEventDate, setSelectedNewEndDate] = useState<Date | undefined>(undefined); const [selectedNewEventDate, setSelectedNewEndDate] = useState<Date | undefined>(undefined);
const calendarContainerRef = useRef(null);
const {data: events } = useGetEvents();
const calendarContainerRef = useRef(null); const onLayout = (event: LayoutChangeEvent) => {
const {data: events} = useGetEvents() const { height } = event.nativeEvent.layout;
setCalendarHeight(height);
};
const onLayout = (event: LayoutChangeEvent) => { const handleSegmentChange = (index: number) => {
const {height} = event.nativeEvent.layout; const selectedMode = modeMap.get(index);
setCalendarHeight(height); if (selectedMode) {
}; setMode(selectedMode as "day" | "week" | "month");
}
};
const handleSegmentChange = (index: number) => { const handleMonthChange = (month: string) => {
const selectedMode = modeMap.get(index); const currentYear = selectedDate.getFullYear();
if (selectedMode) { const currentDay = selectedDate.getDate();
setMode(selectedMode as "week" | "month" | "day"); const newMonthIndex = months.indexOf(month);
}
};
const handleMonthChange = (month: string) => { // Update the date with the new month while preserving the day and year
const currentYear = selectedDate.getFullYear(); const updatedDate = new Date(currentYear, newMonthIndex, currentDay);
const currentDay = selectedDate.getDate(); setSelectedDate(updatedDate);
const newMonthIndex = months.indexOf(month); };
// Update the date with the new month while preserving the day and year console.log({events});
const updatedDate = new Date(currentYear, newMonthIndex, currentDay);
setSelectedDate(updatedDate);
};
console.log({events}) return (
<View style={{ flex: 1, height: "100%", padding: 10 }}>
<HeaderTemplate
message={"Let's get your week started!"}
isWelcome={true}
/>
return ( <View
<View style={{flex: 1, height: "100%", padding: 10}}> style={{ flex: 1, backgroundColor: "#fff", borderRadius: 30 }}
<View style={{height: 60, justifyContent: "space-evenly", alignItems: "flex-start"}}> ref={calendarContainerRef}
<Text>Welcome {profileData?.firstName}</Text> onLayout={onLayout}
<Text>Let's get your week started!</Text> >
</View> <View
style={{
<View flexDirection: "row",
style={{flex: 1, backgroundColor: "#fff", borderRadius: 30}} justifyContent: "space-between",
ref={calendarContainerRef} alignItems: "center",
onLayout={onLayout} paddingHorizontal: 10,
paddingVertical: 8,
borderRadius: 20,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
backgroundColor: "white",
marginBottom: 10,
}}
>
<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"} />}
> >
<View style={{ {months.map((month) => (
flexDirection: "row", <Picker.Item key={month} label={month} value={month} />
justifyContent: "space-between", ))}
alignItems: "center", </Picker>
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> <View>
<SegmentedControl <SegmentedControl
segments={[ segments={[
{label: "D"}, {label: "D"},
{label: "W"}, {label: "W"},
{label: "M"} {label: "M"}]}
]} backgroundColor="#ececec"
inactiveColor="#919191"
activeBackgroundColor="#ea156c"
activeColor="white"
outlineColor="white"
outlineWidth={3}
style={{ backgroundColor: "green" }}
segmentLabelStyle={styles.segmentslblStyle}
onChangeIndex={handleSegmentChange} onChangeIndex={handleSegmentChange}
initialIndex={[...modeMap.entries()].find(([_, value]) => value === mode)?.[0] || 1} initialIndex={mode === "day" ? 0 : mode === "week" ? 1 : 2}
/> />
</View> </View>
</View> </View>
{calendarHeight > 0 && ( {calendarHeight > 0 && (
<Calendar <Calendar
mode={mode} bodyContainerStyle={styles.calHeader}
events={events ?? []} mode={mode}
height={calendarHeight} events={events ?? []}
activeDate={selectedDate} height={calendarHeight}
onPressCell={setSelectedNewEndDate} activeDate={selectedDate}
onPressCell={setSelectedNewEndDate}
onSwipeEnd={(newDate) => { onSwipeEnd={(newDate) => {
console.log(newDate) console.log(newDate);
setSelectedDate(newDate); setSelectedDate(newDate);
}} }}
/> />
)} )}
</View> </View>
<CalendarViewSwitch />
<AddEventDialog/> <AddEventDialog/>
<ManuallyAddEventModal key={`${selectedNewEventDate}`} initialDate={selectedNewEventDate} show={!!selectedNewEventDate} close={() => setSelectedNewEndDate(undefined)}/> <ManuallyAddEventModal key={`${selectedNewEventDate}`} initialDate={selectedNewEventDate} show={!!selectedNewEventDate} close={() => setSelectedNewEndDate(undefined)}/>
</View> </View>
); );
} }
const styles = StyleSheet.create({
segmentslblStyle: {
fontSize: 14,
},
calHeader: {
borderWidth: 0,
},
});

View File

@ -13,27 +13,35 @@ const BrainDumpPage = () => {
return ( return (
<View> <View>
<ScrollView> <ScrollView
<HeaderTemplate message={"Welcome to your notes!"} isWelcome={false} /> showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
>
<View marginH-25> <View marginH-25>
<View style={styles.searchField} centerV> <HeaderTemplate
<TextField message={"Welcome to your notes!"}
value={searchText} isWelcome={false}
onChangeText={(value) => { />
setSearchText(value); <View>
}} <View style={styles.searchField} centerV>
leadingAccessory={ <TextField
<Feather value={searchText}
name="search" onChangeText={(value) => {
size={24} setSearchText(value);
color="#9b9b9b" }}
style={{ paddingRight: 10 }} leadingAccessory={
/> <Feather
} name="search"
placeholder="Search notes..." size={24}
/> color="#9b9b9b"
style={{ paddingRight: 10 }}
/>
}
placeholder="Search notes..."
/>
</View>
<DumpList searchText={searchText} />
</View> </View>
<DumpList searchText={searchText} />
</View> </View>
</ScrollView> </ScrollView>
</View> </View>

View File

@ -1,7 +1,7 @@
import { View, Text } from "react-native-ui-lib"; import { View, Text } from "react-native-ui-lib";
import React, { useState } from "react"; import React, { useState } from "react";
import { IBrainDump } from "@/contexts/DumpContext"; import { IBrainDump } from "@/contexts/DumpContext";
import { TouchableOpacity } from "react-native-gesture-handler"; import { TouchableOpacity, TouchableWithoutFeedback } from "react-native-gesture-handler";
import MoveBrainDump from "./MoveBrainDump"; import MoveBrainDump from "./MoveBrainDump";
const BrainDumpItem = (props: { item: IBrainDump }) => { const BrainDumpItem = (props: { item: IBrainDump }) => {
@ -9,7 +9,7 @@ const BrainDumpItem = (props: { item: IBrainDump }) => {
return ( return (
<View> <View>
<TouchableOpacity onPress={() => setIsVisible(true)}> <TouchableWithoutFeedback onPress={() => setIsVisible(true)}>
<View <View
backgroundColor="white" backgroundColor="white"
marginV-5 marginV-5
@ -19,9 +19,9 @@ const BrainDumpItem = (props: { item: IBrainDump }) => {
<Text text70BL marginB-8> <Text text70BL marginB-8>
{props.item.title} {props.item.title}
</Text> </Text>
<Text text80>{props.item.description}</Text> <Text text70>{props.item.description}</Text>
</View> </View>
</TouchableOpacity> </TouchableWithoutFeedback>
<MoveBrainDump item={props.item} isVisible={isVisible} setIsVisible={setIsVisible} /> <MoveBrainDump item={props.item} isVisible={isVisible} setIsVisible={setIsVisible} />
</View> </View>
); );

View File

@ -1,100 +1,163 @@
import React, {useState} from "react"; import React, { useState } from "react";
import {MaterialIcons} from "@expo/vector-icons"; import {
import {Button, Card, Dialog, PanningProvider, Text, View} from "react-native-ui-lib"; AntDesign,
import {TouchableOpacity} from "react-native"; Feather,
import {ManuallyAddEventModal} from "@/components/pages/calendar/ManuallyAddEventModal"; MaterialCommunityIcons,
MaterialIcons,
} from "@expo/vector-icons";
import {
Button,
ButtonSize,
Card,
Dialog,
PanningProvider,
Text,
View,
} from "react-native-ui-lib";
import { TouchableOpacity } from "react-native";
import { ManuallyAddEventModal } from "@/components/pages/calendar/ManuallyAddEventModal";
import AddChore from "../todos/AddChore";
import AddChoreDialog from "../todos/AddChoreDialog";
import { ToDosContextProvider } from "@/contexts/ToDosContext";
import UploadImageDialog from "./UploadImageDialog";
export const AddEventDialog = () => { export const AddEventDialog = () => {
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const [showManualInputModal, setShowManualInputModal] = useState(false); const [showManualInputModal, setShowManualInputModal] = useState(false);
const [choreDialogVisible, setChoreDialogVisible] = useState<boolean>(false);
const [showUploadDialog, setShowUploadDialog] = useState<boolean>(false);
const handleOpenManualInputModal = () => { const handleOpenManualInputModal = () => {
setShow(false); setShow(false);
setTimeout(() => { setTimeout(() => {
setShowManualInputModal(true); setShowManualInputModal(true);
}, 500); }, 500);
}; };
return ( const handleScanImageDialog = () => {
<> setShow(false);
setTimeout(() => {
setShowUploadDialog(true);
}, 100);
}
return (
<ToDosContextProvider>
<>
<Button
style={{
position: "absolute",
bottom: 20,
right: 20,
height: 40,
borderRadius: 30,
backgroundColor: "#fd1775",
alignItems: "center",
justifyContent: "center",
}}
centerV
color="white"
enableShadow
iconSource={() => (
<MaterialIcons name="add" size={22} color={"white"} />
)}
onPress={() => setShow(true)}
label="New"
text60R
/>
<Dialog
visible={show}
onDismiss={() => setShow(false)}
panDirection={PanningProvider.Directions.DOWN}
center
>
<Card
style={{
paddingHorizontal: 40,
paddingTop: 40,
paddingBottom: 20,
justifyContent: "center",
alignItems: "center",
}}
>
<Text text50R>Create a new event</Text>
<View style={{ marginTop: 20, alignItems: "center", width: "100%" }}>
<Button <Button
style={{ style={{
position: "absolute", marginBottom: 10,
bottom: 20, backgroundColor: "#ea156c",
right: 20, justifyContent: "center",
height: 60, width: "100%",
width: 60, paddingVertical: 13,
borderRadius: 30, }}
backgroundColor: "#fff", label="Scan Image"
alignItems: 'center', onPress={handleScanImageDialog}
justifyContent: 'center', iconSource={() => (
}} <Feather
enableShadow name="camera"
iconSource={() => <MaterialIcons name="add" size={30}/>} size={21}
onPress={() => setShow(true)} style={{ marginRight: 7 }}
color="white"
/>
)}
/> />
<Dialog <Button
visible={show} style={{
onDismiss={() => setShow(false)} marginBottom: 10,
panDirection={PanningProvider.Directions.DOWN} backgroundColor: "#e28800",
center justifyContent: "center",
> width: "100%",
<Card style={{padding: 20, justifyContent: 'center', alignItems: "center"}}> paddingVertical: 13,
<Text text60>Create a new event</Text> }}
label="Create Event"
onPress={handleOpenManualInputModal}
iconSource={() => (
<MaterialCommunityIcons
name="calendar-text-outline"
size={22}
style={{ marginRight: 5 }}
color="white"
/>
)}
/>
<View style={{marginTop: 20, alignItems: 'center'}}> <Button
<Button style={{
style={{ marginBottom: 10,
marginBottom: 10, backgroundColor: "#05a8b6",
backgroundColor: "#007bff", justifyContent: "center",
}} width: "100%",
onPress={handleOpenManualInputModal} paddingVertical: 13,
> }}
<Text style={{color: "white"}}>Create New</Text> label="Add To Do"
</Button> onPress={() => setChoreDialogVisible(true)}
iconSource={() => (
<AntDesign
name="checkcircleo"
size={20}
style={{ marginRight: 7 }}
color="white"
/>
)}
/>
</View>
<Button <TouchableOpacity onPress={() => setShow(false)}>
style={{ <Text style={{ marginTop: 20, color: "#999999" }} text70>Go back to calendar</Text>
marginBottom: 10, </TouchableOpacity>
backgroundColor: "#007bff", </Card>
opacity: 0.5 </Dialog>
}} <AddChoreDialog isVisible={choreDialogVisible} setIsVisible={setChoreDialogVisible} />
disabled <ManuallyAddEventModal
> show={showManualInputModal}
<Text style={{color: "white"}}>Event</Text> close={() => setShowManualInputModal(false)}
</Button> />
<UploadImageDialog show={showUploadDialog} setShow={setShowUploadDialog} />
<Button </>
style={{ </ToDosContextProvider>
marginBottom: 10, );
backgroundColor: "#007bff", };
opacity: 0.5
}}
disabled
>
<Text style={{color: "white"}}>To Do</Text>
</Button>
<Button
style={{
marginBottom: 10,
backgroundColor: "#007bff",
opacity: 0.5
}}
disabled
>
<Text style={{color: "white"}}>Upload Image</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,74 @@
import { View, Text, Button, TouchableOpacity } from "react-native-ui-lib";
import React, { useState } from "react";
import { MaterialIcons } from "@expo/vector-icons";
import { StyleSheet } from "react-native";
const CalendarViewSwitch = () => {
const [show, setShow] = useState<boolean>(false);
const [calView, setCalView] = useState<boolean>(false);
return (
<View
row
spread
style={{
position: "absolute",
bottom: 20,
left: 20,
borderRadius: 30,
backgroundColor: "white",
alignItems: "center",
justifyContent: "center",
// iOS shadow
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84,
// Android shadow (elevation)
elevation: 6,
}}
centerV
>
<TouchableOpacity onPress={() => setCalView(true)}>
<View
centerV
centerH
height={40}
paddingH-15
style={calView ? styles.switchBtnActive : styles.switchBtn}
>
<Text color={calView ? "white" : "#a1a1a1"} text70R>
Family View
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => setCalView(false)}>
<View
centerV
centerH
height={40}
paddingH-15
style={!calView ? styles.switchBtnActive : styles.switchBtn}
>
<Text color={!calView ? "white" : "#a1a1a1"} text70R>
My View
</Text>
</View>
</TouchableOpacity>
</View>
);
};
export default CalendarViewSwitch;
const styles = StyleSheet.create({
switchBtnActive: {
backgroundColor: "#a1a1a1",
borderRadius: 50,
},
switchBtn: {
backgroundColor: "white",
borderRadius: 50,
},
});

View File

@ -0,0 +1,178 @@
import {
View,
Text,
TouchableOpacity,
Image,
Button,
ButtonSize,
} from "react-native-ui-lib";
import React, { useState } from "react";
import { Dialog, PanningProvider, Card } from "react-native-ui-lib";
import { StyleSheet } from "react-native";
import { Feather, MaterialIcons } from "@expo/vector-icons";
import * as ImagePicker from "expo-image-picker";
interface IUploadDialogProps {
show: boolean;
setShow: (value: boolean) => void;
}
const UploadImageDialog = (uploadDialogProps: IUploadDialogProps) => {
const [selectedImage, setSelectedImage] = useState<string | null>(null);
const [imageTitle, setImageTitle] = useState<string | null>(null);
const handleImagePick = async () => {
const permissionResult =
await ImagePicker.requestMediaLibraryPermissionsAsync();
if (permissionResult.granted === false) {
alert("Permission to access camera roll is required!");
return;
}
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
// Check if the user canceled the image picker
if (!result.canceled) {
setSelectedImage(result.assets[0].uri);
setImageTitle(result.assets[0].fileName || "Untitled");
}
};
return (
<Dialog
visible={uploadDialogProps.show}
onDismiss={() => uploadDialogProps.setShow(false)}
panDirection={PanningProvider.Directions.DOWN}
center
>
<Card
style={{
paddingHorizontal: 40,
paddingTop: 20,
paddingBottom: 10,
justifyContent: "center",
alignItems: "center",
}}
>
<View centerH>
<Text text60 marginB-20>
Upload an Image
</Text>
{!selectedImage && (
<TouchableOpacity onPress={handleImagePick}>
<View
style={styles.uploadImgBox}
centerV
centerH
gap-8
marginB-20
>
<MaterialIcons
name="add-photo-alternate"
size={30}
color="#fd1775"
/>
<Text color="#fd1775" text70>
Click here to upload an image
</Text>
</View>
</TouchableOpacity>
)}
{selectedImage && (
<>
<View style={styles.imageContainer} row gap-15>
<Image
source={{ uri: selectedImage }}
style={styles.selectedImage}
/>
<View style={styles.imageInfo}>
<Text style={styles.imageTitle}>{imageTitle}</Text>
</View>
<TouchableOpacity
onPress={() => {
setSelectedImage(null);
setImageTitle("");
}}
>
<Feather
name="trash"
size={22}
color="#919191"
/>
</TouchableOpacity>
</View>
<Button
style={{
marginBottom: 10,
marginTop: 20,
backgroundColor: "#ea156c",
justifyContent: "center",
paddingVertical: 13,
alignItems: "center",
}}
label="Upload Image"
onPress={() => {}}
iconSource={() => (
<Feather
name="camera"
size={21}
style={{ marginRight: 7 }}
color="white"
/>
)}
/>
</>
)}
<TouchableOpacity onPress={() => uploadDialogProps.setShow(false)}>
<Text text80 color="#999999">
Go back
</Text>
</TouchableOpacity>
</View>
</Card>
</Dialog>
);
};
export default UploadImageDialog;
const styles = StyleSheet.create({
uploadImgBox: {
backgroundColor: "#ffe8f2",
width: "100%",
aspectRatio: 1.8,
borderRadius: 20,
borderWidth: 2,
borderColor: "#fd1775",
borderStyle: "dashed",
},
selectedImage: {
width: 60,
aspectRatio: 1,
borderRadius: 10,
},
imageContainer: {
alignItems: "center",
width: "80%",
borderWidth: 1,
borderColor: "#d9d9d9",
padding: 10,
borderRadius: 13,
},
imageInfo: {
marginLeft: 10,
},
imageTitle: {
fontSize: 16,
color: "#333",
},
});

View File

@ -4,6 +4,7 @@ import {
Button, Button,
TouchableOpacity, TouchableOpacity,
Checkbox, Checkbox,
ButtonSize,
} from "react-native-ui-lib"; } from "react-native-ui-lib";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { ProfileType, useAuthContext } from "@/contexts/AuthContext"; import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
@ -15,9 +16,8 @@ import {
useGroceryContext, useGroceryContext,
} from "@/contexts/GroceryContext"; } from "@/contexts/GroceryContext";
import EditGroceryFrequency from "./EditGroceryFrequency"; import EditGroceryFrequency from "./EditGroceryFrequency";
import { TextInput } from "react-native";
import EditGroceryItem from "./EditGroceryItem"; import EditGroceryItem from "./EditGroceryItem";
import { TouchableWithoutFeedback } from "react-native-gesture-handler"; import { StyleSheet } from "react-native";
const GroceryItem = ({ const GroceryItem = ({
item, item,
@ -32,7 +32,9 @@ const GroceryItem = ({
const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false); const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false);
const [isEditingTitle, setIsEditingTitle] = useState<boolean>(false); const [isEditingTitle, setIsEditingTitle] = useState<boolean>(false);
const [newTitle, setNewTitle] = useState<string>(""); const [newTitle, setNewTitle] = useState<string>("");
const [category, setCategory] = useState<GroceryCategory>(GroceryCategory.None); const [category, setCategory] = useState<GroceryCategory>(
GroceryCategory.None
);
const handleTitleChange = (newTitle: string) => { const handleTitleChange = (newTitle: string) => {
updateGroceryItem(item.id, { title: newTitle }); updateGroceryItem(item.id, { title: newTitle });
@ -47,93 +49,124 @@ const GroceryItem = ({
}, []); }, []);
return ( return (
<ListItem <View
key={item.id} key={item.id}
style={{ borderRadius: 50, marginVertical: 5, height: 55 }} style={{ borderRadius: 18, marginVertical: 5 }}
backgroundColor="white" backgroundColor="white"
centerV centerV
padding-0 padding-0
onPress={() => {
setOpenFreqEdit(true);
}}
> >
<EditGroceryFrequency <ListItem
visible={openFreqEdit} onPress={() => {
key={item.id} setOpenFreqEdit(true);
item={item}
onClose={() => {
setOpenFreqEdit(false);
}} }}
/> >
<ListItem.Part left containerStyle={{ flex: 1, paddingStart: 20 }}> <EditGroceryFrequency
{!isEditingTitle ? ( visible={openFreqEdit}
<View> key={item.id}
<TouchableOpacity onPress={() => setIsEditingTitle(true)}> item={item}
<Text text70BL>{item.title}</Text> onClose={() => {
</TouchableOpacity> setOpenFreqEdit(false);
</View> }}
) : ( />
<ListItem.Part left containerStyle={{ flex: 1, paddingStart: 20 }}>
{!isEditingTitle ? (
<View>
<TouchableOpacity onPress={() => setIsEditingTitle(true)}>
<Text text70BL>{item.title}</Text>
</TouchableOpacity>
</View>
) : (
<EditGroceryItem <EditGroceryItem
editGrocery={{ editGrocery={{
id: item.id, id: item.id,
title: newTitle, title: newTitle,
setTitle: setNewTitle, setTitle: setNewTitle,
category:category, category: category,
updateCategory: updateGroceryItem, updateCategory: updateGroceryItem,
closeEdit: setIsEditingTitle, closeEdit: setIsEditingTitle,
setCategory: setCategory, setCategory: setCategory,
}} }}
/> />
)} )}
</ListItem.Part> </ListItem.Part>
<ListItem.Part right containerStyle={{ paddingEnd: 20 }}> <ListItem.Part right containerStyle={{ paddingEnd: item.approved ? 20 : 5 }}>
{!item.approved ? ( {!item.approved ? (
<View row> <View row >
<Button <Button
padding-0 padding-0
children={ children={
<AntDesign <AntDesign
name="check" name="check"
size={24} size={24}
style={{ style={{
color: item.approved ? "green" : "#aaaaaa", color: item.approved ? "green" : "#aaaaaa",
}} }}
/> />
}
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, { approved: true });
}}
/>
<Button
padding-0
children={
<AntDesign
name="close"
size={24}
style={{ color: item.approved ? "#aaaaaa" : "red" }}
/>
}
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, { approved: false });
}}
/>
</View>
) : (
<Checkbox
value={item.bought}
style={styles.checkbox}
onValueChange={() =>
updateGroceryItem(item.id, { bought: !item.bought })
} }
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, { approved: true });
}}
/>
<Button
padding-0
children={
<AntDesign
name="close"
size={24}
style={{ color: item.approved ? "#aaaaaa" : "red" }}
/>
}
backgroundColor="transparent"
size={Button.sizes.small}
onPress={() => {
handleItemApproved(item.id, { approved: false });
}}
/> />
)}
</ListItem.Part>
</ListItem>
{!item.approved && (
<View>
<View centerH>
<View height={1} backgroundColor="#e7e7e7" width={"90%"} />
</View> </View>
) : ( <View paddingL-10 paddingV-15 flexS row centerV>
<Checkbox <View
value={item.bought} style={{
color={"#f58749"} width: 25,
onValueChange={() => aspectRatio: 1,
updateGroceryItem(item.id, { bought: !item.bought }) borderRadius: 50,
} backgroundColor: "red",
/> marginHorizontal: 10,
)} }}
</ListItem.Part> ></View>
</ListItem> <Text color="#858585" text70>Requested by Austin</Text>
</View>
</View>
)}
</View>
); );
}; };
const styles = StyleSheet.create({
checkbox:{
borderRadius: 50,
borderWidth: 1,
color: "#bfbfbf",
borderColor: "#bfbfbf",
}
})
export default GroceryItem; export default GroceryItem;

View File

@ -83,7 +83,7 @@ const GroceryList = () => {
message={"Welcome to your grocery list"} message={"Welcome to your grocery list"}
isWelcome={false} isWelcome={false}
> >
<View row spread> <View row spread gap-5>
<View <View
backgroundColor="#e2eed8" backgroundColor="#e2eed8"
padding-8 padding-8

View File

@ -63,7 +63,7 @@ const SettingsPage = () => {
<Button <Button
backgroundColor="white" backgroundColor="white"
style={styles.mainBtn} style={styles.mainBtn}
label="Chore reward settings" label="To Do reward settings"
color="#ff9900" color="#ff9900"
iconSource={() => ( iconSource={() => (
<Octicons <Octicons

View File

@ -21,27 +21,13 @@ import { PanningDirectionsEnum } from "react-native-ui-lib/src/components/pannin
import { repeatOptions, useToDosContext } from "@/contexts/ToDosContext"; import { repeatOptions, useToDosContext } from "@/contexts/ToDosContext";
import { setDate } from "date-fns"; import { setDate } from "date-fns";
import PointsSlider from "@/components/shared/PointsSlider"; import PointsSlider from "@/components/shared/PointsSlider";
import AddChoreDialog from "./AddChoreDialog";
const AddChore = () => { const AddChore = () => {
const { addToDo, toDos } = useToDosContext();
const [isVisible, setIsVisible] = useState<boolean>(false); const [isVisible, setIsVisible] = useState<boolean>(false);
const [newTitle, setNewTitle] = useState<string>("");
const [points, setPoints] = useState<number>(10);
const [choreDate, setChoreDate] = useState<Date | null>(new Date());
const [rotate, setRotate] = useState<boolean>(false);
const [repeatType, setRepeatType] = useState<string>("Every week");
const handleChange = (text: string) => {
const numericValue = parseInt(text, 10);
if (!isNaN(numericValue) && numericValue >= 0 && numericValue <= 100) {
setPoints(numericValue);
} else if (text === "") {
setPoints(0);
}
};
return ( return (
<LinearGradient <LinearGradient
@ -58,187 +44,11 @@ const AddChore = () => {
> >
<AntDesign name="plus" size={24} color="white" /> <AntDesign name="plus" size={24} color="white" />
<Text white text60R marginL-10> <Text white text60R marginL-10>
Create new chore Add to do
</Text> </Text>
</Button> </Button>
</View> </View>
<Dialog <AddChoreDialog isVisible={isVisible} setIsVisible={setIsVisible} />
bottom={true}
height={"90%"}
panDirection={PanningDirectionsEnum.DOWN}
onDismiss={() => setIsVisible(false)}
containerStyle={{
borderRadius: 10,
backgroundColor: "white",
width: "100%",
alignSelf: "stretch",
padding: 0,
paddingTop: 3,
margin: 0,
}}
visible={isVisible}
>
<View row spread>
<Button
color="#05a8b6"
style={styles.topBtn}
label="Cancel"
onPress={() => {
setIsVisible(false);
}}
/>
<Button
style={styles.topBtn}
iconSource={() => (
<Feather name="chevron-down" size={24} color="black" />
)}
onPress={() => {
setIsVisible(false);
}}
/>
<Button
color="#05a8b6"
style={styles.topBtn}
label="Save"
onPress={() => {
addToDo({
id: 0,
title: newTitle,
done: false,
date: choreDate,
points: points,
rotate: rotate,
repeatType: repeatType,
});
setIsVisible(false);
console.log(toDos);
}}
/>
</View>
<TextField
placeholder="Add a To Do"
value={newTitle}
onChangeText={(text) => {
setNewTitle(text);
}}
placeholderTextColor="#2d2d30"
text60R
marginT-15
marginL-30
/>
<View style={styles.divider} marginT-8 />
<View marginL-30 centerV>
<View row marginB-10>
{choreDate && (
<View row centerV>
<Feather name="calendar" size={25} color="#919191" />
<DateTimePicker
value={choreDate}
text70
marginL-8
onChange={(date) => {
setChoreDate(date);
}}
/>
</View>
)}
</View>
<View row centerV>
<AntDesign name="clockcircleo" size={24} color="#919191" />
<Picker
marginL-8
placeholder="Select Repeat Type"
value={repeatType}
onChange={(value) => {
if (value) {
if (value.toString() == "None") {
setChoreDate(null);
setRepeatType("None");
} else {
setRepeatType(value.toString());
setChoreDate(new Date());
}
}
}}
topBarProps={{ title: "Repeat" }}
style={{ marginVertical: 5 }}
>
{repeatOptions.map((option) => (
<Picker.Item
key={option.value}
label={option.label}
value={option.value}
/>
))}
</Picker>
</View>
</View>
<View style={styles.divider} />
<View marginH-30 marginB-10 row centerV>
<Ionicons name="person-circle-outline" size={28} color="#919191" />
<Text text70R marginL-10>
Assignees
</Text>
<Button
size={ButtonSize.small}
paddingH-8
iconSource={() => (
<Ionicons name="add-outline" size={20} color="#ea156c" />
)}
style={{
marginLeft: "auto",
borderRadius: 8,
backgroundColor: "#ffe8f1",
borderColor: "#ea156c",
borderWidth: 1,
}}
color="#ea156c"
label="Assign"
/>
</View>
<View row marginH-13 marginT-13>
<View
marginL-30
style={{
aspectRatio: 1,
width: 50,
backgroundColor: "red",
borderRadius: 50,
}}
/>
<View
marginL-30
style={{
aspectRatio: 1,
width: 50,
backgroundColor: "red",
borderRadius: 50,
}}
/>
</View>
<View row centerV style={styles.rotateSwitch}>
<Text text80>Take Turns</Text>
<Switch
onColor={"#ea156c"}
value={rotate}
marginL-10
onValueChange={(value) => setRotate(value)}
/>
</View>
<View style={styles.divider} />
<View marginH-30 marginB-15 row centerV>
<Ionicons name="gift-outline" size={25} color="#919191" />
<Text text70BL marginL-10>
Reward Points
</Text>
</View>
<PointsSlider
points={points}
setPoints={setPoints}
handleChange={handleChange}
/>
</Dialog>
</LinearGradient> </LinearGradient>
); );
}; };

View File

@ -0,0 +1,251 @@
import { View, Text, Button, Switch } from "react-native-ui-lib";
import React, { useState } from "react";
import PointsSlider from "@/components/shared/PointsSlider";
import { repeatOptions, useToDosContext } from "@/contexts/ToDosContext";
import { Feather, AntDesign, Ionicons } from "@expo/vector-icons";
import {
Dialog,
TextField,
DateTimePicker,
Picker,
ButtonSize,
} from "react-native-ui-lib";
import { PanningDirectionsEnum } from "react-native-ui-lib/src/incubator/panView";
import { StyleSheet } from "react-native";
interface IAddChoreDialog {
isVisible: boolean;
setIsVisible: (value: boolean) => void;
}
const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => {
const { addToDo, toDos } = useToDosContext();
const [newTitle, setNewTitle] = useState<string>("");
const [points, setPoints] = useState<number>(10);
const [choreDate, setChoreDate] = useState<Date | null>(new Date());
const [rotate, setRotate] = useState<boolean>(false);
const [repeatType, setRepeatType] = useState<string>("Every week");
const handleChange = (text: string) => {
const numericValue = parseInt(text, 10);
if (!isNaN(numericValue) && numericValue >= 0 && numericValue <= 100) {
setPoints(numericValue);
} else if (text === "") {
setPoints(0);
}
};
return (
<Dialog
bottom={true}
height={"90%"}
panDirection={PanningDirectionsEnum.DOWN}
onDismiss={() => addChoreDialogProps.setIsVisible(false)}
containerStyle={{
borderRadius: 10,
backgroundColor: "white",
width: "100%",
alignSelf: "stretch",
padding: 0,
paddingTop: 3,
margin: 0,
}}
visible={addChoreDialogProps.isVisible}
>
<View row spread>
<Button
color="#05a8b6"
style={styles.topBtn}
label="Cancel"
onPress={() => {
addChoreDialogProps.setIsVisible(false);
}}
/>
<Button
style={styles.topBtn}
iconSource={() => (
<Feather name="chevron-down" size={24} color="black" />
)}
onPress={() => {
addChoreDialogProps.setIsVisible(false);
}}
/>
<Button
color="#05a8b6"
style={styles.topBtn}
label="Save"
onPress={() => {
try {
addToDo({
id: 0,
title: newTitle,
done: false,
date: choreDate,
points: points,
rotate: rotate,
repeatType: repeatType,
});
addChoreDialogProps.setIsVisible(false);
console.log(toDos);
} catch (error) {
console.error(error)
}
}}
/>
</View>
<TextField
placeholder="Add a To Do"
value={newTitle}
onChangeText={(text) => {
setNewTitle(text);
}}
placeholderTextColor="#2d2d30"
text60R
marginT-15
marginL-30
/>
<View style={styles.divider} marginT-8 />
<View marginL-30 centerV>
<View row marginB-10>
{choreDate && (
<View row centerV>
<Feather name="calendar" size={25} color="#919191" />
<DateTimePicker
value={choreDate}
text70
marginL-8
onChange={(date) => {
setChoreDate(date);
}}
/>
</View>
)}
</View>
<View row centerV>
<AntDesign name="clockcircleo" size={24} color="#919191" />
<Picker
marginL-8
placeholder="Select Repeat Type"
value={repeatType}
onChange={(value) => {
if (value) {
if (value.toString() == "None") {
setChoreDate(null);
setRepeatType("None");
} else {
setRepeatType(value.toString());
setChoreDate(new Date());
}
}
}}
topBarProps={{ title: "Repeat" }}
style={{ marginVertical: 5 }}
>
{repeatOptions.map((option) => (
<Picker.Item
key={option.value}
label={option.label}
value={option.value}
/>
))}
</Picker>
</View>
</View>
<View style={styles.divider} />
<View marginH-30 marginB-10 row centerV>
<Ionicons name="person-circle-outline" size={28} color="#919191" />
<Text text70R marginL-10>
Assignees
</Text>
<Button
size={ButtonSize.small}
paddingH-8
iconSource={() => (
<Ionicons name="add-outline" size={20} color="#ea156c" />
)}
style={{
marginLeft: "auto",
borderRadius: 8,
backgroundColor: "#ffe8f1",
borderColor: "#ea156c",
borderWidth: 1,
}}
color="#ea156c"
label="Assign"
/>
</View>
<View row marginH-13 marginT-13>
<View
marginL-30
style={{
aspectRatio: 1,
width: 50,
backgroundColor: "red",
borderRadius: 50,
}}
/>
<View
marginL-30
style={{
aspectRatio: 1,
width: 50,
backgroundColor: "red",
borderRadius: 50,
}}
/>
</View>
<View row centerV style={styles.rotateSwitch}>
<Text text80>Take Turns</Text>
<Switch
onColor={"#ea156c"}
value={rotate}
marginL-10
onValueChange={(value) => setRotate(value)}
/>
</View>
<View style={styles.divider} />
<View marginH-30 marginB-15 row centerV>
<Ionicons name="gift-outline" size={25} color="#919191" />
<Text text70BL marginL-10>
Reward Points
</Text>
</View>
<PointsSlider
points={points}
setPoints={setPoints}
handleChange={handleChange}
/>
</Dialog>
);
};
export default AddChoreDialog;
const styles = StyleSheet.create({
divider: { height: 1, backgroundColor: "#e4e4e4", marginVertical: 15 },
gradient: {
height: "25%",
position: "absolute",
bottom: 0,
width: "100%",
},
buttonContainer: {
position: "absolute",
bottom: 25,
width: "100%",
},
button: {
backgroundColor: "rgb(253, 23, 117)",
paddingVertical: 20,
},
topBtn: {
backgroundColor: "white",
color: "#05a8b6",
},
rotateSwitch: {
marginLeft: 35,
marginBottom: 10,
marginTop: 25,
},
});

View File

@ -1,5 +1,7 @@
import React from "react"; import React from "react";
import { StyleSheet } from "react-native";
import { Button, View, Text } from "react-native-ui-lib"; import { Button, View, Text } from "react-native-ui-lib";
interface IDrawerButtonProps { interface IDrawerButtonProps {
bgColor: string; bgColor: string;
color: string; color: string;
@ -7,6 +9,7 @@ interface IDrawerButtonProps {
icon: React.ReactNode; icon: React.ReactNode;
title: string; title: string;
} }
const DrawerButton = (props: IDrawerButtonProps) => { const DrawerButton = (props: IDrawerButtonProps) => {
return ( return (
<Button <Button
@ -18,9 +21,7 @@ const DrawerButton = (props: IDrawerButtonProps) => {
iconSource={() => ( iconSource={() => (
<View <View
backgroundColor={props.bgColor} backgroundColor={props.bgColor}
width={60} style={styles.iconContainer}
height={60}
style={{ borderRadius: 50 }}
centerV centerV
centerH centerH
> >
@ -34,18 +35,16 @@ const DrawerButton = (props: IDrawerButtonProps) => {
flexDirection: "column", flexDirection: "column",
justifyContent: "space-between", justifyContent: "space-between",
paddingVertical: 15, paddingVertical: 15,
// Shadow for iOS
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.3,
shadowRadius: 10, // This will create a blurry shadow
// Shadow for Android
elevation: 1,
}} }}
></Button> ></Button>
); );
}; };
export default DrawerButton; export default DrawerButton;
const styles = StyleSheet.create({
iconContainer: {
width: '70%',
aspectRatio: 1,
borderRadius: 50,
},
});

View File

@ -10,7 +10,7 @@ const HeaderTemplate = (props: {
}) => { }) => {
const { user, profileData } = useAuthContext(); const { user, profileData } = useAuthContext();
return ( return (
<View row centerV padding-25> <View row centerV marginV-15>
<View <View
backgroundColor="pink" backgroundColor="pink"
height={65} height={65}

View File

@ -28,19 +28,19 @@ export const BrainDumpProvider: React.FC<{ children: React.ReactNode }> = ({
id: 0, id: 0,
title: "Favorite Weekend Activities", title: "Favorite Weekend Activities",
description: description:
"What's something fun we can do together this weekend? Maybe a new game, a picnic, or trying out a family recipe. Everyone share one idea!", "What's something fun we can do together this weekend? Maybe a new game, a picnic?",
}, },
{ {
id: 1, id: 1,
title: "Whats For Dinner", title: "Whats For Dinner",
description: description:
"Whats one meal youd love to have for dinner this week? Lets get creative with new ideas we havent tried yet.", "Whats one meal youd love to have for dinner this week?",
}, },
{ {
id: 2, id: 2,
title: "The Best Thing About Today", title: "The Best Thing About Today",
description: description:
"What was the highlight of your day? Lets each take a moment to share something good that happened, no matter how small.", "What was the highlight of your day? Lets each take a moment to share something!",
}, },
{ {
id: 3, id: 3,

View File

@ -45,6 +45,7 @@
"expo-constants": "~16.0.2", "expo-constants": "~16.0.2",
"expo-dev-client": "~4.0.27", "expo-dev-client": "~4.0.27",
"expo-font": "~12.0.9", "expo-font": "~12.0.9",
"expo-image-picker": "~15.0.7",
"expo-linking": "~6.3.1", "expo-linking": "~6.3.1",
"expo-router": "~3.5.20", "expo-router": "~3.5.20",
"expo-splash-screen": "~0.27.5", "expo-splash-screen": "~0.27.5",

View File

@ -4433,11 +4433,6 @@ diff-sequences@^29.6.3:
resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz"
integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==
dijkstrajs@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23"
integrity sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==
dir-glob@^3.0.1: dir-glob@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz"
@ -4823,13 +4818,6 @@ expo-asset@~10.0.10:
invariant "^2.2.4" invariant "^2.2.4"
md5-file "^3.2.3" md5-file "^3.2.3"
expo-barcode-scanner@~13.0.1:
version "13.0.1"
resolved "https://registry.yarnpkg.com/expo-barcode-scanner/-/expo-barcode-scanner-13.0.1.tgz#c7218c78f9e3d27086473a9826756bbcacd7f117"
integrity sha512-xBGLT1An2gpAMIQRTLU3oHydKohX8r8F9/ait1Fk9Vgd0GraFZbP4IiT7nHMlaw4H6E7Muucf7vXpGV6u7d4HQ==
dependencies:
expo-image-loader "~4.7.0"
expo-build-properties@~0.12.4: expo-build-properties@~0.12.4:
version "0.12.5" version "0.12.5"
resolved "https://registry.npmjs.org/expo-build-properties/-/expo-build-properties-0.12.5.tgz" resolved "https://registry.npmjs.org/expo-build-properties/-/expo-build-properties-0.12.5.tgz"
@ -4838,13 +4826,6 @@ expo-build-properties@~0.12.4:
ajv "^8.11.0" ajv "^8.11.0"
semver "^7.6.0" semver "^7.6.0"
expo-camera@~15.0.16:
version "15.0.16"
resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-15.0.16.tgz#149f25304ae7d76ae55653ca16f947e9f437c782"
integrity sha512-FLE02DMqkjwsb7IugKAqQvBe6s+TCQeb5LupO1+r//wAhBwmHncOrc6zV95ZEC2f9PTPK34nFH/s8CDGiVzIAA==
dependencies:
invariant "^2.2.4"
expo-constants@~16.0.0, expo-constants@~16.0.2: expo-constants@~16.0.0, expo-constants@~16.0.2:
version "16.0.2" version "16.0.2"
resolved "https://registry.npmjs.org/expo-constants/-/expo-constants-16.0.2.tgz" resolved "https://registry.npmjs.org/expo-constants/-/expo-constants-16.0.2.tgz"
@ -4853,24 +4834,24 @@ expo-constants@~16.0.0, expo-constants@~16.0.2:
"@expo/config" "~9.0.0" "@expo/config" "~9.0.0"
"@expo/env" "~0.3.0" "@expo/env" "~0.3.0"
expo-dev-client@~4.0.27: expo-dev-client@~4.0.21:
version "4.0.27" version "4.0.24"
resolved "https://registry.yarnpkg.com/expo-dev-client/-/expo-dev-client-4.0.27.tgz#c1589321ade3912cd66c7ef37139aba5e90c7a99" resolved "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.24.tgz"
integrity sha512-4f0eO7GTdGzYYg3qABR98Vc2iiCBA2HICh8namVAvqkcVCuh44I9lOctaAEe/932+lLugEW4+Mv29pdEHq3/FA== integrity sha512-gEaSThTH27lqz13WcDlejizh/4Ize3v6Hg0kvRT6gZYncI9nCiWfgPpMGYToS3/bM8vVr0KOvE4u0ulTnR0ucQ==
dependencies: dependencies:
expo-dev-launcher "4.0.27" expo-dev-launcher "4.0.26"
expo-dev-menu "5.0.21" expo-dev-menu "5.0.20"
expo-dev-menu-interface "1.8.3" expo-dev-menu-interface "1.8.3"
expo-manifests "~0.14.0" expo-manifests "~0.14.0"
expo-updates-interface "~0.16.2" expo-updates-interface "~0.16.2"
expo-dev-launcher@4.0.27: expo-dev-launcher@4.0.26:
version "4.0.27" version "4.0.26"
resolved "https://registry.yarnpkg.com/expo-dev-launcher/-/expo-dev-launcher-4.0.27.tgz#77261eb3f4ad2fe467b7e9adc2dd4a0e868563af" resolved "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.26.tgz"
integrity sha512-n+uUkcr5f5v5VR0sDw/sGna4aut2nTu3EiOqA0ijb8fBuelpgqYiBp2x7Su6wT6InoBHZxTBgVlyzgLNFGSdDw== integrity sha512-6BRVXgJqt4CjXKWVvVZtp5R0Ysbk/KJj/AJTRmI2tzmhra07dQQRIaC5q52QmoaCvzJ5sL/TQgQoFBamX8USAw==
dependencies: dependencies:
ajv "8.11.0" ajv "8.11.0"
expo-dev-menu "5.0.21" expo-dev-menu "5.0.20"
expo-manifests "~0.14.0" expo-manifests "~0.14.0"
resolve-from "^5.0.0" resolve-from "^5.0.0"
semver "^7.6.0" semver "^7.6.0"
@ -4880,10 +4861,10 @@ expo-dev-menu-interface@1.8.3:
resolved "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.8.3.tgz" resolved "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.8.3.tgz"
integrity sha512-QM0LRozeFT5Ek0N7XpV93M+HMdEKRLEOXn0aW5M3uoUlnqC1+PLtF3HMy3k3hMKTTE/kJ1y1Z7akH07T0lunCQ== integrity sha512-QM0LRozeFT5Ek0N7XpV93M+HMdEKRLEOXn0aW5M3uoUlnqC1+PLtF3HMy3k3hMKTTE/kJ1y1Z7akH07T0lunCQ==
expo-dev-menu@5.0.21: expo-dev-menu@5.0.20:
version "5.0.21" version "5.0.20"
resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-5.0.21.tgz#668cc923a9521e4f5c36ffd0664f5c280e154f3a" resolved "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.20.tgz"
integrity sha512-i7kOaxOeBksqgeUDvb5vb2cZIVLZhAX2rjLJNH3fBifiAWISeCBAQsKN9vAkMPQGqL9F88vjMyy14ca6Vo+fEw== integrity sha512-R6dZwgOAYNdPEWJEOgdqXZ8+cKLWMpRhRyFPjiuMlj50bVVEPEo07lPV2SAY+ybwTqntPILqUp6CHppRrHyAyA==
dependencies: dependencies:
expo-dev-menu-interface "1.8.3" expo-dev-menu-interface "1.8.3"
semver "^7.5.4" semver "^7.5.4"
@ -4905,6 +4886,13 @@ expo-image-loader@~4.7.0:
resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-4.7.0.tgz#d403106822de80bda12d644c82b7a3b7983c0f0b" resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-4.7.0.tgz#d403106822de80bda12d644c82b7a3b7983c0f0b"
integrity sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g== integrity sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g==
expo-image-picker@~15.0.7:
version "15.0.7"
resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-15.0.7.tgz#eb25abfdb03cb940f0418add3d9814439526b025"
integrity sha512-u8qiPZNfDb+ap6PJ8pq2iTO7JKX+ikAUQ0K0c7gXGliKLxoXgDdDmXxz9/6QdICTshJBJlBvI0MwY5NWu7A/uw==
dependencies:
expo-image-loader "~4.7.0"
expo-json-utils@~0.13.0: expo-json-utils@~0.13.0:
version "0.13.1" version "0.13.1"
resolved "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-0.13.1.tgz" resolved "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-0.13.1.tgz"
@ -5451,7 +5439,7 @@ fs.realpath@^1.0.0:
fsevents@^2.3.2: fsevents@^2.3.2:
version "2.3.3" version "2.3.3"
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.2: function-bind@^1.1.2:
@ -7020,7 +7008,7 @@ lighthouse-logger@^1.0.0:
lightningcss-darwin-arm64@1.19.0: lightningcss-darwin-arm64@1.19.0:
version "1.19.0" version "1.19.0"
resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz" resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz#56ab071e932f845dbb7667f44f5b78441175a343"
integrity sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg== integrity sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg==
lightningcss-darwin-x64@1.19.0: lightningcss-darwin-x64@1.19.0:
@ -7055,7 +7043,7 @@ lightningcss-linux-x64-musl@1.19.0:
lightningcss-win32-x64-msvc@1.19.0: lightningcss-win32-x64-msvc@1.19.0:
version "1.19.0" version "1.19.0"
resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz#0854dbd153035eca1396e2227c708ad43655a61c" resolved "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz"
integrity sha512-C+VuUTeSUOAaBZZOPT7Etn/agx/MatzJzGRkeV+zEABmPuntv1zihncsi+AyGmjkkzq3wVedEy7h0/4S84mUtg== integrity sha512-C+VuUTeSUOAaBZZOPT7Etn/agx/MatzJzGRkeV+zEABmPuntv1zihncsi+AyGmjkkzq3wVedEy7h0/4S84mUtg==
lightningcss@~1.19.0: lightningcss@~1.19.0:
@ -8212,11 +8200,6 @@ pngjs@^3.3.0:
resolved "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz" resolved "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
pngjs@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==
possible-typed-array-names@^1.0.0: possible-typed-array-names@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz" resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz"
@ -8302,7 +8285,7 @@ prompts@^2.0.1, prompts@^2.2.1, prompts@^2.3.2, prompts@^2.4.2:
kleur "^3.0.3" kleur "^3.0.3"
sisteransi "^1.0.5" sisteransi "^1.0.5"
prop-types@*, prop-types@15.8.1, prop-types@^15.5.10, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1: prop-types@*, prop-types@15.8.1, prop-types@^15.5.10, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1" version "15.8.1"
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -8377,15 +8360,6 @@ qrcode-terminal@0.11.0:
resolved "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz" resolved "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz"
integrity sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ== integrity sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==
qrcode@^1.5.1:
version "1.5.4"
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.4.tgz#5cb81d86eb57c675febb08cf007fff963405da88"
integrity sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==
dependencies:
dijkstrajs "^1.0.1"
pngjs "^5.0.0"
yargs "^15.3.1"
qs@6.13.0: qs@6.13.0:
version "6.13.0" version "6.13.0"
resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz" resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz"
@ -8553,15 +8527,6 @@ react-native-onboarding-swiper@^1.3.0:
dependencies: dependencies:
tinycolor2 "^1.4.1" tinycolor2 "^1.4.1"
react-native-qrcode-svg@^6.3.2:
version "6.3.2"
resolved "https://registry.yarnpkg.com/react-native-qrcode-svg/-/react-native-qrcode-svg-6.3.2.tgz#84b2bb37201589cff1ab58e7f7c884c5133fe47f"
integrity sha512-IJ0UoKd33ATm08K569SOAQx0tP/MTmSjwhIPfEfgbCUGQuU6JTfgDT7sm1TVgAwPbTuA10wwJJYgWXnnFBQ4FQ==
dependencies:
prop-types "^15.8.0"
qrcode "^1.5.1"
text-encoding "^0.7.0"
react-native-reanimated@~3.10.1: react-native-reanimated@~3.10.1:
version "3.10.1" version "3.10.1"
resolved "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.10.1.tgz" resolved "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.10.1.tgz"
@ -8613,11 +8578,6 @@ react-native-swipe-gestures@^1.0.5:
resolved "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz" resolved "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz"
integrity sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw== integrity sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw==
react-native-toast-message@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.2.1.tgz"
integrity sha512-iXFMnlxPcgKKs4bZOIl06W16m6KXMh/bAYpWLyVXlISSCdcL2+FX5WPpRP3TGQeM/u9q+j5ex48DDY+72en+Sw==
react-native-ui-lib@^7.27.0: react-native-ui-lib@^7.27.0:
version "7.29.0" version "7.29.0"
resolved "https://registry.npmjs.org/react-native-ui-lib/-/react-native-ui-lib-7.29.0.tgz" resolved "https://registry.npmjs.org/react-native-ui-lib/-/react-native-ui-lib-7.29.0.tgz"
@ -9745,11 +9705,6 @@ test-value@^2.1.0:
array-back "^1.0.3" array-back "^1.0.3"
typical "^2.6.0" typical "^2.6.0"
text-encoding@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.7.0.tgz#f895e836e45990624086601798ea98e8f36ee643"
integrity sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==
text-table@^0.2.0: text-table@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
@ -10544,7 +10499,7 @@ yargs-parser@^21.1.1:
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^15.1.0, yargs@^15.3.1: yargs@^15.1.0:
version "15.4.1" version "15.4.1"
resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz"
integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==