mirror of
https://github.com/urosran/cally.git
synced 2025-07-17 10:35:08 +00:00
brain_dump and settings
This commit is contained in:
@ -105,10 +105,11 @@ export default function TabLayout() {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<Button
|
<Button
|
||||||
|
onPress={() => props.navigation.navigate("settings")}
|
||||||
label={"Manage Settings"}
|
label={"Manage Settings"}
|
||||||
iconSource={() => (
|
iconSource={() => (
|
||||||
<View
|
<View
|
||||||
backgroundColor='#ededed'
|
backgroundColor="#ededed"
|
||||||
width={60}
|
width={60}
|
||||||
height={60}
|
height={60}
|
||||||
style={{ borderRadius: 50 }}
|
style={{ borderRadius: 50 }}
|
||||||
@ -168,6 +169,13 @@ export default function TabLayout() {
|
|||||||
title: "Brain Dump",
|
title: "Brain Dump",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Drawer.Screen
|
||||||
|
name="settings"
|
||||||
|
options={{
|
||||||
|
drawerLabel: "Settings",
|
||||||
|
title: "Settings",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="grocery"
|
name="grocery"
|
||||||
options={{
|
options={{
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
|
import BrainDumpPage from "@/components/pages/brain_dump/BrainDumpPage";
|
||||||
|
import { BrainDumpProvider } from "@/contexts/DumpContext";
|
||||||
|
import { ScrollView } from "react-native-gesture-handler";
|
||||||
import { View } from "react-native-ui-lib";
|
import { View } from "react-native-ui-lib";
|
||||||
|
|
||||||
export default function Screen() {
|
export default function Screen() {
|
||||||
return (
|
return (
|
||||||
<View/>
|
<BrainDumpProvider>
|
||||||
)
|
<View>
|
||||||
|
<BrainDumpPage />
|
||||||
|
</View>
|
||||||
|
</BrainDumpProvider>
|
||||||
|
);
|
||||||
}
|
}
|
5
app/(auth)/settings/_layout.tsx
Normal file
5
app/(auth)/settings/_layout.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { Stack } from "expo-router";
|
||||||
|
|
||||||
|
export default function StackLayout() {
|
||||||
|
return <Stack screenOptions={{ headerShown: false }} />;
|
||||||
|
}
|
6
app/(auth)/settings/index.tsx
Normal file
6
app/(auth)/settings/index.tsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import SettingsPage from "@/components/pages/settings/SettingsPage";
|
||||||
|
import { View } from "react-native-ui-lib";
|
||||||
|
|
||||||
|
export default function Screen() {
|
||||||
|
return <SettingsPage />;
|
||||||
|
}
|
54
components/pages/brain_dump/BrainDumpPage.tsx
Normal file
54
components/pages/brain_dump/BrainDumpPage.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { ScrollView } from "react-native";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { View, Text } from "react-native-ui-lib";
|
||||||
|
import DumpList from "./DumpList";
|
||||||
|
import HeaderTemplate from "@/components/shared/HeaderTemplate";
|
||||||
|
import { TextField } from "react-native-ui-lib";
|
||||||
|
import { StyleSheet } from "react-native";
|
||||||
|
import { Feather } from "@expo/vector-icons";
|
||||||
|
import { TextInput } from "react-native-gesture-handler";
|
||||||
|
|
||||||
|
const BrainDumpPage = () => {
|
||||||
|
const [searchText, setSearchText] = useState<string>("");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<ScrollView>
|
||||||
|
<HeaderTemplate message={"Welcome to your notes!"} isWelcome={false} />
|
||||||
|
<View marginH-25>
|
||||||
|
<View style={styles.searchField} centerV>
|
||||||
|
<TextField
|
||||||
|
value={searchText}
|
||||||
|
onChangeText={(value) => {
|
||||||
|
setSearchText(value);
|
||||||
|
}}
|
||||||
|
leadingAccessory={
|
||||||
|
<Feather
|
||||||
|
name="search"
|
||||||
|
size={24}
|
||||||
|
color="#9b9b9b"
|
||||||
|
style={{ paddingRight: 10 }}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
placeholder="Search notes..."
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<DumpList searchText={searchText} />
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
searchField: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#9b9b9b",
|
||||||
|
borderRadius: 18,
|
||||||
|
height: 48,
|
||||||
|
paddingLeft: 10,
|
||||||
|
marginVertical: 20,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BrainDumpPage;
|
30
components/pages/brain_dump/DumpItem.tsx
Normal file
30
components/pages/brain_dump/DumpItem.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { View, Text } from "react-native-ui-lib";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { IBrainDump } from "@/contexts/DumpContext";
|
||||||
|
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||||
|
import MoveBrainDump from "./MoveBrainDump";
|
||||||
|
|
||||||
|
const BrainDumpItem = (props: { item: IBrainDump }) => {
|
||||||
|
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<TouchableOpacity onPress={() => setIsVisible(true)}>
|
||||||
|
<View
|
||||||
|
backgroundColor="white"
|
||||||
|
marginV-5
|
||||||
|
padding-15
|
||||||
|
style={{ borderRadius: 20, elevation: 2 }}
|
||||||
|
>
|
||||||
|
<Text text70BL marginB-8>
|
||||||
|
{props.item.title}
|
||||||
|
</Text>
|
||||||
|
<Text text80>{props.item.description}</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<MoveBrainDump item={props.item} isVisible={isVisible} setIsVisible={setIsVisible} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BrainDumpItem;
|
27
components/pages/brain_dump/DumpList.tsx
Normal file
27
components/pages/brain_dump/DumpList.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { View } from 'react-native-ui-lib';
|
||||||
|
import React from 'react';
|
||||||
|
import { useBrainDumpContext } from '@/contexts/DumpContext';
|
||||||
|
import { FlatList } from 'react-native';
|
||||||
|
import BrainDumpItem from './DumpItem';
|
||||||
|
|
||||||
|
const DumpList = (props: { searchText: string }) => {
|
||||||
|
const { brainDumps } = useBrainDumpContext();
|
||||||
|
|
||||||
|
const filteredBrainDumps = props.searchText.trim() === ""
|
||||||
|
? brainDumps
|
||||||
|
: brainDumps.filter((item) =>
|
||||||
|
item.title.toLowerCase().includes(props.searchText.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<FlatList
|
||||||
|
data={filteredBrainDumps}
|
||||||
|
keyExtractor={(item) => item.title}
|
||||||
|
renderItem={({ item }) => <BrainDumpItem key={item.title} item={item} />}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DumpList;
|
124
components/pages/brain_dump/MoveBrainDump.tsx
Normal file
124
components/pages/brain_dump/MoveBrainDump.tsx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Button, Dialog, View, Text, TextField } from "react-native-ui-lib";
|
||||||
|
import { StyleSheet } from "react-native";
|
||||||
|
import { PanningDirectionsEnum } from "react-native-ui-lib/src/incubator/panView";
|
||||||
|
import { IBrainDump } from "@/contexts/DumpContext";
|
||||||
|
import { Entypo, EvilIcons, Feather, Octicons } from "@expo/vector-icons";
|
||||||
|
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||||
|
|
||||||
|
const MoveBrainDump = (props: {
|
||||||
|
item: IBrainDump;
|
||||||
|
isVisible: boolean;
|
||||||
|
setIsVisible: (value: boolean) => void;
|
||||||
|
}) => {
|
||||||
|
const [description, setDescription] = useState<string>(
|
||||||
|
props.item.description
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
bottom={true}
|
||||||
|
height={"90%"}
|
||||||
|
panDirection={PanningDirectionsEnum.DOWN}
|
||||||
|
onDismiss={() => props.setIsVisible(false)}
|
||||||
|
containerStyle={{
|
||||||
|
borderRadius: 10,
|
||||||
|
backgroundColor: "white",
|
||||||
|
width: "100%",
|
||||||
|
alignSelf: "stretch",
|
||||||
|
padding: 0,
|
||||||
|
paddingTop: 3,
|
||||||
|
margin: 0,
|
||||||
|
}}
|
||||||
|
visible={props.isVisible}
|
||||||
|
>
|
||||||
|
<View row spread paddingH-10 paddingV-15>
|
||||||
|
<Button
|
||||||
|
color="#05a8b6"
|
||||||
|
style={styles.topBtn}
|
||||||
|
iconSource={() => <EvilIcons name="close" size={30} color="black" />}
|
||||||
|
onPress={() => {
|
||||||
|
props.setIsVisible(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
style={styles.topBtn}
|
||||||
|
iconSource={() => (
|
||||||
|
<Feather name="chevron-down" size={24} color="black" />
|
||||||
|
)}
|
||||||
|
onPress={() => {
|
||||||
|
props.setIsVisible(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View row>
|
||||||
|
<Button
|
||||||
|
style={styles.topBtn}
|
||||||
|
iconSource={() => (
|
||||||
|
<Octicons name="pencil" size={24} color="#919191" />
|
||||||
|
)}
|
||||||
|
onPress={() => {}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
style={styles.topBtn}
|
||||||
|
iconSource={() => (
|
||||||
|
<EvilIcons name="trash" size={30} color="#919191" />
|
||||||
|
)}
|
||||||
|
onPress={() => {}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View centerH>
|
||||||
|
<Text text60R>{props.item.title} </Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.divider} />
|
||||||
|
<View row marginH-20>
|
||||||
|
<Entypo
|
||||||
|
name="text"
|
||||||
|
size={24}
|
||||||
|
color="black"
|
||||||
|
style={{ marginBottom: "auto" }}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
textAlignVertical="top"
|
||||||
|
multiline
|
||||||
|
placeholder="Add description"
|
||||||
|
numberOfLines={3}
|
||||||
|
value={description}
|
||||||
|
onChangeText={(value) => {
|
||||||
|
setDescription(value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.divider} />
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default MoveBrainDump;
|
51
components/pages/settings/SettingsPage.tsx
Normal file
51
components/pages/settings/SettingsPage.tsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { View, Text, Button } from "react-native-ui-lib";
|
||||||
|
import React from "react";
|
||||||
|
import { StyleSheet } from "react-native";
|
||||||
|
import { Entypo, Ionicons, Octicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
mainBtn: { width: "100%", justifyContent: "flex-start", marginBottom: 20, height: 60 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const SettingsPage = () => {
|
||||||
|
return (
|
||||||
|
<View centerH marginH-30 marginT-30>
|
||||||
|
<Button
|
||||||
|
backgroundColor="white"
|
||||||
|
style={styles.mainBtn}
|
||||||
|
label="Manage my profile"
|
||||||
|
color="#07b8c7"
|
||||||
|
iconSource={() => (
|
||||||
|
<Ionicons name="person-circle-sharp" size={24} color="#07b8c7" style={{marginRight: 10}} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
backgroundColor="white"
|
||||||
|
style={styles.mainBtn}
|
||||||
|
label="Calendar settings"
|
||||||
|
color="#fd1775"
|
||||||
|
iconSource={() => (
|
||||||
|
<Ionicons name="home-outline" size={24} color="#fd1775" style={{marginRight: 10}} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
backgroundColor="white"
|
||||||
|
style={styles.mainBtn}
|
||||||
|
label="Chore reward settings"
|
||||||
|
color="#ff9900"
|
||||||
|
iconSource={() => (<Octicons name="gear" size={24} color="#ff9900" style={{marginRight: 10}} />)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
backgroundColor="white"
|
||||||
|
style={styles.mainBtn}
|
||||||
|
label="Kaly privacy policy"
|
||||||
|
iconSource={() => (
|
||||||
|
<Entypo name="text-document" size={24} color="#6c645b" style={{marginRight: 10}} />
|
||||||
|
)}
|
||||||
|
color="#6c645b"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SettingsPage;
|
100
contexts/DumpContext.tsx
Normal file
100
contexts/DumpContext.tsx
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||||
|
import { createContext, useContext, useState } from "react";
|
||||||
|
|
||||||
|
export interface IBrainDump {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IBrainDumpContext {
|
||||||
|
brainDumps: IBrainDump[];
|
||||||
|
updateBrainDumpItem: (id: number, changes: Partial<IBrainDump>) => void;
|
||||||
|
isAddingBrainDump: boolean;
|
||||||
|
setIsAddingBrainDump: (value: boolean) => void;
|
||||||
|
addBrainDump: (BrainDump: IBrainDump) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BrainDumpContext = createContext<IBrainDumpContext | undefined>(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
|
||||||
|
export const BrainDumpProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const [isAddingBrainDump, setIsAddingBrainDump] = useState<boolean>(false);
|
||||||
|
const [brainDumps, setBrainDumps] = useState<IBrainDump[]>([
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
title: "Favorite Weekend Activities",
|
||||||
|
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!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "What’s For Dinner",
|
||||||
|
description:
|
||||||
|
"What’s one meal you’d love to have for dinner this week? Let’s get creative with new ideas we haven’t tried yet.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "The Best Thing About Today",
|
||||||
|
description:
|
||||||
|
"What was the highlight of your day? Let’s each take a moment to share something good that happened, no matter how small.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: "A Dream Vacation Spot",
|
||||||
|
description:
|
||||||
|
"If we could go anywhere in the world right now, where would it be? Everyone pick one dream destination and tell us why.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: "Favorite Childhood Memory",
|
||||||
|
description:
|
||||||
|
"What’s a favorite memory from your childhood? Let’s take a trip down memory lane and share some of the moments that made us smile.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: "A New Family Tradition",
|
||||||
|
description:
|
||||||
|
"What’s one new tradition we could start as a family? Maybe a weekly movie night, a monthly game day, or a yearly family trip. Share your ideas!",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const addBrainDump = (BrainDump: IBrainDump) => {
|
||||||
|
setBrainDumps((prevBrainDumps) => [
|
||||||
|
...prevBrainDumps,
|
||||||
|
{
|
||||||
|
...BrainDump,
|
||||||
|
id: prevBrainDumps.length
|
||||||
|
? prevBrainDumps[prevBrainDumps.length - 1].id + 1
|
||||||
|
: 0,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateBrainDumpItem = (id: number, changes: Partial<IBrainDump>) => {
|
||||||
|
setBrainDumps((prevBrainDumps) =>
|
||||||
|
prevBrainDumps.map((BrainDump) =>
|
||||||
|
BrainDump.id === id ? { ...BrainDump, ...changes } : BrainDump
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BrainDumpContext.Provider
|
||||||
|
value={{
|
||||||
|
brainDumps,
|
||||||
|
updateBrainDumpItem,
|
||||||
|
isAddingBrainDump,
|
||||||
|
setIsAddingBrainDump,
|
||||||
|
addBrainDump,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</BrainDumpContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useBrainDumpContext = () => useContext(BrainDumpContext)!;
|
Reference in New Issue
Block a user