mirror of
https://github.com/urosran/cally.git
synced 2025-07-16 01:56:16 +00:00
205 lines
6.2 KiB
TypeScript
205 lines
6.2 KiB
TypeScript
import React, { useRef, useState } from "react";
|
|
import { LayoutChangeEvent, StyleSheet } from "react-native";
|
|
import { Calendar } from "react-native-big-calendar";
|
|
import {
|
|
Picker,
|
|
PickerModes,
|
|
SegmentedControl,
|
|
View,
|
|
} from "react-native-ui-lib";
|
|
import { MaterialIcons } from "@expo/vector-icons";
|
|
import { AddEventDialog } from "@/components/pages/calendar/AddEventDialog";
|
|
import HeaderTemplate from "@/components/shared/HeaderTemplate";
|
|
import CalendarViewSwitch from "@/components/pages/calendar/CalendarViewSwitch";
|
|
import { ManuallyAddEventModal } from "@/components/pages/calendar/ManuallyAddEventModal";
|
|
import { CalendarEvent } from "@/contexts/CalendarContext";
|
|
import { useSettingsContext } from "@/contexts/SettingsContext";
|
|
import EditEventDialog from "./EditEventDialog";
|
|
import { useGetEvents } from "@/hooks/firebase/useGetEvents";
|
|
import { Text } from "react-native-ui-lib";
|
|
|
|
const modeMap = new Map([
|
|
[0, "day"],
|
|
[1, "week"],
|
|
[2, "month"],
|
|
]);
|
|
|
|
const months = [
|
|
"January",
|
|
"February",
|
|
"March",
|
|
"April",
|
|
"May",
|
|
"June",
|
|
"July",
|
|
"August",
|
|
"September",
|
|
"October",
|
|
"November",
|
|
"December",
|
|
];
|
|
|
|
export default function CalendarPage() {
|
|
const { calendarColor } = useSettingsContext();
|
|
const [editVisible, setEditVisible] = useState<boolean>(false);
|
|
const [eventForEdit, setEventForEdit] = useState<CalendarEvent>();
|
|
|
|
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,
|
|
},
|
|
});
|
|
|
|
const [isFamilyView, setIsFamilyView] = useState<boolean>(false);
|
|
const [calendarHeight, setCalendarHeight] = useState(0);
|
|
const [mode, setMode] = useState<"week" | "month" | "day">("week");
|
|
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
|
|
const [selectedNewEventDate, setSelectedNewEndDate] = useState<
|
|
Date | undefined
|
|
>(undefined);
|
|
|
|
const calendarContainerRef = useRef(null);
|
|
const { data: events } = useGetEvents(isFamilyView);
|
|
|
|
const onLayout = (event: LayoutChangeEvent) => {
|
|
const { height } = event.nativeEvent.layout;
|
|
setCalendarHeight(height);
|
|
};
|
|
|
|
const handleSegmentChange = (index: number) => {
|
|
const selectedMode = modeMap.get(index);
|
|
if (selectedMode) {
|
|
setMode(selectedMode as "day" | "week" | "month");
|
|
}
|
|
};
|
|
|
|
const handleMonthChange = (month: string) => {
|
|
const currentDay = selectedDate.getDate();
|
|
const currentYear = selectedDate.getFullYear();
|
|
|
|
const newMonthIndex = months.indexOf(month);
|
|
|
|
const updatedDate = new Date(currentYear, newMonthIndex, currentDay);
|
|
|
|
setSelectedDate(updatedDate);
|
|
};
|
|
|
|
return (
|
|
<View
|
|
style={{ flex: 1, height: "100%", padding: 10 }}
|
|
paddingH-22
|
|
paddingT-0
|
|
>
|
|
<HeaderTemplate
|
|
message={"Let's get your week started!"}
|
|
isWelcome={true}
|
|
/>
|
|
|
|
<View
|
|
style={{ flex: 1, backgroundColor: "#fff", borderRadius: 30 }}
|
|
ref={calendarContainerRef}
|
|
onLayout={onLayout}
|
|
>
|
|
<View
|
|
style={{
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 8,
|
|
borderRadius: 20,
|
|
borderBottomLeftRadius: 0,
|
|
borderBottomRightRadius: 0,
|
|
backgroundColor: "white",
|
|
marginBottom: 10,
|
|
}}
|
|
>
|
|
<View row centerV gap-3>
|
|
<Text style={{ fontFamily: "Manrope_500Medium", fontSize: 17 }}>
|
|
{selectedDate.getFullYear()}
|
|
</Text>
|
|
<Picker
|
|
value={months[selectedDate.getMonth()]} // Get the month from the date
|
|
placeholder={"Select Month"}
|
|
style={{ fontFamily: "Manrope_500Medium", fontSize: 17 }}
|
|
mode={PickerModes.SINGLE}
|
|
onChange={(itemValue) => handleMonthChange(itemValue as string)}
|
|
trailingAccessory={<MaterialIcons name={"keyboard-arrow-down"} />}
|
|
topBarProps={{
|
|
title: selectedDate.getFullYear().toString(),
|
|
titleStyle: { fontFamily: "Manrope_500Medium", fontSize: 17 },
|
|
}}
|
|
>
|
|
{months.map((month) => (
|
|
<Picker.Item key={month} label={month} value={month} />
|
|
))}
|
|
</Picker>
|
|
</View>
|
|
|
|
<View>
|
|
<SegmentedControl
|
|
segments={[{ label: "D" }, { label: "W" }, { label: "M" }]}
|
|
backgroundColor="#ececec"
|
|
inactiveColor="#919191"
|
|
activeBackgroundColor="#ea156c"
|
|
activeColor="white"
|
|
outlineColor="white"
|
|
outlineWidth={3}
|
|
segmentLabelStyle={styles.segmentslblStyle}
|
|
onChangeIndex={handleSegmentChange}
|
|
initialIndex={mode === "day" ? 0 : mode === "week" ? 1 : 2}
|
|
/>
|
|
</View>
|
|
</View>
|
|
|
|
{calendarHeight > 0 && (
|
|
<Calendar
|
|
bodyContainerStyle={styles.calHeader}
|
|
mode={mode}
|
|
events={isFamilyView ? events ?? [] : events ?? []}
|
|
eventCellStyle={(event) => ({ backgroundColor: event.eventColor })}
|
|
onPressEvent={(event) => {
|
|
setEditVisible(true);
|
|
setEventForEdit(event);
|
|
}}
|
|
height={calendarHeight}
|
|
activeDate={selectedDate}
|
|
date={selectedDate}
|
|
onPressCell={setSelectedNewEndDate}
|
|
headerContentStyle={mode === "day" ? styles.dayModeHeader : {}}
|
|
/>
|
|
)}
|
|
</View>
|
|
<CalendarViewSwitch viewSwitch={setIsFamilyView} />
|
|
<AddEventDialog />
|
|
{eventForEdit && (
|
|
<EditEventDialog
|
|
isVisible={editVisible}
|
|
setIsVisible={() => {
|
|
setEditVisible(!editVisible);
|
|
}}
|
|
event={eventForEdit}
|
|
/>
|
|
)}
|
|
|
|
<ManuallyAddEventModal
|
|
key={`${selectedNewEventDate}`}
|
|
initialDate={selectedNewEventDate}
|
|
show={!!selectedNewEventDate}
|
|
close={() => setSelectedNewEndDate(undefined)}
|
|
/>
|
|
</View>
|
|
);
|
|
}
|