mirror of
https://github.com/urosran/cally.git
synced 2025-11-26 08:24:55 +00:00
add braindump
This commit is contained in:
@ -91,6 +91,9 @@ android {
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0.0"
|
||||
manifestPlaceholders = [
|
||||
appAuthRedirectScheme: "callyplanner"
|
||||
]
|
||||
}
|
||||
signingConfigs {
|
||||
debug {
|
||||
|
||||
@ -20,11 +20,11 @@ SplashScreen.preventAutoHideAsync();
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
|
||||
// if (__DEV__) {
|
||||
// functions().useEmulator('localhost', 5001);
|
||||
// firestore().useEmulator("localhost", 5471);
|
||||
// auth().useEmulator("http://localhost:9099");
|
||||
// }
|
||||
if (__DEV__) {
|
||||
functions().useEmulator('localhost', 5001);
|
||||
firestore().useEmulator("localhost", 5471);
|
||||
auth().useEmulator("http://localhost:9099");
|
||||
}
|
||||
|
||||
export default function RootLayout() {
|
||||
const [loaded] = useFonts({
|
||||
|
||||
21
assets/svgs/BinIcon.tsx
Normal file
21
assets/svgs/BinIcon.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import * as React from "react"
|
||||
import Svg, { Path } from "react-native-svg"
|
||||
|
||||
interface BinIconProps extends React.SVGProps<SVGSVGElement> {}
|
||||
const BinIcon: React.FC<BinIconProps> = (props) => (
|
||||
<Svg
|
||||
width={19}
|
||||
height={21}
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<Path
|
||||
stroke="#B7B7B7"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={1.7}
|
||||
d="m15.568 4.122-.834 12.5c-.072 1.095-.11 1.642-.345 2.057-.209.366-.523.66-.901.843-.43.208-.979.208-2.076.208H7.237c-1.097 0-1.646 0-2.076-.208a2.081 2.081 0 0 1-.9-.843c-.237-.415-.274-.962-.347-2.057l-.833-12.5M1 4.122h16.649m-4.162 0-.282-.845c-.273-.819-.41-1.228-.662-1.53a2.08 2.08 0 0 0-.835-.603C11.34 1 10.909 1 10.046 1H8.603c-.863 0-1.295 0-1.662.144a2.081 2.081 0 0 0-.835.602c-.253.303-.39.712-.662 1.53l-.282.846m6.244 4.162v7.284M7.243 8.284v7.284"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
export default BinIcon
|
||||
20
assets/svgs/PenIcon.tsx
Normal file
20
assets/svgs/PenIcon.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import * as React from "react";
|
||||
import Svg, { Path } from "react-native-svg";
|
||||
|
||||
interface PenIconProps extends React.SVGProps<SVGSVGElement> {}
|
||||
|
||||
const PenIcon: React.FC<PenIconProps> = (props) => (
|
||||
<Svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={17}
|
||||
height={19}
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<Path
|
||||
fill="#919191"
|
||||
d="M9.46 4.489a.907.907 0 1 0-1.416-1.135l1.417 1.135Zm-7.844 8.337.687.592a.835.835 0 0 0 .021-.025l-.708-.567Zm-.207.505-.906-.059v.017l.906.042Zm-.17 3.658-.906-.042c-.002.045 0 .09.004.135l.903-.093Zm.953.831.03.907c.06-.002.12-.01.18-.024l-.21-.883Zm3.63-.86.21.883.013-.003-.223-.88Zm.466-.295.7.578.008-.01-.708-.568Zm8.016-8.546a.908.908 0 0 0-1.416-1.136l1.416 1.136ZM8.048 3.353A.908.908 0 0 0 9.464 4.49L8.048 3.353Zm2.63-1.828.707.568a.942.942 0 0 0 .035-.046l-.742-.522Zm1.97-.387.581-.697a.915.915 0 0 0-.09-.067l-.49.764Zm2.707 2.253.643-.64a.941.941 0 0 0-.062-.057l-.58.697Zm-.01 1.982-.636-.648a.92.92 0 0 0-.072.08l.707.568Zm-2.457 1.61a.907.907 0 1 0 1.416 1.136l-1.416-1.136ZM9.654 3.787a.907.907 0 1 0-1.795.269l1.795-.27Zm4.064 4.663a.908.908 0 0 0-.244-1.798l.244 1.798ZM8.044 3.354.908 12.258l1.416 1.135L9.461 4.49 8.044 3.354ZM.93 12.233c-.251.291-.4.656-.426 1.04l1.812.117c-.001.01-.005.02-.012.028L.93 12.233Zm-.427 1.056-.169 3.658 1.813.084.17-3.658-1.814-.084Zm-.165 3.793a1.834 1.834 0 0 0 1.884 1.645l-.059-1.814h-.007a.02.02 0 0 1-.006-.004.02.02 0 0 1-.005-.006.018.018 0 0 1-.002-.007l-1.805.186ZM2.4 18.703l3.63-.86-.419-1.766-3.63.86.42 1.766Zm3.644-.863c.37-.094.7-.303.943-.598l-1.4-1.155a.021.021 0 0 1 .01-.006l.447 1.759Zm.95-.607 7.309-9.114-1.416-1.136-7.308 9.114 1.416 1.136ZM9.465 4.489l1.921-2.396L9.97.958 8.048 3.353 9.464 4.49Zm1.956-2.442a.544.544 0 0 1 .739-.145l.98-1.528a2.36 2.36 0 0 0-3.204.63l1.485 1.043Zm.648-.211 2.707 2.253 1.161-1.395L13.229.44l-1.16 1.395Zm2.645 2.196a.487.487 0 0 1 .143.347l1.815.01a2.303 2.303 0 0 0-.673-1.639l-1.285 1.282Zm.143.347c-.001.13-.054.255-.147.346l1.27 1.296c.44-.43.688-1.017.692-1.632l-1.816-.01Zm-.22.426-1.748 2.178 1.416 1.136 1.748-2.178-1.415-1.136Zm-6.777-.75a5.215 5.215 0 0 0 5.86 4.395l-.245-1.798a3.4 3.4 0 0 1-3.82-2.865l-1.795.269Z"
|
||||
/>
|
||||
</Svg>
|
||||
);
|
||||
export default PenIcon;
|
||||
97
components/pages/brain_dump/AddBrainDump.tsx
Normal file
97
components/pages/brain_dump/AddBrainDump.tsx
Normal file
@ -0,0 +1,97 @@
|
||||
import { View, Text, Button, TextField } from "react-native-ui-lib";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Dialog } from "react-native-ui-lib";
|
||||
import { PanningDirectionsEnum } from "react-native-ui-lib/src/incubator/panView";
|
||||
import CloseXIcon from "@/assets/svgs/CloseXIcon";
|
||||
import { StyleSheet } from "react-native";
|
||||
import DropModalIcon from "@/assets/svgs/DropModalIcon";
|
||||
import MenuIcon from "@/assets/svgs/MenuIcon";
|
||||
import { useBrainDumpContext } from "@/contexts/DumpContext";
|
||||
|
||||
interface IAddBrainDumpProps {
|
||||
isVisible: boolean;
|
||||
setIsVisible: (value: boolean) => void;
|
||||
}
|
||||
const AddBrainDump = ({
|
||||
addBrainDumpProps,
|
||||
}: {
|
||||
addBrainDumpProps: IAddBrainDumpProps;
|
||||
}) => {
|
||||
const {addBrainDump} = useBrainDumpContext();
|
||||
const [dumpTitle, setDumpTitle] = useState<string>("");
|
||||
const [dumpDesc, setDumpDesc] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
setDumpDesc("");
|
||||
setDumpTitle("");
|
||||
}, [addBrainDumpProps.isVisible]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
bottom={true}
|
||||
height={"90%"}
|
||||
panDirection={PanningDirectionsEnum.DOWN}
|
||||
onDismiss={() => addBrainDumpProps.setIsVisible(false)}
|
||||
containerStyle={{
|
||||
borderRadius: 10,
|
||||
backgroundColor: "white",
|
||||
width: "100%",
|
||||
alignSelf: "stretch",
|
||||
padding: 0,
|
||||
paddingTop: 3,
|
||||
margin: 0,
|
||||
}}
|
||||
visible={addBrainDumpProps.isVisible}
|
||||
>
|
||||
<View row spread style={styles.topBtns} marginB-20>
|
||||
<Button
|
||||
color="#05a8b6"
|
||||
label="Cancel"
|
||||
style={styles.topBtn}
|
||||
onPress={() => {
|
||||
addBrainDumpProps.setIsVisible(false);
|
||||
}}
|
||||
/>
|
||||
<DropModalIcon style={{ marginTop: 15 }} onPress={() => addBrainDumpProps.setIsVisible(false)}/>
|
||||
<Button
|
||||
color="#05a8b6"
|
||||
label="Save"
|
||||
style={styles.topBtn}
|
||||
onPress={() => {
|
||||
addBrainDump({id: 99, title: dumpTitle, description: dumpDesc})
|
||||
addBrainDumpProps.setIsVisible(false);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View marginH-20>
|
||||
<TextField
|
||||
value={dumpTitle}
|
||||
placeholder="Set Title"
|
||||
text60R
|
||||
onChangeText={(text) => {
|
||||
setDumpTitle(text);
|
||||
}}
|
||||
/>
|
||||
<View height={2} backgroundColor="#b3b3b3" width={"100%"} marginB-20/>
|
||||
<TextField
|
||||
value={dumpDesc}
|
||||
placeholder="Write Description"
|
||||
text70
|
||||
onChangeText={(text) => {
|
||||
setDumpDesc(text);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
topBtns: {},
|
||||
topBtn: {
|
||||
backgroundColor: "white",
|
||||
color: "#05a8b6",
|
||||
},
|
||||
});
|
||||
|
||||
export default AddBrainDump;
|
||||
@ -1,15 +1,17 @@
|
||||
import { ScrollView } from "react-native";
|
||||
import React, { useState } from "react";
|
||||
import { View, Text } from "react-native-ui-lib";
|
||||
import { View, Text, Button } 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 { Feather, MaterialIcons } from "@expo/vector-icons";
|
||||
import { TextInput } from "react-native-gesture-handler";
|
||||
import AddBrainDump from "./AddBrainDump";
|
||||
|
||||
const BrainDumpPage = () => {
|
||||
const [searchText, setSearchText] = useState<string>("");
|
||||
const [isAddVisible, setIsAddVisible] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<View>
|
||||
@ -44,6 +46,35 @@ const BrainDumpPage = () => {
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
<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={() => {
|
||||
setIsAddVisible(true);
|
||||
}}
|
||||
label="New"
|
||||
text60R
|
||||
/>
|
||||
<AddBrainDump
|
||||
addBrainDumpProps={{
|
||||
isVisible: isAddVisible,
|
||||
setIsVisible: setIsAddVisible,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,16 +1,21 @@
|
||||
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';
|
||||
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() === ""
|
||||
const filteredBrainDumps =
|
||||
props.searchText.trim() === ""
|
||||
? brainDumps
|
||||
: brainDumps.filter((item) =>
|
||||
item.title.toLowerCase().includes(props.searchText.toLowerCase())
|
||||
: brainDumps.filter(
|
||||
(item) =>
|
||||
item.title.toLowerCase().includes(props.searchText.toLowerCase()) ||
|
||||
item.description
|
||||
.toLowerCase()
|
||||
.includes(props.searchText.toLowerCase())
|
||||
);
|
||||
|
||||
return (
|
||||
@ -18,7 +23,9 @@ const DumpList = (props: { searchText: string }) => {
|
||||
<FlatList
|
||||
data={filteredBrainDumps}
|
||||
keyExtractor={(item) => item.title}
|
||||
renderItem={({ item }) => <BrainDumpItem key={item.title} item={item} />}
|
||||
renderItem={({ item }) => (
|
||||
<BrainDumpItem key={item.title} item={item} />
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
@ -1,19 +1,29 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, 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 { IBrainDump, useBrainDumpContext } from "@/contexts/DumpContext";
|
||||
import { Entypo, EvilIcons, Feather, Octicons } from "@expo/vector-icons";
|
||||
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||
import PenIcon from "@/assets/svgs/PenIcon";
|
||||
import BinIcon from "@/assets/svgs/BinIcon";
|
||||
import DropModalIcon from "@/assets/svgs/DropModalIcon";
|
||||
import CloseXIcon from "@/assets/svgs/CloseXIcon";
|
||||
|
||||
const MoveBrainDump = (props: {
|
||||
item: IBrainDump;
|
||||
isVisible: boolean;
|
||||
setIsVisible: (value: boolean) => void;
|
||||
}) => {
|
||||
const { updateBrainDumpItem, deleteBrainDump } = useBrainDumpContext();
|
||||
const [description, setDescription] = useState<string>(
|
||||
props.item.description
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
updateBrainDumpItem(props.item.id, { description: description });
|
||||
}, [description]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
bottom={true}
|
||||
@ -35,16 +45,14 @@ const MoveBrainDump = (props: {
|
||||
<Button
|
||||
color="#05a8b6"
|
||||
style={styles.topBtn}
|
||||
iconSource={() => <EvilIcons name="close" size={30} color="black" />}
|
||||
iconSource={() => <CloseXIcon />}
|
||||
onPress={() => {
|
||||
props.setIsVisible(false);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
style={styles.topBtn}
|
||||
iconSource={() => (
|
||||
<Feather name="chevron-down" size={24} color="black" />
|
||||
)}
|
||||
iconSource={() => <DropModalIcon />}
|
||||
onPress={() => {
|
||||
props.setIsVisible(false);
|
||||
}}
|
||||
@ -52,17 +60,19 @@ const MoveBrainDump = (props: {
|
||||
<View row>
|
||||
<Button
|
||||
style={styles.topBtn}
|
||||
iconSource={() => (
|
||||
<Octicons name="pencil" size={24} color="#919191" />
|
||||
)}
|
||||
onPress={() => {}}
|
||||
iconSource={() => <PenIcon />}
|
||||
onPress={() => {
|
||||
console.log("selview");
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
style={styles.topBtn}
|
||||
iconSource={() => (
|
||||
<EvilIcons name="trash" size={30} color="#919191" />
|
||||
)}
|
||||
onPress={() => {}}
|
||||
marginL-5
|
||||
iconSource={() => <BinIcon />}
|
||||
onPress={() => {
|
||||
deleteBrainDump(props.item.id);
|
||||
props.setIsVisible(false);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
import {AntDesign, Ionicons} from "@expo/vector-icons";
|
||||
import React, {useCallback, useState} from "react";
|
||||
import {Button, Checkbox, Text, View} from "react-native-ui-lib";
|
||||
import {ScrollView, StyleSheet} from "react-native";
|
||||
import {colorMap} from "@/contexts/SettingsContext";
|
||||
import {TouchableOpacity} from "react-native-gesture-handler";
|
||||
import {fetchGoogleCalendarEvents} from "@/calendar-integration/google-calendar-utils";
|
||||
import {fetchMicrosoftCalendarEvents} from "@/calendar-integration/microsoft-calendar-utils";
|
||||
import {useCreateEventFromProvider} from "@/hooks/firebase/useCreateEvent";
|
||||
import {useAuthContext} from "@/contexts/AuthContext";
|
||||
import {useUpdateUserData} from "@/hooks/firebase/useUpdateUserData";
|
||||
import {GoogleSignin} from "@react-native-google-signin/google-signin";
|
||||
import { AntDesign, Ionicons } from "@expo/vector-icons";
|
||||
import React, { useCallback, useState } from "react";
|
||||
import { Button, Checkbox, Text, View } from "react-native-ui-lib";
|
||||
import { ScrollView, StyleSheet } from "react-native";
|
||||
import { colorMap } from "@/contexts/SettingsContext";
|
||||
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||
import { fetchGoogleCalendarEvents } from "@/calendar-integration/google-calendar-utils";
|
||||
import { fetchMicrosoftCalendarEvents } from "@/calendar-integration/microsoft-calendar-utils";
|
||||
import { useCreateEventFromProvider } from "@/hooks/firebase/useCreateEvent";
|
||||
import { useAuthContext } from "@/contexts/AuthContext";
|
||||
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
|
||||
import { GoogleSignin } from "@react-native-google-signin/google-signin";
|
||||
import * as AuthSession from "expo-auth-session";
|
||||
import debounce from "debounce";
|
||||
import AppleIcon from "@/assets/svgs/AppleIcon";
|
||||
import GoogleIcon from "@/assets/svgs/GoogleIcon";
|
||||
import OutlookIcon from "@/assets/svgs/OutlookIcon";
|
||||
|
||||
GoogleSignin.configure({
|
||||
webClientId:
|
||||
@ -25,7 +28,7 @@ const GoogleLogin = async () => {
|
||||
|
||||
const microsoftConfig = {
|
||||
clientId: "13c79071-1066-40a9-9f71-b8c4b138b4af", // Replace with your Microsoft client ID
|
||||
redirectUri: AuthSession.makeRedirectUri({path: "settings"}), // Generate redirect URI automatically for Expo
|
||||
redirectUri: AuthSession.makeRedirectUri({ path: "settings" }), // Generate redirect URI automatically for Expo
|
||||
scopes: [
|
||||
"openid",
|
||||
"profile",
|
||||
@ -35,20 +38,24 @@ const microsoftConfig = {
|
||||
],
|
||||
authorizationEndpoint:
|
||||
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
||||
tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token"
|
||||
tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
||||
};
|
||||
|
||||
const CalendarSettingsPage = (props: {
|
||||
setSelectedPage: (page: number) => void;
|
||||
}) => {
|
||||
const [startDate, setStartDate] = useState<boolean>(true);
|
||||
const {profileData} = useAuthContext();
|
||||
const [startDate, setStartDate] = useState<boolean>(false);
|
||||
const { profileData } = useAuthContext();
|
||||
|
||||
const [selectedColor, setSelectedColor] = useState<string>(profileData?.eventColor ?? colorMap.pink);
|
||||
const [previousSelectedColor, setPreviousSelectedColor] = useState<string>(profileData?.eventColor ?? colorMap.pink);
|
||||
const [selectedColor, setSelectedColor] = useState<string>(
|
||||
profileData?.eventColor ?? colorMap.pink
|
||||
);
|
||||
const [previousSelectedColor, setPreviousSelectedColor] = useState<string>(
|
||||
profileData?.eventColor ?? colorMap.pink
|
||||
);
|
||||
|
||||
const {mutateAsync: createEventFromProvider} = useCreateEventFromProvider();
|
||||
const {mutateAsync: updateUserData} = useUpdateUserData();
|
||||
const { mutateAsync: createEventFromProvider } = useCreateEventFromProvider();
|
||||
const { mutateAsync: updateUserData } = useUpdateUserData();
|
||||
|
||||
const fetchAndSaveGoogleEvents = () => {
|
||||
const timeMin = new Date(new Date().setHours(0, 0, 0, 0));
|
||||
@ -59,7 +66,7 @@ const CalendarSettingsPage = (props: {
|
||||
fetchGoogleCalendarEvents(
|
||||
profileData?.googleToken,
|
||||
timeMin.toISOString().slice(0, -5) + "Z",
|
||||
timeMax.toISOString().slice(0, -5) + "Z",
|
||||
timeMax.toISOString().slice(0, -5) + "Z"
|
||||
).then((response) => {
|
||||
response?.forEach((item) => saveData(item));
|
||||
});
|
||||
@ -77,13 +84,12 @@ const CalendarSettingsPage = (props: {
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
fetchMicrosoftCalendarEvents(
|
||||
profileData?.microsoftToken,
|
||||
startDateTime.toISOString().slice(0, -5) + "Z",
|
||||
endDateTime.toISOString().slice(0, -5) + "Z"
|
||||
).then((response) => {
|
||||
console.log(response)
|
||||
console.log(response);
|
||||
response?.forEach((item) => saveData(item));
|
||||
});
|
||||
};
|
||||
@ -96,7 +102,7 @@ const CalendarSettingsPage = (props: {
|
||||
let idToken = googleUserData?.idToken;
|
||||
|
||||
if (idToken) {
|
||||
await updateUserData({newUserData: {googleToken: idToken}});
|
||||
await updateUserData({ newUserData: { googleToken: idToken } });
|
||||
}
|
||||
}
|
||||
} catch (apiError) {
|
||||
@ -134,14 +140,17 @@ const CalendarSettingsPage = (props: {
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: `client_id=${microsoftConfig.clientId}&redirect_uri=${encodeURIComponent(
|
||||
body: `client_id=${
|
||||
microsoftConfig.clientId
|
||||
}&redirect_uri=${encodeURIComponent(
|
||||
microsoftConfig.redirectUri
|
||||
)}&grant_type=authorization_code&code=${code}&code_verifier=${
|
||||
authRequest.codeVerifier
|
||||
}&scope=${encodeURIComponent("https://graph.microsoft.com/Calendars.ReadWrite offline_access")}`,
|
||||
}&scope=${encodeURIComponent(
|
||||
"https://graph.microsoft.com/Calendars.ReadWrite offline_access"
|
||||
)}`,
|
||||
});
|
||||
|
||||
|
||||
console.log("Token response status:", tokenResponse.status);
|
||||
|
||||
if (!tokenResponse.ok) {
|
||||
@ -154,7 +163,9 @@ const CalendarSettingsPage = (props: {
|
||||
|
||||
if (tokenData?.id_token) {
|
||||
console.log("ID token received, updating user data...");
|
||||
await updateUserData({newUserData: {microsoftToken: tokenData.access_token}});
|
||||
await updateUserData({
|
||||
newUserData: { microsoftToken: tokenData.access_token },
|
||||
});
|
||||
console.log("User data updated successfully.");
|
||||
}
|
||||
} else {
|
||||
@ -170,19 +181,19 @@ const CalendarSettingsPage = (props: {
|
||||
try {
|
||||
await updateUserData({
|
||||
newUserData: {
|
||||
eventColor: color
|
||||
}
|
||||
eventColor: color,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update color:", error);
|
||||
setSelectedColor(previousSelectedColor)
|
||||
setSelectedColor(previousSelectedColor);
|
||||
}
|
||||
}, 500),
|
||||
[]
|
||||
);
|
||||
|
||||
const handleChangeColor = (color: string) => {
|
||||
setPreviousSelectedColor(selectedColor)
|
||||
setPreviousSelectedColor(selectedColor);
|
||||
setSelectedColor(color);
|
||||
debouncedUpdateUserData(color);
|
||||
};
|
||||
@ -192,7 +203,7 @@ const CalendarSettingsPage = (props: {
|
||||
<View marginH-30>
|
||||
<TouchableOpacity onPress={() => props.setSelectedPage(0)}>
|
||||
<View row marginT-20 marginB-35 centerV>
|
||||
<Ionicons name="chevron-back" size={22} color="#979797"/>
|
||||
<Ionicons name="chevron-back" size={22} color="#979797" />
|
||||
<Text text70 color="#979797">
|
||||
Return to main settings
|
||||
</Text>
|
||||
@ -207,35 +218,39 @@ const CalendarSettingsPage = (props: {
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.pink)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.pink}>
|
||||
{selectedColor == colorMap.pink && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.orange)}>
|
||||
<TouchableOpacity
|
||||
onPress={() => handleChangeColor(colorMap.orange)}
|
||||
>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.orange}>
|
||||
{selectedColor == colorMap.orange && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.green)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.green}>
|
||||
{selectedColor == colorMap.green && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.teal)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.teal}>
|
||||
{selectedColor == colorMap.teal && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.purple)}>
|
||||
<TouchableOpacity
|
||||
onPress={() => handleChangeColor(colorMap.purple)}
|
||||
>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.purple}>
|
||||
{selectedColor == colorMap.purple && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
@ -270,54 +285,52 @@ const CalendarSettingsPage = (props: {
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.card}>
|
||||
<Text text70>Add Calendar</Text>
|
||||
<View style={{marginTop: 20}}>
|
||||
<Text text60R marginT-30 marginB-25>
|
||||
Add Calendar
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
label={"Connect Google"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-google" size={22} color="#979797"/>
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={handleGoogleLogin}
|
||||
/>
|
||||
<Button
|
||||
label={"Connect Microsoft"}
|
||||
label="Connect Google"
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-microsoft" size={22} color="#979797"/>
|
||||
<View marginR-15>
|
||||
<GoogleIcon />
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={handleMicrosoftSignIn}
|
||||
style={styles.addCalBtn}
|
||||
color="black"
|
||||
text70BL
|
||||
/>
|
||||
<Button
|
||||
label="Connect Apple"
|
||||
iconSource={() => (
|
||||
<View marginR-15>
|
||||
<AppleIcon />
|
||||
</View>
|
||||
)}
|
||||
style={styles.addCalBtn}
|
||||
color="black"
|
||||
text70BL
|
||||
/>
|
||||
<Button
|
||||
onPress={handleMicrosoftSignIn}
|
||||
label="Connect Outlook"
|
||||
iconSource={() => (
|
||||
<View marginR-15>
|
||||
<OutlookIcon />
|
||||
</View>
|
||||
)}
|
||||
style={styles.addCalBtn}
|
||||
color="black"
|
||||
text70BL
|
||||
/>
|
||||
|
||||
<Text text60R marginT-30 marginB-20>
|
||||
Connected Calendars
|
||||
</Text>
|
||||
<View style={styles.card}>
|
||||
<Text text70>Calendars</Text>
|
||||
<View style={{marginTop: 20}}>
|
||||
<View style={{ marginTop: 20 }}>
|
||||
<Button
|
||||
label={"Sync Outlook"}
|
||||
iconSource={() => (
|
||||
@ -325,12 +338,12 @@ const CalendarSettingsPage = (props: {
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
style={{ borderRadius: 50 }}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-microsoft" size={22} color="#979797"/>
|
||||
<Ionicons name="logo-microsoft" size={22} color="#979797" />
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
@ -346,12 +359,12 @@ const CalendarSettingsPage = (props: {
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
style={{ borderRadius: 50 }}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-google" size={22} color="#979797"/>
|
||||
<Ionicons name="logo-google" size={22} color="#979797" />
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
|
||||
@ -55,7 +55,7 @@ const UserSettings = (props: { setSelectedPage: (page: number) => void }) => {
|
||||
|
||||
{!selectedView && (
|
||||
<View>
|
||||
<Text>Nigga</Text>
|
||||
<Text>selview</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@ -13,6 +13,7 @@ interface IBrainDumpContext {
|
||||
isAddingBrainDump: boolean;
|
||||
setIsAddingBrainDump: (value: boolean) => void;
|
||||
addBrainDump: (BrainDump: IBrainDump) => void;
|
||||
deleteBrainDump: (id: number) => void;
|
||||
}
|
||||
|
||||
const BrainDumpContext = createContext<IBrainDumpContext | undefined>(
|
||||
@ -82,6 +83,12 @@ export const BrainDumpProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const deleteBrainDump = (id: number) => {
|
||||
setBrainDumps((prevBrainDumps) =>
|
||||
prevBrainDumps.filter((BrainDump) => BrainDump.id !== id)
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<BrainDumpContext.Provider
|
||||
value={{
|
||||
@ -90,6 +97,7 @@ export const BrainDumpProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
isAddingBrainDump,
|
||||
setIsAddingBrainDump,
|
||||
addBrainDump,
|
||||
deleteBrainDump
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user