import React, { useEffect, useState } from "react"; import { FaAngleDown, FaBell, FaClock, FaPlus, FaLink } from "react-icons/fa"; import { IoTimer } from "react-icons/io5"; import { BsThreeDots } from "react-icons/bs"; import Image from "next/image"; import CreateOrUpdateRoom from "../Modals/CreateOrUpdateRoom"; import { ShowModalType, useKeyboardContext, } from "../../contexts/keyboardContext"; import { collection, getFirestore, onSnapshot, orderBy, query, where, } from "firebase/firestore"; import { Collections } from "../../services/collections"; import { useTeamDashboardContext } from "../../contexts/teamDashboardContext"; import Room, { RoomStatus, RoomType } from "../../models/room"; import { useAuth } from "../../contexts/authContext"; import { Divider, Dropdown, Menu, Radio, Tooltip } from "antd"; import RoomCard from "../RoomCard"; import toast from "react-hot-toast"; import RoomTypeTag from "../RoomTypeTag"; import moment from "moment"; import { getTime } from "../../helpers/dateTime"; enum RoomTypeFilter { team = "team", me = "me", archived = "archived", } enum RoomTimeFilter { today = "today", week = "week", month = "month", } const db = getFirestore(); const today = new Date(); const lastWeek = new Date(); lastWeek.setDate(lastWeek.getDate() - 7); const nextWeek = new Date(); nextWeek.setDate(nextWeek.getDate() + 7); export default function DashboardRoom() { const { currUser } = useAuth(); const { handleModalType, showModalType } = useKeyboardContext(); const { team } = useTeamDashboardContext(); const [roomsMap, setRoomsMap] = useState>( new Map() ); // get recurring rooms data realtime: ALL of them useEffect(() => { /** * QUERY: * all recurring rooms, as the created date can be a year ago * */ const q = query( collection(db, Collections.rooms), where("teamId", "==", team.id), where("type", "==", RoomType.recurring) ); // return unsubscribe return onSnapshot(q, (snapshot) => { snapshot.docChanges().forEach(handleDocChange); }); }, []); // get scheduled rooms data realtime: the ones with the date range useEffect(() => { /** * QUERY: * all scheduled rooms in the past 7 days or the next 7 days * */ const q = query( collection(db, Collections.rooms), where("teamId", "==", team.id), where("type", "==", RoomType.scheduled), where("scheduledDateTime", ">", lastWeek), where("scheduledDateTime", "<", nextWeek), orderBy("scheduledDateTime", "asc") ); // return unsubscribe return onSnapshot(q, (snapshot) => { snapshot.docChanges().forEach(handleDocChange); }); }, []); // get now rooms data realtime useEffect(() => { /** * QUERY: * all live/now rooms going on right now * */ const q = query( collection(db, Collections.rooms), where("teamId", "==", team.id), where("type", "==", RoomType.now), where("createdDate", ">", lastWeek), orderBy("createdDate", "asc") ); // return unsubscribe return onSnapshot(q, (snapshot) => { snapshot.docChanges().forEach(handleDocChange); }); }, []); function handleDocChange(change) { let updatedRoom = change.doc.data() as Room; updatedRoom.id = change.doc.id; if (change.type === "added" || change.type === "modified") { // update rooms map setRoomsMap((prevMap) => { return new Map(prevMap.set(updatedRoom.id, updatedRoom)); }); } if (change.type === "removed") { console.log("Removed room: ", updatedRoom); } } // on CTRL + Q, new tab to google meet // on CTRL + V, show modal to create meeting with the link const [selectedTabPane, setSelectedTabPane] = useState( RoomTypeFilter.me ); // sort this mega array const allRooms = Array.from(roomsMap.values()); const teamRooms = allRooms.filter( (room) => room.status != RoomStatus.archived ); const meRooms = allRooms.filter( (room) => room.members.includes(currUser.uid) && room.status != RoomStatus.archived ); const archivedRooms = allRooms.filter( (room) => room.status == RoomStatus.archived ); // data for different meRooms const recurring = meRooms.filter( (room) => room.type == RoomType.recurring && room.status == RoomStatus.empty ); const now = meRooms.filter( (room) => (room.type == RoomType.now && room.status != RoomStatus.archived) || room.status == RoomStatus.live ); const scheduled = meRooms.filter( (room) => room.type == RoomType.scheduled && room.status == RoomStatus.empty ); // sorting array of scheduled rooms scheduled.sort(function (a, b) { // Turn your strings into dates, and then subtract them // to get a value that is either negative, positive, or zero. if (!b.scheduledDateTime) { return -1; } return ( getTime(a.scheduledDateTime.toDate()) - getTime(b.scheduledDateTime.toDate()) ); }); var relativeTimeNextMeeting = ""; // go through scheduled and find the first one coming up if (scheduled && scheduled.length > 0) { const firstOneInFuture = scheduled.find( (room) => moment(room.scheduledDateTime.toDate()).diff(today) > 0 ); if (firstOneInFuture) { const meetingDatetime: Date = firstOneInFuture.scheduledDateTime.toDate(); relativeTimeNextMeeting = moment(meetingDatetime).fromNow(); } } function getRoomContent() { // return data based on the selected filters switch (selectedTabPane) { case RoomTypeFilter.team: // render sections for different types const recurringTeam = teamRooms.filter( (room) => room.type == RoomType.recurring && room.status == RoomStatus.empty ); const nowTeam = teamRooms.filter( (room) => (room.type == RoomType.now && room.status != RoomStatus.archived) || room.status == RoomStatus.live ); const scheduledTeam = teamRooms.filter( (room) => room.type == RoomType.scheduled && room.status == RoomStatus.empty ); // sorting array of scheduled rooms scheduledTeam.sort(function (a, b) { // Turn your strings into dates, and then subtract them // to get a value that is either negative, positive, or zero. if (!b.scheduledDateTime) { return -1; } return ( getTime(a.scheduledDateTime.toDate()) - getTime(b.scheduledDateTime.toDate()) ); }); return ( <>
{nowTeam.map((room) => ( ))} {scheduledTeam.map((room) => ( ))} {recurringTeam.map((room) => ( ))}
); case RoomTypeFilter.me: return ( <>
{now.map((room) => ( ))} {scheduled.map((room) => ( ))} {recurring.map((room) => ( ))}
); case RoomTypeFilter.archived: return ( {archivedRooms.map((room) => { // if the room is return ( ); })} ); default: return allRooms.map((room) => { // if the room is return ( ); }); } } const TimePeriodFilterMenu = ( Past 24 Hours (Coming Soon) This Month (Coming Soon) ); const [selectedUpdateRoom, setSelectedUpdateRoom] = useState(null); async function handleUpdateRoom(roomId: string) { console.log("going to update room"); // get the room details and pass it into the modal if (!roomsMap.has(roomId)) { toast.error("not a valid room to edit"); return; } // pass this to the modal for use setSelectedUpdateRoom(roomsMap.get(roomId)); // call the keyboard context to show the modal handleModalType(ShowModalType.createRoom); } async function handleCloseModal() { console.log("closing modal"); // to make sure that the next time the props changes, the modal has the updated room object setSelectedUpdateRoom(null); // close the modal handleModalType(ShowModalType.na); } return (
{/* modal for creating room */} {/* header */} ROOMS {relativeTimeNextMeeting ? ( {"You have your next scheduled one "}{" "} {relativeTimeNextMeeting} {"."} ) : ( <> )} setSelectedTabPane(e.target.value)} > {RoomTypeFilter.me}{" "} {meRooms.length > 0 ? meRooms.length : ""} {RoomTypeFilter.team}{" "} {teamRooms.length} {RoomTypeFilter.archived}{" "} {archivedRooms.length > 0 ? archivedRooms.length : ""} Week {/* */} {/* all rooms */} {getRoomContent()}
); }