Added notifciations

This commit is contained in:
Milan Paunovic
2024-11-04 01:01:59 +01:00
parent 848211c3c8
commit 84a974f3f7
8 changed files with 153 additions and 16 deletions

View File

@ -10,6 +10,8 @@ import NavToDosIcon from "@/assets/svgs/NavToDosIcon";
import NavBrainDumpIcon from "@/assets/svgs/NavBrainDumpIcon";
import NavCalendarIcon from "@/assets/svgs/NavCalendarIcon";
import NavSettingsIcon from "@/assets/svgs/NavSettingsIcon";
import FeedbackNavIcon from "@/assets/svgs/FeedbackNavIcon";
import {MaterialIcons} from "@expo/vector-icons";
import {useSetAtom} from "jotai";
import {
isFamilyViewAtom,
@ -17,7 +19,7 @@ import {
toDosPageIndex,
userSettingsView,
} from "@/components/pages/calendar/atoms";
import FeedbackNavIcon from "@/assets/svgs/FeedbackNavIcon";
import Ionicons from "@expo/vector-icons/Ionicons";
export default function TabLayout() {
const {mutateAsync: signOut} = useSignOut();
@ -41,7 +43,7 @@ export default function TabLayout() {
drawerContent={(props) => {
return (
<DrawerContentScrollView {...props} style={{}}>
<View centerV marginH-30 marginT-20 marginB-20row>
<View centerV marginH-30 marginT-20 marginB-20 row>
<ImageBackground
source={require("../../assets/images/splash.png")}
style={{
@ -139,6 +141,19 @@ export default function TabLayout() {
}}
icon={<NavBrainDumpIcon/>}
/>
<DrawerButton
color="#e0ca03"
title={"Notifications"}
bgColor={"#ffdda1"}
pressFunc={() => {
props.navigation.navigate("notifications");
setPageIndex(0);
setToDosIndex(0);
setUserView(true);
setIsFamilyView(false);
}}
icon={<Ionicons name="notifications-outline" size={24} color={"#ffa200"} />}
/>
</View>
</View>
<Button
@ -242,6 +257,13 @@ export default function TabLayout() {
title: "To-Dos",
}}
/>
<Drawer.Screen
name="notifications"
options={{
drawerLabel: "Notifications",
title: "Notifications",
}}
/>
<Drawer.Screen
name="feedback"
options={{drawerLabel: "Feedback", title: "Feedback"}}

View File

@ -1,13 +1,12 @@
import {BrainDumpProvider} from "@/contexts/DumpContext";
import {View} from "react-native-ui-lib";
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";
export default function Screen() {
return (
<BrainDumpProvider>
<View>
<BrainDumpPage />
<BrainDumpPage/>
</View>
</BrainDumpProvider>
);

View File

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

View File

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

View File

@ -15,7 +15,6 @@ import {CalendarEvent} from "@/components/pages/calendar/interfaces";
import {Text} from "react-native-ui-lib";
import {addDays, compareAsc, isWithinInterval, subDays} from "date-fns";
import {useCalSync} from "@/hooks/useCalSync";
import { useIsMutating } from "react-query";
import {useSyncEvents} from "@/hooks/useSyncOnScroll";
interface EventCalendarProps {

View File

@ -0,0 +1,60 @@
import {FlatList, ScrollView, StyleSheet} from "react-native";
import React from "react";
import {Card, Text, View} from "react-native-ui-lib";
import HeaderTemplate from "@/components/shared/HeaderTemplate";
import {useGetNotifications} from "@/hooks/firebase/useGetNotifications";
import {formatDistanceToNow} from "date-fns";
const NotificationsPage = () => {
const {data: notifications} = useGetNotifications()
console.log(notifications?.[0]?.timestamp)
return (
<View flexG height={"100%"}>
<View flexG>
<ScrollView
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
>
<View marginH-25>
<HeaderTemplate
message={"Welcome to your notifications!"}
isWelcome={false}
children={
<Text
style={{fontFamily: "Manrope_400Regular", fontSize: 14}}
>
See your notifications here.
</Text>
}
/>
<View>
<FlatList data={notifications ?? []} renderItem={({item}) => <Card padding-20 gap-10>
<Text text70>{item.content}</Text>
<View row spread>
<Text text90>{formatDistanceToNow(new Date(item.timestamp), { addSuffix: true })}</Text>
<Text text90>{item.timestamp.toLocaleDateString()}</Text>
</View>
</Card>}/>
</View>
</View>
</ScrollView>
</View>
</View>
);
};
const styles = StyleSheet.create({
searchField: {
borderWidth: 0.7,
borderColor: "#9b9b9b",
borderRadius: 15,
height: 42,
paddingLeft: 10,
marginVertical: 20,
},
});
export default NotificationsPage;

View File

@ -1,6 +1,6 @@
const {onRequest} = require("firebase-functions/v2/https");
const {getAuth} = require("firebase-admin/auth");
const {getFirestore} = require("firebase-admin/firestore");
const {getFirestore, Timestamp} = require("firebase-admin/firestore");
const logger = require("firebase-functions/logger");
const functions = require('firebase-functions');
const admin = require('firebase-admin');
@ -22,7 +22,7 @@ exports.sendNotificationOnEventCreation = functions.firestore
.document('Events/{eventId}')
.onCreate(async (snapshot, context) => {
const eventData = snapshot.data();
const { familyId, creatorId, email } = eventData;
const { familyId, creatorId, email, title } = eventData;
if (!familyId || !creatorId) {
console.error('Missing familyId or creatorId in event data');
@ -44,7 +44,7 @@ exports.sendNotificationOnEventCreation = functions.firestore
notificationTimeout = setTimeout(async () => {
const eventMessage = eventCount === 1
? `An event "${eventData.title}" has been added. Check it out!`
? `An event "${title}" has been added. Check it out!`
: `${eventCount} new events have been added.`;
let messages = pushTokens.map(pushToken => {
@ -85,6 +85,22 @@ exports.sendNotificationOnEventCreation = functions.firestore
}
}
// Save the notification in Firestore for record-keeping
const notificationData = {
creatorId,
familyId,
content: eventMessage,
eventId: context.params.eventId,
timestamp: Timestamp.now(),
};
try {
await db.collection("Notifications").add(notificationData);
console.log("Notification stored in Firestore:", notificationData);
} catch (error) {
console.error("Error saving notification to Firestore:", error);
}
// Reset state variables after notifications are sent
eventCount = 0;
pushTokens = [];

View File

@ -0,0 +1,29 @@
import {useQuery} from "react-query";
import firestore from "@react-native-firebase/firestore";
import {useAuthContext} from "@/contexts/AuthContext";
export const useGetNotifications = () => {
const { user, profileData } = useAuthContext();
return useQuery({
queryKey: ["notifications", user?.uid],
queryFn: async () => {
const snapshot = await firestore()
.collection("Notifications")
.where("familyId", "==", profileData?.familyId)
.get();
return snapshot.docs.map((doc) => {
const data = doc.data();
return {...data, timestamp: new Date(data.timestamp.seconds * 1000 + data.timestamp.nanoseconds / 1e6)} as {
creatorId: string,
familyId: string,
content: string,
eventId: string,
timestamp: Date,
};
});
}
})
};