ui tweaks

This commit is contained in:
ivic00
2024-09-28 20:38:20 +02:00
parent 7fa5a17e0b
commit 908eeab607
10 changed files with 371 additions and 220 deletions

View File

@ -1,125 +1,159 @@
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 {Button, Picker, PickerModes, SegmentedControl, Text, View} from "react-native-ui-lib"; import {
import {MaterialIcons} from "@expo/vector-icons"; Button,
import {AddEventDialog} from "@/components/pages/calendar/AddEventDialog"; Picker,
import {useGetEvents} from "@/hooks/firebase/useGetEvents"; 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";
import { useAuthContext } from "@/contexts/AuthContext"; import { useAuthContext } from "@/contexts/AuthContext";
import HeaderTemplate from "@/components/shared/HeaderTemplate";
import CalendarViewSwitch from "@/components/pages/calendar/CalendarViewSwitch";
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 calendarContainerRef = useRef(null); const calendarContainerRef = useRef(null);
const { data: events} = useGetEvents() const { data: events } = useGetEvents();
const onLayout = (event: LayoutChangeEvent) => { const onLayout = (event: LayoutChangeEvent) => {
const {height} = event.nativeEvent.layout; const { height } = event.nativeEvent.layout;
setCalendarHeight(height); setCalendarHeight(height);
}; };
const handleSegmentChange = (index: number) => { const handleSegmentChange = (index: number) => {
const selectedMode = modeMap.get(index); const selectedMode = modeMap.get(index);
if (selectedMode) { if (selectedMode) {
setMode(selectedMode as "week" | "month" | "day"); setMode(selectedMode as "week" | "month" | "day");
} }
}; };
const handleMonthChange = (month: string) => { const handleMonthChange = (month: string) => {
const currentYear = selectedDate.getFullYear(); const currentYear = selectedDate.getFullYear();
const currentDay = selectedDate.getDate(); const currentDay = selectedDate.getDate();
const newMonthIndex = months.indexOf(month); const newMonthIndex = months.indexOf(month);
// Update the date with the new month while preserving the day and year // Update the date with the new month while preserving the day and year
const updatedDate = new Date(currentYear, newMonthIndex, currentDay); const updatedDate = new Date(currentYear, newMonthIndex, currentDay);
setSelectedDate(updatedDate); setSelectedDate(updatedDate);
}; };
console.log(events) console.log(events);
return ( return (
<View style={{flex: 1, height: "100%", padding: 10}}> <View style={{ flex: 1, height: "100%", padding: 10 }}>
<View style={{height: 60, justifyContent: "space-evenly", alignItems: "flex-start"}}> <HeaderTemplate
<Text>Welcome {profileData?.firstName}</Text> message={"Let's get your week started!"}
<Text>Let's get your week started!</Text> isWelcome={true}
</View> />
<View <View
style={{flex: 1, backgroundColor: "#fff", borderRadius: 30}} style={{ flex: 1, backgroundColor: "#fff", borderRadius: 30 }}
ref={calendarContainerRef} ref={calendarContainerRef}
onLayout={onLayout} onLayout={onLayout}
> >
<View style={{ <View
flexDirection: "row", style={{
justifyContent: "space-between", flexDirection: "row",
alignItems: "center", justifyContent: "space-between",
paddingHorizontal: 10, alignItems: "center",
paddingVertical: 8, paddingHorizontal: 10,
borderRadius: 20, paddingVertical: 8,
borderBottomLeftRadius: 0, borderRadius: 20,
borderBottomRightRadius: 0, borderBottomLeftRadius: 0,
backgroundColor: "#f9f9f9", borderBottomRightRadius: 0,
marginBottom: 10, backgroundColor: "white",
shadowColor: "#000", marginBottom: 10,
shadowOffset: { width: 0, height: 2 }, }}
shadowOpacity: 0.1, >
shadowRadius: 5, <Picker
elevation: 3, value={months[selectedDate.getMonth()]} // Get the month from the date
}}> placeholder={"Select Month"}
<Picker mode={PickerModes.SINGLE}
value={months[selectedDate.getMonth()]} // Get the month from the date onChange={(itemValue) => handleMonthChange(itemValue as string)}
placeholder={"Select Month"} trailingAccessory={<MaterialIcons name={"keyboard-arrow-down"} />}
mode={PickerModes.SINGLE} >
onChange={(itemValue) => handleMonthChange(itemValue as string)} {months.map((month) => (
trailingAccessory={<MaterialIcons name={"keyboard-arrow-down"}/>} <Picker.Item key={month} label={month} value={month} />
> ))}
{months.map((month) => ( </Picker>
<Picker.Item key={month} label={month} value={month}/>
))}
</Picker>
<View> <View>
<SegmentedControl <SegmentedControl
segments={[ segments={[{ label: "D" }, { label: "W" }, { label: "M" }]}
{label: "D"}, backgroundColor="#ececec"
{label: "W"}, inactiveColor="#919191"
{label: "M"} activeBackgroundColor="#ea156c"
]} activeColor="white"
onChangeIndex={handleSegmentChange} outlineColor="white"
initialIndex={[...modeMap.entries()].find(([_, value]) => value === mode)?.[0] || 1} outlineWidth={3}
/> style={{ backgroundColor: "green" }}
</View> segmentLabelStyle={styles.segmentslblStyle}
</View> onChangeIndex={handleSegmentChange}
initialIndex={
{calendarHeight > 0 && ( [...modeMap.entries()].find(
<Calendar ([_, value]) => value === mode
mode={mode} )?.[0] || 1
events={events ?? []} }
height={calendarHeight} />
activeDate={selectedDate} </View>
onSwipeEnd={(newDate) => {
console.log(newDate)
setSelectedDate(newDate);
}}
/>
)}
</View>
<AddEventDialog/>
</View> </View>
);
{calendarHeight > 0 && (
<Calendar
bodyContainerStyle={styles.calHeader}
mode={mode}
events={events ?? []}
height={calendarHeight}
activeDate={selectedDate}
onSwipeEnd={(newDate) => {
console.log(newDate);
setSelectedDate(newDate);
}}
/>
)}
</View>
<CalendarViewSwitch />
<AddEventDialog />
</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

@ -22,16 +22,19 @@ export const AddEventDialog = () => {
position: "absolute", position: "absolute",
bottom: 20, bottom: 20,
right: 20, right: 20,
height: 60, height: 40,
width: 60,
borderRadius: 30, borderRadius: 30,
backgroundColor: "#fff", backgroundColor: "#fd1775",
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
}} }}
centerV
color="white"
enableShadow enableShadow
iconSource={() => <MaterialIcons name="add" size={30}/>} iconSource={() => <MaterialIcons name="add" size={22} color={'white'}/>}
onPress={() => setShow(true)} onPress={() => setShow(true)}
label="New"
text60R
/> />
<Dialog <Dialog

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

@ -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

@ -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,