seeding initial office rooms and showing them

This commit is contained in:
Arjun Patel
2022-01-22 14:39:01 -08:00
parent 45dbb7c170
commit 9c64e80b08
8 changed files with 272 additions and 3 deletions
-2
View File
@@ -55,8 +55,6 @@ export default function Announcements() {
updatedOrNewAnn.id = change.doc.id;
if (change.type === "added" || change.type === "modified") {
console.log("New or updated announcement: ", updatedOrNewAnn);
// update rooms map
setAnnMap((prevMap) => {
return new Map(prevMap.set(updatedOrNewAnn.id, updatedOrNewAnn));
+100
View File
@@ -0,0 +1,100 @@
import {
collection,
getFirestore,
onSnapshot,
query,
where,
} from "firebase/firestore";
import { useEffect, useState } from "react";
import { useAuth } from "../../contexts/authContext";
import { useTeamDashboardContext } from "../../contexts/teamDashboardContext";
import OfficeRoom from "../../models/officeRoom";
import { Collections } from "../../services/collections";
import OfficeRoomService from "../../services/officeRoomService";
import OfficeCard from "../OfficeCard";
const db = getFirestore();
const officeRoomService = new OfficeRoomService();
export default function Office() {
const { currUser } = useAuth();
const { team } = useTeamDashboardContext();
const [officeRoomsMap, setOfficeRoomsMap] = useState<Map<string, OfficeRoom>>(
new Map<string, OfficeRoom>()
);
// get all offices for this team : realtime
useEffect(() => {
/**
* QUERY:
* all offices for this team
*
*/
const q = query(
collection(db, Collections.officeRooms),
where("teamId", "==", team.id)
);
// return unsubscribe
return onSnapshot(q, (snapshot) => {
if (snapshot.empty) {
// seed data and create the initial rooms
console.log("seeding office rooms for this team");
officeRoomService.createInitialOfficeRooms(currUser.uid, team.id);
return;
}
snapshot.docChanges().forEach((change) => {
let updatedOfficeRoom = change.doc.data() as OfficeRoom;
updatedOfficeRoom.id = change.doc.id;
if (change.type === "added" || change.type === "modified") {
// update office rooms map on change of the room
setOfficeRoomsMap((prevMap) => {
return new Map(
prevMap.set(updatedOfficeRoom.id, updatedOfficeRoom)
);
});
}
if (change.type === "removed") {
console.log("Removed office room: ", updatedOfficeRoom);
}
});
});
}, []);
const allOfficeRooms = Array.from(officeRoomsMap.values());
allOfficeRooms.sort((a, b) => {
if (a.name < b.name) {
return 1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
// if there are none, then show user button to create initial office rooms and then create them
return (
<section className="p-5 flex flex-col bg-gray-100 bg-opacity-25 rounded-lg shadow-md w-96 shrink-0">
<span className="flex flex-row justify-start items-center pb-5">
<span className="flex flex-col">
<span className="text-white uppercase">Office</span>
</span>
</span>
{/* all office rooms */}
<span className="flex flex-col space-y-5">
{allOfficeRooms.map((officeRoom) => (
<OfficeCard key={officeRoom.id} officeRoom={officeRoom} />
))}
{/* <OfficeCard /> */}
</span>
</section>
);
}
+1 -1
View File
@@ -204,7 +204,7 @@ export default function TeamVoiceLine() {
}
return (
<section className="p-5 flex flex-col bg-gray-100 bg-opacity-25 rounded-lg shadow-md w-96 shrink-0 max-h-[32rem]">
<section className="p-5 flex flex-col bg-gray-100 bg-opacity-25 rounded-lg shadow-md w-96 shrink-0">
<span className="flex flex-row justify-start items-center pb-5">
<span className="flex flex-col">
<span className="text-white">TEAM</span>
+41
View File
@@ -0,0 +1,41 @@
import { Avatar } from "antd";
import OfficeRoom, { OfficeRoomState } from "../models/officeRoom";
interface IOfficeCard {
officeRoom: OfficeRoom;
}
export default function OfficeCard(props: IOfficeCard) {
return (
<span className="flex flex-col">
<span className="flex flex-row justify-start items-center">
{renderOfficePulse(OfficeRoomState.active)}
{/* office location name */}
<span className="text-gray-200 text-lg font-semibold ml-2">
{props.officeRoom.name}
</span>
{/* all members in room */}
<span className="ml-auto">
<Avatar.Group>
{props.officeRoom.members.map((officeLocation) => {
<Avatar
style={{ backgroundColor: "teal", verticalAlign: "middle" }}
className="shadow-xl hover:z-20 hover:cursor-pointer"
>
{officeLocation[0]}
</Avatar>;
})}
</Avatar.Group>
</span>
</span>
</span>
);
}
function renderOfficePulse(officeRoomState: OfficeRoomState) {
return (
<span className="h-4 w-4 rounded-full bg-green-500 animate-pulse shadow-lg"></span>
);
}
+37
View File
@@ -0,0 +1,37 @@
import { Timestamp } from "firebase/firestore";
import { v4 as uuidv4 } from "uuid";
export default class OfficeRoom {
id: string = uuidv4();
teamId: string;
name: string; // entrance, kitchen, etc.
createdDate: Timestamp;
createdByUserId: string;
lastUpdatedDate: Timestamp;
members: string[] = []; // id's of users in the office room
state: OfficeRoomState;
constructor(
_name: string,
_teamId: string,
_createdBy: string,
_state: OfficeRoomState = OfficeRoomState.idle
) {
this.name = _name;
this.teamId = _teamId;
this.createdByUserId = _createdBy;
this.state = _state;
}
}
export enum OfficeRoomState {
active = "active",
idle = "idle",
archived = "archived",
}
+3
View File
@@ -19,6 +19,7 @@ import TeamService from "../../services/teamService";
import UserService from "../../services/userService";
import Announcements from "../../components/Dashboard/Announcements";
import Links from "../../components/Dashboard/Links";
import Office from "../../components/Dashboard/Office";
// User has switched back to the tab
const onFocus = () => {
@@ -87,6 +88,8 @@ function TeamDashboard() {
<div className="flex flex-row items-baseline space-x-5 space-y-5">
<div className="flex flex-col max-w-sm space-y-5">
<TeamVoiceLine />
<Office />
</div>
<div className="flex flex-col space-y-5 flex-1 overflow-auto">
+2
View File
@@ -8,4 +8,6 @@ export enum Collections {
rooms = "rooms",
announcements = "announcements",
links = "links",
officeRooms = "officeRooms",
}
+88
View File
@@ -0,0 +1,88 @@
import {
addDoc,
collection,
doc,
FieldValue,
Firestore,
getFirestore,
serverTimestamp,
setDoc,
writeBatch,
} from "firebase/firestore";
import OfficeRoom from "../models/officeRoom";
import { Collections } from "./collections";
export default class OfficeRoomService {
private db: Firestore = getFirestore();
private batch = writeBatch(this.db);
async createInitialOfficeRooms(createdByUserId: string, teamId: string) {
const entrance = new OfficeRoom("Entrance", teamId, createdByUserId);
const kitchen = new OfficeRoom("Kitchen", teamId, createdByUserId);
const hallway = new OfficeRoom("Hallway", teamId, createdByUserId);
const corner = new OfficeRoom("Corner", teamId, createdByUserId);
const main = new OfficeRoom("Team Hub", teamId, createdByUserId);
const handsOnDeck = new OfficeRoom(
"All Hand On Deck",
teamId,
createdByUserId
);
const initialORs: OfficeRoom[] = [
entrance,
kitchen,
hallway,
corner,
main,
handsOnDeck,
];
initialORs.forEach((oR) => {
const oRRef = doc(this.db, Collections.officeRooms, oR.id);
this.batch.set(oRRef, { ...oR, createdDate: serverTimestamp() });
});
await this.batch.commit();
}
// async createOrUpdateRoom(room: Room) {
// if (room.id) {
// //update
// await this.updateRoom(room);
// } else {
// //create
// const roomDocRef = await addDoc(collection(this.db, Collections.rooms), {
// ...room,
// createdDate: serverTimestamp(),
// });
// }
// }
// async updateMembersInRoom(roomId: string, newMembersInRoom: string[]) {
// // if the room is going to be empty, then change status accordingly
// var status: RoomStatus = RoomStatus.live;
// if (newMembersInRoom.length == 0) {
// status = RoomStatus.empty;
// }
// const docRef = doc(this.db, Collections.rooms, roomId);
// await setDoc(
// docRef,
// {
// status,
// membersInRoom: newMembersInRoom,
// lastUpdatedDate: serverTimestamp(),
// },
// { merge: true }
// );
// }
// async updateRoom(room: Room) {
// const docRef = doc(this.db, Collections.rooms, room.id);
// await setDoc(
// docRef,
// { ...room, lastUpdatedDate: serverTimestamp() },
// { merge: true }
// );
// }
}