diff --git a/components/Dashboard/Links.tsx b/components/Dashboard/Links.tsx index 0edb38e..8ad1757 100644 --- a/components/Dashboard/Links.tsx +++ b/components/Dashboard/Links.tsx @@ -98,8 +98,8 @@ export default function Links() { return false; } - // if I am the sender, then also show - if (link.createdByUserId == currUser.uid) { + // if I am the sender, then also show, but only if it's me sending to a specific person + if (link.createdByUserId == currUser.uid && link.recipients?.length > 0) { return true; } @@ -222,7 +222,7 @@ export default function Links() { {/* table of links */} -
+
{getFilteredContent().map((link) => ( ))} diff --git a/components/Dashboard/Rooms.tsx b/components/Dashboard/Rooms.tsx index 78975eb..c6fb035 100644 --- a/components/Dashboard/Rooms.tsx +++ b/components/Dashboard/Rooms.tsx @@ -42,6 +42,8 @@ const db = getFirestore(); 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(); @@ -52,41 +54,84 @@ export default function DashboardRoom() { new Map() ); - // get rooms data realtime + // get recurring rooms data realtime: ALL of them useEffect(() => { /** * QUERY: - * all rooms in the past week - * order createdDate desc + * all recurring rooms, as the created date can be a year ago * */ const q = query( collection(db, Collections.rooms), where("teamId", "==", team.id), - where("createdDate", ">", lastWeek), - orderBy("createdDate", "desc") + where("type", "==", RoomType.recurring) ); // return unsubscribe return onSnapshot(q, (snapshot) => { - snapshot.docChanges().forEach((change) => { - let updatedRoom = change.doc.data() as Room; - updatedRoom.id = change.doc.id; - - if (change.type === "added" || change.type === "modified") { - console.log("New or updated room: ", updatedRoom); - // update rooms map - setRoomsMap((prevMap) => { - return new Map(prevMap.set(updatedRoom.id, updatedRoom)); - }); - } - if (change.type === "removed") { - console.log("Removed room: ", updatedRoom); - } - }); + snapshot.docChanges().forEach(handleDocChange); }); }, []); + // get scheduled rooms data realtime + 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") { + console.log("New or updated room: ", updatedRoom); + // 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 @@ -94,7 +139,9 @@ export default function DashboardRoom() { RoomTypeFilter.me ); + // sort this mega array const allRooms = Array.from(roomsMap.values()); + const teamRooms = allRooms.filter( (room) => room.status != RoomStatus.archived ); @@ -112,15 +159,106 @@ export default function DashboardRoom() { // return data based on the selected filters switch (selectedTabPane) { case RoomTypeFilter.team: - return teamRooms; + return teamRooms.map((room) => { + // if the room is + return ( + + ); + }); case RoomTypeFilter.me: - return meRooms; + // render sections for different types + + const recurring = meRooms.filter( + (room) => room.type == RoomType.recurring + ); + const now = meRooms.filter((room) => room.status == RoomStatus.live); + const scheduled = meRooms.filter( + (room) => room.type == RoomType.scheduled + ); + + return ( + <> + Live +
+ {now.map((room) => ( + + ))} +
+ + Scheduled +
+ {scheduled.map((room) => ( + + ))} +
+ + Recurring +
+ {recurring.map((room) => ( + + ))} +
+ + ); + + // return meRooms.map((room) => { + // return ( + // + // ); + // }); case RoomTypeFilter.live: - return liveRooms; + return liveRooms.map((room) => { + // if the room is + return ( + + ); + }); case RoomTypeFilter.archived: - return archivedRooms; + return archivedRooms.map((room) => { + // if the room is + return ( + + ); + }); default: - return allRooms; + return allRooms.map((room) => { + // if the room is + return ( + + ); + }); } } @@ -164,7 +302,7 @@ export default function DashboardRoom() { } return ( -
+
{/* modal for creating room */} {/* all rooms */} - - {getRoomContent().map((room) => { - return ( - - ); - })} - + {getRoomContent()}
); } diff --git a/components/Dashboard/TeamVoiceLine.tsx b/components/Dashboard/TeamVoiceLine.tsx index daadccf..774c7d4 100644 --- a/components/Dashboard/TeamVoiceLine.tsx +++ b/components/Dashboard/TeamVoiceLine.tsx @@ -208,7 +208,7 @@ export default function TeamVoiceLine() { } return ( -
+
TEAM diff --git a/components/Modals/CreateOrUpdateRoom.tsx b/components/Modals/CreateOrUpdateRoom.tsx index 5fa2886..56b9407 100644 --- a/components/Modals/CreateOrUpdateRoom.tsx +++ b/components/Modals/CreateOrUpdateRoom.tsx @@ -1,4 +1,15 @@ -import { Divider, Modal, Radio, Select, Switch, Tooltip } from "antd"; +import { + DatePicker, + Divider, + Modal, + Radio, + Select, + Switch, + TimePicker, + Tooltip, +} from "antd"; +import { Timestamp } from "firebase/firestore"; +import moment from "moment"; import React, { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { useAuth } from "../../contexts/authContext"; @@ -41,6 +52,13 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { setMembersSelected(props.updateRoom.members); setRoomType(props.updateRoom.type); setRoomAppxDateTime(props.updateRoom.approximateDateTime); + + if (props.updateRoom.scheduledDateTime) { + const convertedToMoment = moment( + props.updateRoom.scheduledDateTime.toDate() + ); + setDateTimePicker(convertedToMoment); + } } else { // update state when user does ctrl + v resetForm(); @@ -77,10 +95,32 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { } if (roomType == RoomType.now) { + // make sure approximate time isn't selected + newRoom.approximateDateTime = null; newRoom.status = RoomStatus.live; + } else if (roomType == RoomType.scheduled) { + // make sure that either appx or time picker is selected, not both + if (roomAppxDateTime && dateTimePicker) { + toast.error( + "Please only select an approximate slot or specific time, not both!" + ); + return; + } else if (roomAppxDateTime) { + newRoom.approximateDateTime = roomAppxDateTime; + } else { + newRoom.scheduledDateTime = Timestamp.fromDate( + dateTimePicker.toDate() + ); + } + } else if (roomType == RoomType.recurring) { + // clear the field for the time picker if they ever selected that + newRoom.scheduledDateTime = null; + + newRoom.approximateDateTime = roomAppxDateTime; } - newRoom.approximateDateTime = roomAppxDateTime; + // newRoom.approximateDateTime = roomAppxDateTime; + newRoom.link = roomLink; newRoom.members = [...membersSelected]; // add currUser to the list of "people" newRoom.type = roomType; @@ -94,13 +134,15 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { newRoom.membersInRoom = props.updateRoom.membersInRoom; } + console.log(newRoom); + + handleModalType(ShowModalType.na); + await roomService.createOrUpdateRoom(newRoom); resetForm(); toast.success("done"); - - handleModalType(ShowModalType.na); } catch (error) { toast.error("problem creating room"); console.log(error); @@ -116,6 +158,8 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { setRoomAppxDateTime(""); setRoomType(RoomType.now); + setDateTimePicker(null); + setShowMoreDetails(false); } @@ -130,6 +174,7 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { const [roomType, setRoomType] = useState(RoomType.now); const [roomAppxDateTime, setRoomAppxDateTime] = useState(""); // for certain room types + const [dateTimePicker, setDateTimePicker] = useState(null); const [showMoreDetails, setShowMoreDetails] = useState(false); @@ -141,6 +186,14 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { console.log(value); } + function handleDateTimePickerChange(time) { + console.log(time); + + setRoomAppxDateTime(""); + + setDateTimePicker(time); + } + const allUsersForSelection: User[] = [...teamUsers, user]; const MemberSelection = () => { @@ -235,23 +288,54 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { {roomType == RoomType.recurring || roomType == RoomType.scheduled ? ( - - - Approximate Slot - - The calendar way of doing things is overwhelming. Put a rough - day/time that makes sense to you. +
+ + + Approximate Slot + + Sometimes you don't have a specific time or want to + propose a rough period. + + setRoomAppxDateTime(e.target.value)} + /> - setRoomAppxDateTime(e.target.value)} - /> - - + + {roomType == RoomType.scheduled ? ( + <> + OR + + Specific Time + {/* */} + + + + + ) : ( + <> + )} +
) : ( <> )} @@ -286,7 +370,7 @@ export default function CreateOrUpdateRoomModal(props: IModalProps) { Optional - Add any mandatory attendees you want or just tell - them later and they will see it in the team section. + them later and they will see it in the team rooms. {MemberSelection()}
diff --git a/components/RoomCard.tsx b/components/RoomCard.tsx index 368f399..40122b8 100644 --- a/components/RoomCard.tsx +++ b/components/RoomCard.tsx @@ -225,7 +225,7 @@ export default function RoomCard(props: IRoomCardProps) { {/* header */} diff --git a/components/RoomsRowsByType.tsx b/components/RoomsRowsByType.tsx new file mode 100644 index 0000000..f5b0b64 --- /dev/null +++ b/components/RoomsRowsByType.tsx @@ -0,0 +1,38 @@ +import Room, { RoomType } from "../models/room"; +import RoomCard from "./RoomCard"; + +interface IRoomsData { + rooms: Room[]; +} + +// different rows for the types +export function RoomsRowsByType(props: IRoomsData) { + // got the top level content/rooms + // now let's drill down and filter + const recurringRooms = props.rooms.filter( + (room) => room.type == RoomType.recurring + ); + + const scheduledRooms = props.rooms.filter( + (room) => room.type == RoomType.scheduled + ); + + const nowRooms = props.rooms.filter( + (room) => room.type == RoomType.scheduled + ); + + return; + // return props.rooms.map((room) => { + // // if the room is + // return ( + // + // ); + // }) +} + +// simple table for the archived rooms +export function ArchivedRoomsTable(props: IRoomsData) {} diff --git a/models/room.ts b/models/room.ts index c9ea324..ce76e23 100644 --- a/models/room.ts +++ b/models/room.ts @@ -18,8 +18,18 @@ export default class Room { status: RoomStatus = RoomStatus.empty; approximateDateTime: string; // vaguely say when the meeting should be...give user pointers + scheduledDateTime: Timestamp; + + // scheduledJsDateTime(): Date { + // return this.scheduledDateTime.toDate(); + // } createdDate: Timestamp; + + // createdJsDate(): Date { + // return this.createdDate.toDate(); + // } + createdByUserId: string; teamId: string; diff --git a/pages/teams/[teamid].tsx b/pages/teams/[teamid].tsx index 96dcd62..722d826 100644 --- a/pages/teams/[teamid].tsx +++ b/pages/teams/[teamid].tsx @@ -89,7 +89,7 @@ function TeamDashboard() {
-
+