mirror of
https://github.com/urosran/cally.git
synced 2026-10-23 09:47:53 +00:00
Merge remote-tracking branch 'origin/main' into dev
This commit is contained in:
@@ -14,6 +14,7 @@ import { useAtom } from "jotai";
|
||||
import { modeAtom, selectedDateAtom } from "@/components/pages/calendar/atoms";
|
||||
import { format, isSameDay } from "date-fns";
|
||||
import { useAuthContext } from "@/contexts/AuthContext";
|
||||
import {useIsMutating} from "react-query";
|
||||
|
||||
export const CalendarHeader = memo(() => {
|
||||
const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function CalendarPage() {
|
||||
paddingT-0
|
||||
>
|
||||
<HeaderTemplate
|
||||
message={"Let's get your week started!"}
|
||||
message={"Let's get your week started !"}
|
||||
isWelcome
|
||||
isCalendar={true}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Calendar } from "react-native-big-calendar";
|
||||
import { ActivityIndicator, StyleSheet, View, ViewStyle } from "react-native";
|
||||
import { ActivityIndicator, ScrollView, StyleSheet, View, ViewStyle } from "react-native";
|
||||
import { useGetEvents } from "@/hooks/firebase/useGetEvents";
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import {
|
||||
@@ -15,6 +15,8 @@ import { useAuthContext } from "@/contexts/AuthContext";
|
||||
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 {useSyncEvents} from "@/hooks/useSyncOnScroll";
|
||||
|
||||
interface EventCalendarProps {
|
||||
calendarHeight: number;
|
||||
@@ -39,7 +41,9 @@ export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
|
||||
const setEventForEdit = useSetAtom(eventForEditAtom);
|
||||
const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom);
|
||||
|
||||
const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes());
|
||||
const {isSyncing} = useSyncEvents()
|
||||
const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes());
|
||||
useCalSync()
|
||||
|
||||
const todaysDate = new Date();
|
||||
|
||||
@@ -47,15 +51,15 @@ export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
|
||||
(event: CalendarEvent) => {
|
||||
if (mode === "day" || mode === "week") {
|
||||
setEditVisible(true);
|
||||
console.log({ event });
|
||||
setEventForEdit(event);
|
||||
} else {
|
||||
setMode("day");
|
||||
setSelectedDate(event.start);
|
||||
}
|
||||
},
|
||||
[setEditVisible, setEventForEdit, mode]
|
||||
);
|
||||
// console.log({event});
|
||||
setEventForEdit(event);
|
||||
} else {
|
||||
setMode("day");
|
||||
setSelectedDate(event.start);
|
||||
}
|
||||
},
|
||||
[setEditVisible, setEventForEdit, mode]
|
||||
);
|
||||
|
||||
const handlePressCell = useCallback(
|
||||
(date: Date) => {
|
||||
@@ -94,7 +98,7 @@ export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
|
||||
);
|
||||
|
||||
const memoizedEventCellStyle = useCallback(
|
||||
(event: CalendarEvent) => ({ backgroundColor: event.eventColor }),
|
||||
(event: CalendarEvent) => ({ backgroundColor: event.eventColor , fontSize: 14}),
|
||||
[]
|
||||
);
|
||||
|
||||
@@ -103,9 +107,7 @@ export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
|
||||
[profileData]
|
||||
);
|
||||
|
||||
console.log({
|
||||
memoizedWeekStartsOn,
|
||||
profileData: profileData?.firstDayOfWeek,
|
||||
// console.log({memoizedWeekStartsOn, profileData: profileData?.firstDayOfWeek,
|
||||
});
|
||||
|
||||
const isSameDate = useCallback((date1: Date, date2: Date) => {
|
||||
@@ -175,11 +177,7 @@ export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
|
||||
}, {} as Record<string, CalendarEvent[]>);
|
||||
|
||||
const endTime = Date.now();
|
||||
console.log(
|
||||
"memoizedEvents computation time:",
|
||||
endTime - startTime,
|
||||
"ms"
|
||||
);
|
||||
// console.log("memoizedEvents computation time:", endTime - startTime, "ms");
|
||||
|
||||
return { enrichedEvents, filteredEvents };
|
||||
}, [events, selectedDate, mode]);
|
||||
@@ -239,106 +237,123 @@ export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
|
||||
if (isLoading) {
|
||||
return (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color="#0000ff" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
{isSyncing && <Text>Syncing...</Text>}
|
||||
<ActivityIndicator size="large" color="#0000ff"/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// console.log(enrichedEvents, filteredEvents)
|
||||
|
||||
return (
|
||||
<Calendar
|
||||
bodyContainerStyle={styles.calHeader}
|
||||
swipeEnabled
|
||||
mode={mode}
|
||||
enableEnrichedEvents={true}
|
||||
sortedMonthView
|
||||
// enrichedEventsByDate={enrichedEvents}
|
||||
events={filteredEvents}
|
||||
// eventCellStyle={memoizedEventCellStyle}
|
||||
onPressEvent={handlePressEvent}
|
||||
weekStartsOn={memoizedWeekStartsOn}
|
||||
height={calendarHeight}
|
||||
activeDate={todaysDate}
|
||||
date={selectedDate}
|
||||
onPressCell={handlePressCell}
|
||||
headerContentStyle={memoizedHeaderContentStyle}
|
||||
onSwipeEnd={handleSwipeEnd}
|
||||
scrollOffsetMinutes={offsetMinutes}
|
||||
theme={{
|
||||
palette: {
|
||||
nowIndicator: profileData?.eventColor || "#fd1575",
|
||||
gray: {
|
||||
"100": "#e8eaed",
|
||||
"200": "#e8eaed",
|
||||
"500": "#b7b7b7",
|
||||
"800": "#919191",
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: "PlusJakartaSans_500Medium",
|
||||
sm: { fontFamily: "Manrope_600SemiBold", fontSize: 15 },
|
||||
xl: {
|
||||
fontFamily: "PlusJakartaSans_500Medium",
|
||||
fontSize: 16,
|
||||
},
|
||||
moreLabel: {},
|
||||
xs: { fontSize: 10 },
|
||||
},
|
||||
}}
|
||||
dayHeaderStyle={dateStyle}
|
||||
dayHeaderHighlightColor={"white"}
|
||||
showAdjacentMonths
|
||||
hourStyle={styles.hourStyle}
|
||||
onPressDateHeader={handlePressDayHeader}
|
||||
ampm
|
||||
// renderCustomDateForMonth={renderCustomDateForMonth}
|
||||
/>
|
||||
);
|
||||
}
|
||||
<>
|
||||
{isSyncing && (
|
||||
<View style={styles.loadingContainer}>
|
||||
{isSyncing && <Text>Syncing...</Text>}
|
||||
<ActivityIndicator size="large" color="#0000ff"/>
|
||||
</View>
|
||||
)}
|
||||
<Calendar
|
||||
bodyContainerStyle={styles.calHeader}
|
||||
swipeEnabled
|
||||
mode={mode}
|
||||
// enableEnrichedEvents={true}
|
||||
sortedMonthView
|
||||
// enrichedEventsByDate={enrichedEvents}
|
||||
events={filteredEvents}
|
||||
eventCellStyle={memoizedEventCellStyle}
|
||||
onPressEvent={handlePressEvent}
|
||||
weekStartsOn={memoizedWeekStartsOn}
|
||||
height={calendarHeight}
|
||||
activeDate={todaysDate}
|
||||
date={selectedDate}
|
||||
onPressCell={handlePressCell}
|
||||
headerContentStyle={memoizedHeaderContentStyle}
|
||||
onSwipeEnd={handleSwipeEnd}
|
||||
scrollOffsetMinutes={offsetMinutes}
|
||||
theme={{
|
||||
palette: {
|
||||
nowIndicator: profileData?.eventColor || "#fd1575",
|
||||
gray: {
|
||||
"100": "#e8eaed",
|
||||
"200": "#e8eaed",
|
||||
"500": "#b7b7b7",
|
||||
"800": "#919191",
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: "PlusJakartaSans_500Medium",
|
||||
sm: {fontFamily: "Manrope_600SemiBold", fontSize: 8},
|
||||
xl: {
|
||||
fontFamily: "PlusJakartaSans_500Medium",
|
||||
fontSize: 14,
|
||||
},
|
||||
moreLabel: {},
|
||||
xs: {fontSize: 10},
|
||||
},
|
||||
}}
|
||||
dayHeaderStyle={dateStyle}
|
||||
dayHeaderHighlightColor={"white"}
|
||||
showAdjacentMonths
|
||||
headerContainerStyle={mode !== "month" ? {
|
||||
overflow:"hidden",
|
||||
} : {}}
|
||||
hourStyle={styles.hourStyle}
|
||||
onPressDateHeader={handlePressDayHeader} ampm
|
||||
// renderCustomDateForMonth={renderCustomDateForMonth}
|
||||
/>
|
||||
</>
|
||||
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
segmentslblStyle: {
|
||||
fontSize: 12,
|
||||
fontFamily: "Manrope_600SemiBold",
|
||||
},
|
||||
calHeader: {
|
||||
borderWidth: 0,
|
||||
},
|
||||
dayModeHeader: {
|
||||
alignSelf: "flex-start",
|
||||
justifyContent: "space-between",
|
||||
alignContent: "center",
|
||||
width: 38,
|
||||
right: 42,
|
||||
height: 13,
|
||||
},
|
||||
weekModeHeader: {},
|
||||
monthModeHeader: {},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
dayHeader: {
|
||||
backgroundColor: "#4184f2",
|
||||
aspectRatio: 1,
|
||||
borderRadius: 100,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
otherDayHeader: {
|
||||
backgroundColor: "transparent",
|
||||
color: "#919191",
|
||||
aspectRatio: 1,
|
||||
borderRadius: 100,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
hourStyle: {
|
||||
color: "#5f6368",
|
||||
fontSize: 12,
|
||||
fontFamily: "Manrope_500Medium",
|
||||
},
|
||||
segmentslblStyle: {
|
||||
fontSize: 12,
|
||||
fontFamily: "Manrope_600SemiBold",
|
||||
},
|
||||
calHeader: {
|
||||
borderWidth: 0,
|
||||
},
|
||||
dayModeHeader: {
|
||||
alignSelf: "flex-start",
|
||||
justifyContent: "space-between",
|
||||
alignContent: "center",
|
||||
width: 38,
|
||||
right: 42,
|
||||
height: 13,
|
||||
},
|
||||
weekModeHeader: {},
|
||||
monthModeHeader: {},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
zIndex: 100,
|
||||
backgroundColor: "rgba(255, 255, 255, 0.9)",
|
||||
},
|
||||
dayHeader: {
|
||||
backgroundColor: "#4184f2",
|
||||
aspectRatio: 1,
|
||||
borderRadius: 100,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
otherDayHeader: {
|
||||
backgroundColor: "transparent",
|
||||
color: "#919191",
|
||||
aspectRatio: 1,
|
||||
borderRadius: 100,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
hourStyle: {
|
||||
color: "#5f6368",
|
||||
fontSize: 12,
|
||||
fontFamily: "Manrope_500Medium",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
@@ -142,7 +142,7 @@ const CalendarSettingsPage = () => {
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.subTitle} marginT-30 marginB-25>
|
||||
Add Calendar
|
||||
Add Calendars
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState } from "react";
|
||||
import { Dialog, Button, Text, View } from "react-native-ui-lib";
|
||||
import { StyleSheet } from "react-native";
|
||||
import { Feather } from "@expo/vector-icons";
|
||||
import {useDeleteUser} from "@/hooks/firebase/useDeleteUser";
|
||||
|
||||
interface ConfirmationDialogProps {
|
||||
visible: boolean;
|
||||
@@ -17,6 +18,7 @@ const DeleteProfileDialogs: React.FC<ConfirmationDialogProps> = ({
|
||||
onConfirm,
|
||||
}) => {
|
||||
const [confirmationDialog, setConfirmationDialog] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog
|
||||
|
||||
@@ -21,6 +21,7 @@ import { useChangeProfilePicture } from "@/hooks/firebase/useChangeProfilePictur
|
||||
import { colorMap } from "@/constants/colorMap";
|
||||
import DeleteProfileDialogs from "../user_components/DeleteProfileDialogs";
|
||||
import {AntDesign} from "@expo/vector-icons";
|
||||
import {useDeleteUser} from "@/hooks/firebase/useDeleteUser";
|
||||
|
||||
const MyProfile = () => {
|
||||
const { user, profileData } = useAuthContext();
|
||||
@@ -53,6 +54,7 @@ const MyProfile = () => {
|
||||
|
||||
const { mutateAsync: updateUserData } = useUpdateUserData();
|
||||
const { mutateAsync: changeProfilePicture } = useChangeProfilePicture();
|
||||
const { mutateAsync: deleteAsync } = useDeleteUser()
|
||||
const isFirstRender = useRef(true);
|
||||
|
||||
const handleUpdateUserData = async () => {
|
||||
@@ -305,9 +307,7 @@ const MyProfile = () => {
|
||||
}}
|
||||
visible={showDeleteDialog}
|
||||
onDismiss={handleHideDeleteDialog}
|
||||
onConfirm={() => {
|
||||
console.log("delete account here");
|
||||
}}
|
||||
onConfirm={() => deleteAsync({})}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user