getting rid of old modals
This commit is contained in:
@@ -1,231 +0,0 @@
|
||||
import { Divider, Select, Switch, Tooltip } from "antd";
|
||||
const { Option } = Select;
|
||||
|
||||
import Modal from "antd/lib/modal/Modal";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useAuth } from "../../contexts/authContext";
|
||||
import {
|
||||
ShowModalType,
|
||||
useKeyboardContext,
|
||||
} from "../../contexts/keyboardContext";
|
||||
import { useTeamDashboardContext } from "../../contexts/teamDashboardContext";
|
||||
import Link, { LinkType } from "../../models/link";
|
||||
import { SendService } from "../../services/sendService";
|
||||
import LinkIcon from "../LinkIcon";
|
||||
|
||||
const sendService = new SendService();
|
||||
|
||||
export default function CreateOrUpdateLink() {
|
||||
const { currUser } = useAuth();
|
||||
const { pastedLink, handleModalType, showModalType } = useKeyboardContext();
|
||||
const { teamUsers, team } = useTeamDashboardContext();
|
||||
|
||||
useEffect(() => {
|
||||
if (pastedLink) {
|
||||
setLink(pastedLink ?? "");
|
||||
}
|
||||
}, [pastedLink]);
|
||||
|
||||
function closeModal() {
|
||||
handleModalType(ShowModalType.na);
|
||||
}
|
||||
|
||||
function handleSelectRecipients(value) {
|
||||
// passed in array of selections...userIds
|
||||
|
||||
setRecipientsSelected(value);
|
||||
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
function handleSelectRecipientMode(isChecked) {
|
||||
// clear the list of recipients if team selected
|
||||
if (isChecked) {
|
||||
setRecipientsSelected([]);
|
||||
setIsTeamLink(true);
|
||||
} else {
|
||||
setRecipientsSelected([]);
|
||||
setIsTeamLink(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmitLink() {
|
||||
if (!link || !name) {
|
||||
toast.error("Please add a valid link and name");
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!isTeamLink &&
|
||||
(!recipientsSelected || recipientsSelected.length == 0)
|
||||
) {
|
||||
toast.error(
|
||||
"Please select members or send it to the team with the toggle"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// if it's a team link, make sure recipients is null ... but the model should handle this for us?
|
||||
|
||||
try {
|
||||
const newLink = new Link(
|
||||
name,
|
||||
description,
|
||||
link,
|
||||
team.id,
|
||||
recipientsSelected,
|
||||
currUser.uid
|
||||
);
|
||||
|
||||
handleModalType(ShowModalType.na);
|
||||
|
||||
// send to database
|
||||
await sendService.sendLink(newLink);
|
||||
|
||||
resetForm();
|
||||
|
||||
toast.success("link sent");
|
||||
} catch (error) {
|
||||
toast.error("Something went wrong in sending the link.");
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
setLink("");
|
||||
setName("");
|
||||
setDescription("");
|
||||
setShowMoreDetails(false);
|
||||
setIsTeamLink(true);
|
||||
setRecipientsSelected([]);
|
||||
}
|
||||
|
||||
const [link, setLink] = useState<string>("");
|
||||
const [name, setName] = useState<string>("");
|
||||
const [description, setDescription] = useState<string>("");
|
||||
const [showMoreDetails, setShowMoreDetails] = useState<boolean>(false);
|
||||
const [isTeamLink, setIsTeamLink] = useState<boolean>(true);
|
||||
const [recipientsSelected, setRecipientsSelected] = useState<string[]>([]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Link Details"
|
||||
visible={showModalType == ShowModalType.createLink}
|
||||
onCancel={closeModal}
|
||||
onOk={handleSubmitLink}
|
||||
>
|
||||
<div className="flex flex-col space-y-5">
|
||||
<span className="flex flex-col items-start">
|
||||
<span className="text-lg">Link</span>
|
||||
<span className="text-gray-300 text-xs mb-2">
|
||||
Please make sure this is valid for others to access.
|
||||
</span>
|
||||
{/* icon and link input */}
|
||||
<span className="flex flex-row items-center space-x-2 w-full">
|
||||
<LinkIcon className="text-3xl" linkType={Link.getLinkType(link)} />
|
||||
|
||||
<input
|
||||
autoFocus
|
||||
className="flex-1 rounded-lg bg-gray-50 p-3"
|
||||
value={link}
|
||||
placeholder="https://jira.atlassian.com/team/xxx"
|
||||
onChange={(e) => setLink(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-col items-start">
|
||||
<span className="text-lg">Name</span>
|
||||
<span className="text-gray-300 text-xs mb-2">
|
||||
Make sure this makes sense to who you are sending it to.
|
||||
</span>
|
||||
|
||||
<input
|
||||
className="w-full rounded-lg bg-gray-50 p-3"
|
||||
value={name}
|
||||
placeholder="ex. User Story - Customer Creating Orders"
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-col items-start">
|
||||
<span className="text-lg">Recipients</span>
|
||||
<span className="text-gray-300 text-xs mb-2">
|
||||
Choose team or individual recipients
|
||||
</span>
|
||||
|
||||
<span className="mb-2">
|
||||
<Switch
|
||||
defaultChecked
|
||||
onChange={handleSelectRecipientMode}
|
||||
checkedChildren={<span>Team</span>}
|
||||
unCheckedChildren={<span>Members</span>}
|
||||
/>
|
||||
</span>
|
||||
|
||||
{/* select team members to send to */}
|
||||
{!isTeamLink ? (
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: "100%" }}
|
||||
placeholder="Please select team members"
|
||||
onChange={handleSelectRecipients}
|
||||
value={recipientsSelected}
|
||||
optionLabelProp="label"
|
||||
filterOption={(input, option) =>
|
||||
option.props.label.toLowerCase().indexOf(input.toLowerCase()) >=
|
||||
0
|
||||
}
|
||||
>
|
||||
{teamUsers.map((tu) => {
|
||||
return (
|
||||
<Option key={tu.id} label={tu.firstName}>
|
||||
{tu.firstName} {tu.lastName}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</span>
|
||||
|
||||
{showMoreDetails ? (
|
||||
<>
|
||||
<Divider />
|
||||
|
||||
<button
|
||||
className="text-sm text-gray-300 text-left underline decoration-gray-300"
|
||||
onClick={() => setShowMoreDetails(false)}
|
||||
>
|
||||
Hide details...
|
||||
</button>
|
||||
|
||||
<span className="flex flex-col items-start">
|
||||
<span className="text-md">Description</span>
|
||||
<span className="text-gray-300 text-xs mb-2">
|
||||
Optional - Add any pointers about this file.
|
||||
</span>
|
||||
|
||||
<input
|
||||
className="w-full rounded-lg bg-gray-50 p-3"
|
||||
value={description}
|
||||
placeholder="ex. Please review this and add feedback asap"
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<button
|
||||
className="text-sm text-gray-300 text-left underline decoration-gray-300"
|
||||
onClick={() => setShowMoreDetails(true)}
|
||||
>
|
||||
Click to show more details...
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -1,532 +0,0 @@
|
||||
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 { GlobalHotKeys, KeyMap } from "react-hotkeys";
|
||||
import { useAuth } from "../../contexts/authContext";
|
||||
import {
|
||||
ShowModalType,
|
||||
useKeyboardContext,
|
||||
} from "../../contexts/keyboardContext";
|
||||
import { useTeamDashboardContext } from "../../contexts/teamDashboardContext";
|
||||
import Room, { RoomStatus, RoomType } from "../../models/room";
|
||||
import { User } from "../../models/user";
|
||||
import RoomService from "../../services/roomService";
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
const roomService = new RoomService();
|
||||
|
||||
interface IModalProps {
|
||||
show: boolean;
|
||||
updateRoom: Room;
|
||||
handleClose: Function;
|
||||
}
|
||||
|
||||
export default function CreateOrUpdateRoomModal(props: IModalProps) {
|
||||
const { currUser } = useAuth();
|
||||
const { teamUsers, team, user } = useTeamDashboardContext();
|
||||
const { pastedLink, handleModalType, showModalType } = useKeyboardContext();
|
||||
|
||||
// handle when we want to update a room and props changes
|
||||
// prefill with existing stuff
|
||||
useEffect(() => {
|
||||
console.log("change in props");
|
||||
|
||||
if (props.updateRoom) {
|
||||
setRoomLink(props.updateRoom.link);
|
||||
setRoomName(props.updateRoom.name);
|
||||
setRoomDescription(props.updateRoom.description);
|
||||
if (props.updateRoom.attachments && props.updateRoom.attachments[0]) {
|
||||
setRoomAttachment(props.updateRoom.attachments[0]);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}, [props.updateRoom]);
|
||||
|
||||
// update state when user does ctrl + v
|
||||
useEffect(() => {
|
||||
// todo: check if link is valid google meet link? again?
|
||||
console.log("updated link!!!!!");
|
||||
setRoomLink(pastedLink);
|
||||
}, [pastedLink]);
|
||||
|
||||
const handleCloseModal = () => {
|
||||
resetForm();
|
||||
|
||||
props.handleClose();
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
// make sure link, room, and type are selected
|
||||
if (!roomName) {
|
||||
toast.error("Please fill in room link and name.");
|
||||
return;
|
||||
}
|
||||
if (!roomLink && !hasGSuite) {
|
||||
toast.error("must provide room link if you don't have a GSuite");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const newRoom = new Room();
|
||||
|
||||
if (roomAttachment) {
|
||||
newRoom.attachments = [roomAttachment];
|
||||
}
|
||||
|
||||
if (hasGSuite) {
|
||||
// create google meet link based on the room name without spaces
|
||||
var slugName =
|
||||
user.firstName +
|
||||
"-" +
|
||||
"room" +
|
||||
moment(new Date()).format("dddddohmma");
|
||||
slugName = slugName.replace(/\s/g, "-");
|
||||
|
||||
const autoLink =
|
||||
"https://accounts.google.com/AccountChooser/signinchooser?continue=https://g.co/meet/" +
|
||||
slugName;
|
||||
|
||||
newRoom.link = autoLink;
|
||||
} else {
|
||||
newRoom.link = roomLink;
|
||||
}
|
||||
|
||||
if (roomType == RoomType.now) {
|
||||
// make sure approximate time isn't selected
|
||||
newRoom.approximateDateTime = null;
|
||||
newRoom.status = RoomStatus.live;
|
||||
|
||||
// automatically add me to the room
|
||||
newRoom.membersInRoom = [];
|
||||
|
||||
// navigate to the new room automatically
|
||||
// window.open(roomLink, "_blank");
|
||||
} else if (roomType == RoomType.scheduled) {
|
||||
// make sure that either appx or time picker is selected, not both
|
||||
if (!dateTimePicker) {
|
||||
toast.error("Please select a date and time!");
|
||||
return;
|
||||
}
|
||||
|
||||
newRoom.approximateDateTime = null;
|
||||
|
||||
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.members = [...membersSelected]; // add currUser to the list of "people"
|
||||
newRoom.type = roomType;
|
||||
newRoom.description = roomDescription;
|
||||
newRoom.name = roomName;
|
||||
newRoom.createdByUserId = currUser.uid;
|
||||
newRoom.teamId = team.id;
|
||||
|
||||
if (props.updateRoom) {
|
||||
newRoom.id = props.updateRoom.id;
|
||||
newRoom.membersInRoom = props.updateRoom.membersInRoom;
|
||||
toast.success("updated room");
|
||||
} else {
|
||||
toast.success("created room");
|
||||
}
|
||||
|
||||
console.log(newRoom);
|
||||
|
||||
handleModalType(ShowModalType.na);
|
||||
|
||||
await roomService.createOrUpdateRoom(newRoom);
|
||||
|
||||
resetForm();
|
||||
} catch (error) {
|
||||
toast.error("problem creating/updating room");
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
function resetForm() {
|
||||
setRoomLink("");
|
||||
setRoomName(
|
||||
user.firstName +
|
||||
"'s Room - " +
|
||||
moment(new Date()).format("dddd do h:mm a")
|
||||
);
|
||||
setRoomDescription("");
|
||||
setMembersSelected([currUser.uid] as string[]);
|
||||
setRoomAttachment("");
|
||||
setRoomAppxDateTime("");
|
||||
setRoomType(RoomType.now);
|
||||
|
||||
setDateTimePicker(null);
|
||||
|
||||
setShowMoreDetails(false);
|
||||
|
||||
sethasGSuite(true);
|
||||
}
|
||||
|
||||
const [roomLink, setRoomLink] = useState<string>(pastedLink ?? "");
|
||||
const [roomName, setRoomName] = useState<string>(
|
||||
user.firstName + "'s Room - " + moment(new Date()).format("dddd do h:mm a")
|
||||
);
|
||||
const [roomDescription, setRoomDescription] = useState<string>("");
|
||||
|
||||
const [roomAttachment, setRoomAttachment] = useState<string>("");
|
||||
const [membersSelected, setMembersSelected] = useState<string[]>([
|
||||
currUser.uid,
|
||||
]);
|
||||
|
||||
const [roomType, setRoomType] = useState<RoomType>(RoomType.now);
|
||||
const [roomAppxDateTime, setRoomAppxDateTime] = useState<string>(""); // for certain room types
|
||||
const [dateTimePicker, setDateTimePicker] = useState(null);
|
||||
|
||||
const [showMoreDetails, setShowMoreDetails] = useState<boolean>(false);
|
||||
const [hasGSuite, sethasGSuite] = useState<boolean>(true);
|
||||
|
||||
function handleSelectMember(value) {
|
||||
// passed in array of selections...userIds
|
||||
|
||||
setMembersSelected(value);
|
||||
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
function handleDateTimePickerChange(time) {
|
||||
console.log(time);
|
||||
|
||||
setRoomAppxDateTime("");
|
||||
|
||||
setDateTimePicker(time);
|
||||
}
|
||||
|
||||
const allUsersForSelection: User[] = [...teamUsers, user];
|
||||
|
||||
const MemberSelection = () => {
|
||||
return (
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: "100%" }}
|
||||
placeholder="Please select team members"
|
||||
onChange={handleSelectMember}
|
||||
value={membersSelected}
|
||||
optionLabelProp="label"
|
||||
filterOption={(input, option) =>
|
||||
option.props.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}
|
||||
>
|
||||
{allUsersForSelection.map((tu) => {
|
||||
return (
|
||||
<Option key={tu.id} label={tu.firstName}>
|
||||
{tu.firstName} {tu.lastName}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
async function createRoomNow() {
|
||||
console.log("creating room");
|
||||
|
||||
// reset form for the right values to be in there
|
||||
resetForm();
|
||||
|
||||
// submit form
|
||||
// handleSubmit().then((res) => console.log(res));
|
||||
|
||||
const newRoom = new Room();
|
||||
|
||||
// create google meet link based on the room name without spaces
|
||||
var slugName =
|
||||
user.firstName + "-" + "room" + moment(new Date()).format("dddddohmma");
|
||||
slugName = slugName.replace(/\s/g, "-");
|
||||
|
||||
const autoLink =
|
||||
"https://accounts.google.com/AccountChooser/signinchooser?continue=https://g.co/meet/" +
|
||||
slugName;
|
||||
|
||||
newRoom.link = autoLink;
|
||||
newRoom.status = RoomStatus.empty;
|
||||
newRoom.membersInRoom = [];
|
||||
newRoom.approximateDateTime = null;
|
||||
|
||||
newRoom.members = [currUser.uid]; // add currUser to the list of "people"
|
||||
newRoom.type = RoomType.now;
|
||||
newRoom.name = roomName;
|
||||
newRoom.createdByUserId = currUser.uid;
|
||||
newRoom.teamId = team.id;
|
||||
|
||||
console.log(newRoom);
|
||||
|
||||
handleModalType(ShowModalType.na);
|
||||
|
||||
await roomService.createOrUpdateRoom(newRoom);
|
||||
|
||||
resetForm();
|
||||
|
||||
toast.success("created room");
|
||||
}
|
||||
|
||||
const keyMap: KeyMap = {
|
||||
CREATE_ROOM_NOW: {
|
||||
name: "create room now",
|
||||
sequence: "q",
|
||||
action: "keyup",
|
||||
},
|
||||
};
|
||||
const handlers = {
|
||||
CREATE_ROOM_NOW: createRoomNow,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<GlobalHotKeys keyMap={keyMap} handlers={handlers} />
|
||||
|
||||
<Modal
|
||||
title="Room Details"
|
||||
centered
|
||||
visible={props.show}
|
||||
onOk={handleSubmit}
|
||||
onCancel={handleCloseModal}
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
{hasGSuite ? (
|
||||
<span className="flex flex-col items-start">
|
||||
<span className="text-lg">Link</span>
|
||||
<span className="text-gray-300 text-xs flex-1">
|
||||
We'll create a link for you. Don't have a GSuite?{" "}
|
||||
<button
|
||||
onClick={() => sethasGSuite(false)}
|
||||
className="text-blue-500"
|
||||
>
|
||||
Click here.
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="flex flex-col items-start">
|
||||
<span className="text-lg">Link</span>
|
||||
{roomLink ? (
|
||||
<span className="text-gray-300 text-xs mb-2">
|
||||
Please make sure this is valid so that your team can join
|
||||
properly.
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-xs mb-2">
|
||||
<a
|
||||
href="https://meet.google.com/new"
|
||||
target={"_blank"}
|
||||
rel={"noreferrer"}
|
||||
className=""
|
||||
>
|
||||
Click here to create one
|
||||
</a>{" "}
|
||||
and then come back and paste the link for your team.{" "}
|
||||
<button
|
||||
onClick={() => sethasGSuite(true)}
|
||||
className="text-blue-500"
|
||||
>
|
||||
Have a GSuite? Click here.
|
||||
</button>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<input
|
||||
autoFocus
|
||||
className="w-full rounded-lg bg-gray-50 p-3"
|
||||
value={roomLink}
|
||||
placeholder="https://meet.google.com/xxx-xxxx"
|
||||
onChange={(e) => setRoomLink(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<span className="flex flex-col items-start flex-1 mt-4 ">
|
||||
<span className="text-lg">Room Name</span>
|
||||
<span className="text-gray-300 text-xs mb-2 flex-1">
|
||||
Be specific enough, everyone down the hall will see this.
|
||||
</span>
|
||||
<input
|
||||
placeholder="ex. Design - Ecommerce Figma"
|
||||
className="w-full rounded-lg bg-gray-50 p-3"
|
||||
value={roomName}
|
||||
onChange={(e) => setRoomName(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
|
||||
{/* room type selection */}
|
||||
<span className="flex flex-col items-start flex-1 mt-4 ">
|
||||
<span className="text-lg">Type</span>
|
||||
<span className="text-gray-300 text-xs mb-2 flex-1"></span>
|
||||
<Radio.Group
|
||||
value={roomType}
|
||||
onChange={(event) => setRoomType(event.target.value)}
|
||||
>
|
||||
<Radio.Button value={RoomType.now}>{RoomType.now}</Radio.Button>
|
||||
<Radio.Button value={RoomType.scheduled}>
|
||||
{RoomType.scheduled}
|
||||
</Radio.Button>
|
||||
<Radio.Button value={RoomType.recurring}>
|
||||
{RoomType.recurring}
|
||||
</Radio.Button>
|
||||
</Radio.Group>
|
||||
|
||||
{roomType == RoomType.recurring ? (
|
||||
<Tooltip
|
||||
title={`Put things like "ping me when ready" or "sometime this afternoon"`}
|
||||
>
|
||||
<span className="flex flex-col items-stretch flex-1 mt-4">
|
||||
<span className="text-md">Approximate Slot</span>
|
||||
<span className="text-gray-300 text-xs mb-2 flex-1">
|
||||
Sometimes you don't have a specific time or want to
|
||||
propose a rough period.
|
||||
</span>
|
||||
<input
|
||||
placeholder="ex. 2pm-ish...after lunch...every evening"
|
||||
className="w-full rounded-lg bg-gray-50 p-3"
|
||||
value={roomAppxDateTime}
|
||||
onChange={(e) => setRoomAppxDateTime(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{roomType == RoomType.scheduled ? (
|
||||
<span className="flex flex-col items-start flex-1 mt-4">
|
||||
<span className="text-md">Specific Time</span>
|
||||
{/* <TimePicker
|
||||
minuteStep={15}
|
||||
use12Hours
|
||||
format="h:mm a"
|
||||
value={timePicker}
|
||||
defaultValue={moment(new Date())}
|
||||
onChange={handleTimePickerChange}
|
||||
/> */}
|
||||
|
||||
<DatePicker
|
||||
minuteStep={15}
|
||||
use12Hours
|
||||
format="YYYY-MM-DD h:mm a"
|
||||
value={dateTimePicker}
|
||||
onChange={handleDateTimePickerChange}
|
||||
showTime={{ defaultValue: moment("00:00:00", "HH:mm:ss") }}
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</span>
|
||||
|
||||
{/* people selection */}
|
||||
<span className="flex flex-col items-start flex-1 mt-4">
|
||||
<span className="flex flex-row w-full items-center">
|
||||
<span className="text-lg flex-1">People</span>
|
||||
{/* team or personal */}
|
||||
|
||||
<span className="flex flex-col items-end">
|
||||
<Tooltip
|
||||
title={
|
||||
"Private mode coming soon, but keep it collaborative for now."
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
disabled={true}
|
||||
defaultChecked
|
||||
checkedChildren={<span>Visible</span>}
|
||||
unCheckedChildren={<span>Private</span>}
|
||||
/>
|
||||
</Tooltip>
|
||||
<span className="text-gray-300 text-xs mb-2 flex-1">
|
||||
Team sees this room.
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span className="text-gray-300 text-xs mb-2 flex-1">
|
||||
Optional - Add any mandatory attendees you want or just tell them
|
||||
later.
|
||||
</span>
|
||||
{MemberSelection()}
|
||||
</span>
|
||||
|
||||
{showMoreDetails ? (
|
||||
<>
|
||||
<Divider />
|
||||
|
||||
<button
|
||||
className="text-sm text-gray-300 text-left underline decoration-gray-300"
|
||||
onClick={() => setShowMoreDetails(false)}
|
||||
>
|
||||
Hide details...
|
||||
</button>
|
||||
|
||||
<span className="flex flex-col items-start flex-1 mt-4">
|
||||
<span className="text-md">Agenda</span>
|
||||
<span className="text-gray-300 text-xs mb-2 flex-1">
|
||||
Optional
|
||||
</span>
|
||||
<textarea
|
||||
placeholder="ex. Let's discuss ways to..."
|
||||
className="w-full rounded-lg bg-gray-50 p-3"
|
||||
value={roomDescription}
|
||||
onChange={(e) => setRoomDescription(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-col items-start flex-1 mt-4">
|
||||
<span className="text-md">Attachment</span>
|
||||
<span className="text-gray-300 text-xs mb-2">
|
||||
Optional - ppt, meeting notes...
|
||||
</span>
|
||||
<span className="text-gray-300 text-xs mb-2">
|
||||
have multiple? just post it in the team attachments
|
||||
</span>
|
||||
<input
|
||||
placeholder="https://"
|
||||
className="w-full rounded-lg bg-gray-50 p-3"
|
||||
value={roomAttachment}
|
||||
onChange={(e) => setRoomAttachment(e.target.value)}
|
||||
/>
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<button
|
||||
className="text-sm text-gray-300 text-left underline decoration-gray-300 mt-5"
|
||||
onClick={() => setShowMoreDetails(true)}
|
||||
>
|
||||
Click to show more details...
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
import { Avatar, Modal, Tooltip } from "antd";
|
||||
import { Message } from "../../models/message";
|
||||
import { FaBackward } from "react-icons/fa";
|
||||
import { useTeamDashboardContext } from "../../contexts/teamDashboardContext";
|
||||
import { useAuth } from "../../contexts/authContext";
|
||||
import { useKeyboardContext } from "../../contexts/keyboardContext";
|
||||
import moment from "moment";
|
||||
|
||||
export default function PowerPlayer(props: {
|
||||
show: boolean;
|
||||
handleCloseModal: Function;
|
||||
}) {
|
||||
const { currUser } = useAuth();
|
||||
const { allMessages, teamUsersMap } = useTeamDashboardContext();
|
||||
const { handleAddAudioToQueue } = useKeyboardContext();
|
||||
// two arrays:
|
||||
// 1. all of my messages in order date desc => top
|
||||
// const sentMessages = allMessages.filter(msg => msg.senderUserId == currUser.uid)
|
||||
|
||||
// // 2. all of incoming messages in order date desc => bottom
|
||||
// const receivedMessages = allMessages.filter(msg => msg.receiverUserId == currUser.uid)
|
||||
|
||||
const messageRangeHalfToPlay = 2;
|
||||
function handlePlayAudio(url: string) {
|
||||
// todo play like 2 indexes lower to 2 indexes higher instead of
|
||||
// const indexOfMessage = 5;
|
||||
|
||||
// var startPlay = indexOfMessage - messageRangeHalfToPlay;
|
||||
// if (startPlay < 0) {
|
||||
// startPlay = 0;
|
||||
// }
|
||||
|
||||
// var endPlay = indexOfMessage + messageRangeHalfToPlay;
|
||||
// if (endPlay > allMessages.length) {
|
||||
// endPlay = allMessages.length;
|
||||
// }
|
||||
|
||||
// // loop through start to end and add to queue
|
||||
// var convoChunk: string[] = []
|
||||
|
||||
handleAddAudioToQueue([url], true);
|
||||
}
|
||||
|
||||
function handleClose(e) {
|
||||
props.handleCloseModal();
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Power Playback "
|
||||
visible={props.show}
|
||||
onCancel={handleClose}
|
||||
footer={
|
||||
<button
|
||||
onClick={handleClose}
|
||||
className="ml-auto text-sm text-orange-500 font-semibold py-1 px-4 bg-gray-200 rounded"
|
||||
>
|
||||
👋 Close
|
||||
</button>
|
||||
}
|
||||
>
|
||||
<span className="flex flex-col items-start">
|
||||
<span>One timeline to listen to the past 24 hours.</span>
|
||||
|
||||
<span className="text-sm text-gray-400">
|
||||
The bottom are your messages. The top are incoming messages. Click on
|
||||
the bubbles to listen to conversations during that period.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div className="flex flex-col py-20 overflow-x-scroll">
|
||||
{/* top incoming messages */}
|
||||
<div className="flex flex-row">
|
||||
{allMessages.map((msg, i) => {
|
||||
const relativeDateTime: string = moment(
|
||||
msg.createdDate.toDate()
|
||||
).fromNow();
|
||||
|
||||
if (msg.senderUserId == currUser.uid) {
|
||||
// if I am the sender
|
||||
const receiverUser = teamUsersMap[msg.receiverUserId];
|
||||
|
||||
if (!receiverUser) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
"you -> " + receiverUser.nickName + ": " + relativeDateTime
|
||||
}
|
||||
>
|
||||
<span
|
||||
key={i}
|
||||
onClick={() => handlePlayAudio(msg.audioDataUrl)}
|
||||
className="border-r-2 border-r-sky-400 translate-y-10 min-w-max hover:cursor-pointer border-t-2 border-t-black"
|
||||
>
|
||||
<Avatar.Group className="translate-x-8 pl-2 translate-y-10">
|
||||
<Avatar src={receiverUser.avatarUrl} />
|
||||
{/* <Avatar src={currUser.photoURL} /> */}
|
||||
<div className="rounded-full w-8 h-8 -translate-x-2 bg-teal-500"></div>
|
||||
</Avatar.Group>
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
const sender = teamUsersMap[msg.senderUserId];
|
||||
|
||||
// incoming messages
|
||||
return (
|
||||
<span
|
||||
key={i}
|
||||
onClick={() => handlePlayAudio(msg.audioDataUrl)}
|
||||
className="border-r-2 border-r-orange-400 min-w-max hover:cursor-pointer border-b-2 border-b-black"
|
||||
>
|
||||
<Tooltip title={sender?.firstName + ": " + relativeDateTime}>
|
||||
<img
|
||||
src={sender ? sender?.avatarUrl : "K"}
|
||||
alt="K"
|
||||
className="rounded-full w-10 h-10 translate-x-2/4 -translate-y-2/4"
|
||||
/>
|
||||
</Tooltip>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* middle line */}
|
||||
{/* <div className="border border-b-2 border-b-black flex-1 w-full"></div> */}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -1,547 +0,0 @@
|
||||
import { Carousel, Divider, Drawer, Modal } from "antd";
|
||||
import { CarouselRef } from "antd/lib/carousel";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { GlobalHotKeys, KeyMap } from "react-hotkeys";
|
||||
import { BsThreeDots } from "react-icons/bs";
|
||||
import {
|
||||
FaArrowLeft,
|
||||
FaArrowRight,
|
||||
FaClock,
|
||||
FaLink,
|
||||
FaPlus,
|
||||
FaUserCheck,
|
||||
} from "react-icons/fa";
|
||||
import { FcGoogle } from "react-icons/fc";
|
||||
import { useKeyboardContext } from "../../contexts/keyboardContext";
|
||||
import Rooms from "../demo/Rooms";
|
||||
import Image from "next/image";
|
||||
import Cookies from "js-cookie";
|
||||
import { CookieType } from "../../helpers/cookies";
|
||||
|
||||
export default function ShortcutHelpModal() {
|
||||
const [visible, setVisible] = useState<boolean>(false);
|
||||
const carouselRef = useRef<CarouselRef>();
|
||||
|
||||
const { isRecording } = useKeyboardContext();
|
||||
|
||||
useEffect(() => {
|
||||
// if have the specific cookie, then don't show the modal, otherwise show the modal
|
||||
const cookie = Cookies.get(CookieType.TEAM_SHORTCUTS_ONBOARDING);
|
||||
if (!cookie) {
|
||||
setVisible(true);
|
||||
Cookies.set(CookieType.TEAM_SHORTCUTS_ONBOARDING, "true");
|
||||
}
|
||||
}, []);
|
||||
|
||||
function handleShowModal() {
|
||||
setVisible(true);
|
||||
}
|
||||
function handleDismissModal() {
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
const keyMap: KeyMap = {
|
||||
SHOW_HELP_MODAL: {
|
||||
name: "show help modal",
|
||||
sequence: "/",
|
||||
action: "keyup",
|
||||
},
|
||||
};
|
||||
const handlers = { SHOW_HELP_MODAL: handleShowModal };
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* fixed help on bottom left */}
|
||||
<span
|
||||
onClick={handleShowModal}
|
||||
className="hover:cursor-pointer z-50 backdrop-blur-md fixed bottom-10 right-10 bg-gray-200 bg-opacity-80 py-2 px-3 rounded text-gray-500 flex flex-row items-center space-x-2"
|
||||
>
|
||||
<span>Help</span>
|
||||
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-500 text-sm font-bold`}
|
||||
>
|
||||
/
|
||||
</button>
|
||||
</span>
|
||||
|
||||
<GlobalHotKeys keyMap={keyMap} handlers={handlers} />
|
||||
|
||||
{/* <Drawer
|
||||
title="Help"
|
||||
placement={"right"}
|
||||
closable={false}
|
||||
onClose={handleDismissModal}
|
||||
visible={visible}
|
||||
zIndex={0}
|
||||
></Drawer> */}
|
||||
|
||||
<Modal
|
||||
title="Help"
|
||||
onCancel={handleDismissModal}
|
||||
visible={visible}
|
||||
footer={<></>}
|
||||
zIndex={5}
|
||||
width={750}
|
||||
>
|
||||
<Carousel ref={carouselRef} dotPosition="top" className="pt-5">
|
||||
<div>
|
||||
<span className="flex flex-col px-10">
|
||||
<span className="flex flex-row justify-between items-start mb-10">
|
||||
<FaArrowLeft
|
||||
onClick={() => carouselRef.current.prev()}
|
||||
className="hover:cursor-pointer bg-teal-600 text-white p-1 rounded-full text-xl"
|
||||
/>
|
||||
|
||||
<span className="flex flex-col items-center">
|
||||
<span className="text-xl">Live Collaboration</span>
|
||||
<span className="text-md text-gray-300 text-center">
|
||||
Building the habit of{" "}
|
||||
<span className="text-teal-600">
|
||||
{" "}
|
||||
resolving issues on the spot
|
||||
</span>{" "}
|
||||
<br></br>
|
||||
through seamless communication.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<FaArrowRight
|
||||
onClick={() => carouselRef.current.next()}
|
||||
className="hover:cursor-pointer bg-teal-600 text-white p-1 rounded-full text-xl"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<span className="flex flex-col ml-2 items-start justify-start">
|
||||
<span className="text-lg text-gray-500 text-left">
|
||||
Hop into Office Rooms
|
||||
</span>
|
||||
<span className="text-md text-gray-300 text-left">
|
||||
Work with your closest teammates in the{" "}
|
||||
<span className="text-teal-600"> hallway or corner </span>
|
||||
throughout the day.
|
||||
<br></br> Have lunch and take breaks in the{" "}
|
||||
<span className="text-teal-600">kitchen.</span>
|
||||
</span>
|
||||
</span>
|
||||
<img
|
||||
src="/screenshots/officerooms.png"
|
||||
className="h-[15rem] rounded-lg"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
{/* spontaneous bug room */}
|
||||
<span
|
||||
className="shrink-0 h-[15rem] flex flex-col bg-gray-200 bg-opacity-80
|
||||
rounded-lg justify-between w-80 max-w-screen-sm m-2 overflow-clip shadow-lg"
|
||||
>
|
||||
{/* header */}
|
||||
<span className="flex flex-1 flex-row justify-between items-baseline space-x-1 p-5">
|
||||
{/* meeting details */}
|
||||
<span className="flex flex-col items-baseline justify-start max-w-xs pr-10">
|
||||
<span className="text-gray-500 font-semibold mr-auto">
|
||||
bug fixing
|
||||
</span>
|
||||
<span className="text-xs text-gray-400 overflow-wrap mb-auto h-full">
|
||||
were just fixing that jsx bug thats a paiiinnnn
|
||||
</span>
|
||||
|
||||
{/* badges and tags */}
|
||||
<span className="flex flex-row flex-wrap mt-auto">
|
||||
<span className="text-xs m-1 text-white bg-red-400 p-1 rounded-md font-bold flex flex-row items-center">
|
||||
<span>blockers</span>
|
||||
</span>
|
||||
|
||||
<span className="text-xs m-1 text-white bg-indigo-400 p-1 rounded-md font-bold flex flex-row items-center">
|
||||
<span>engineering</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{/* room status */}
|
||||
<span className="flex flex-col items-end space-y-1 justify-between h-full">
|
||||
<span
|
||||
className="text-xs bg-red-500
|
||||
text-white font-bold p-1 rounded-md flex flex-row space-x-2 items-center"
|
||||
>
|
||||
<FaClock />
|
||||
<span>live</span>
|
||||
</span>
|
||||
|
||||
{/* room attachments */}
|
||||
<span className="flex flex-row space-x-2">
|
||||
<button className="bg-gray-400 bg-opacity-25 p-2 ml-auto rounded hover:bg-opacity-40">
|
||||
<FaLink className="text-sm text-gray-400" />
|
||||
</button>
|
||||
|
||||
<button className="bg-gray-400 bg-opacity-25 p-2 ml-auto rounded hover:bg-opacity-40">
|
||||
<FaLink className="text-sm text-gray-400" />
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{/* footer */}
|
||||
<span className="flex flex-row items-center bg-gray-400 bg-opacity-30 p-3">
|
||||
<span className="inline-flex flex-row-reverse items-center shrink-0 mr-1">
|
||||
<span className="relative flex">
|
||||
<span className="bg-gray-200 rounded-full shadow-md absolute w-full h-full"></span>
|
||||
<Image
|
||||
className=""
|
||||
src={
|
||||
"/avatars/svg/Artboards_Diversity_Avatars_by_Netguru-20.svg"
|
||||
}
|
||||
alt="profile"
|
||||
width={30}
|
||||
height={30}
|
||||
/>
|
||||
</span>
|
||||
<span className="-mr-4 relative flex">
|
||||
<span className="bg-gray-200 rounded-full shadow-md absolute w-full h-full"></span>
|
||||
<Image
|
||||
className=""
|
||||
src={
|
||||
"/avatars/svg/Artboards_Diversity_Avatars_by_Netguru-22.svg"
|
||||
}
|
||||
alt="profile"
|
||||
width={30}
|
||||
height={30}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-xs text-gray-400">
|
||||
Arjun and Liam
|
||||
</span>
|
||||
<button className="ml-auto text-sm text-orange-500 font-semibold py-1 px-4 bg-gray-200 rounded">
|
||||
👋 Leave
|
||||
</button>
|
||||
<BsThreeDots className="text-white ml-2 hover:cursor-pointer" />{" "}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-col ml-2 items-end">
|
||||
<span className="text-lg text-gray-500">
|
||||
Create a Meeting Room
|
||||
</span>
|
||||
<span className={`text-md text-gray-300 text-right`}>
|
||||
Click on the{" "}
|
||||
<button className="inline bg-gray-300 bg-opacity-25 p-1 rounded hover:bg-opacity-40">
|
||||
<FaPlus className="text-md text-white" />
|
||||
</button>{" "}
|
||||
to create a formal <FcGoogle className="inline text-lg" />{" "}
|
||||
Meet.
|
||||
</span>
|
||||
<span className={`text-md text-teal-600 text-right`}>
|
||||
Spontaneous, scheduled, or recurring rooms.
|
||||
</span>
|
||||
|
||||
<span className="flex flex-row items-center space-x-2">
|
||||
<button className="inline bg-gray-300 bg-opacity-25 p-2 rounded hover:bg-opacity-40">
|
||||
<FaPlus className="text-md text-white" />
|
||||
</button>
|
||||
|
||||
<span>or</span>
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
Q
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<span className="flex flex-col ml-2 items-start">
|
||||
<span className="text-lg text-gray-500">
|
||||
{"Cross Collaborate"}
|
||||
</span>
|
||||
<span className={`text-md text-gray-300 text-left`}>
|
||||
Walk into the office with clarity of what <br></br>
|
||||
<span className="text-teal-600">
|
||||
team conversations{" "}
|
||||
</span>{" "}
|
||||
are going on across the hall.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<img
|
||||
src="/illustrations/undraw_team_collaboration_re_ow29.svg"
|
||||
className="h-[10rem]"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="flex flex-col px-10">
|
||||
<span className="flex flex-row justify-between items-start mb-10">
|
||||
<FaArrowLeft
|
||||
onClick={() => carouselRef.current.prev()}
|
||||
className="hover:cursor-pointer bg-teal-600 text-white p-1 rounded-full text-xl"
|
||||
/>
|
||||
|
||||
<span className="text-xl">Audio Messages</span>
|
||||
|
||||
<FaArrowRight
|
||||
onClick={() => carouselRef.current.next()}
|
||||
className="hover:cursor-pointer bg-teal-600 text-white p-1 rounded-full text-xl"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<span className="flex flex-col ml-2 items-center">
|
||||
<span className="text-lg text-gray-500">
|
||||
Select a Teammate
|
||||
</span>
|
||||
<span className="text-md text-gray-300 text-center">
|
||||
Type numbers on your keyboard.
|
||||
</span>
|
||||
|
||||
<span className="flex flex-row space-x-2">
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
1
|
||||
</button>
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
2
|
||||
</button>
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
3
|
||||
</button>
|
||||
<span className="text-gray-300">...</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<img
|
||||
src="/screenshots/teamvoiceline.png"
|
||||
className="h-[10rem] w-[22rem]"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<img
|
||||
src="/illustrations/undraw_conference_speaker_re_1rna.svg"
|
||||
className="h-[10rem]"
|
||||
/>
|
||||
|
||||
<span className="flex flex-col ml-2 items-center">
|
||||
<span className="text-lg text-gray-500">
|
||||
Send an Audio Message
|
||||
</span>
|
||||
<span className={`text-md text-gray-300 text-center`}>
|
||||
Press and hold R.{" "}
|
||||
<span className="text-teal-600">
|
||||
Your teammate will <br></br> hear you instantly
|
||||
</span>{" "}
|
||||
if they are online.
|
||||
</span>
|
||||
<span className={`text-md text-gray-300 text-center`}>
|
||||
As if they were across the table.
|
||||
</span>
|
||||
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold
|
||||
${isRecording ? "bg-orange-500 text-white" : ""}`}
|
||||
>
|
||||
R
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<span className="flex flex-col ml-2 items-center">
|
||||
<span className="text-lg text-gray-500">
|
||||
Play Incoming Message
|
||||
</span>
|
||||
<span className={`text-md text-gray-300 text-center`}>
|
||||
Select teammate and then press SPACE <br></br> to listen to
|
||||
the last conversation.
|
||||
</span>
|
||||
{/* <span className={`text-md text-gray-300 text-center`}>
|
||||
Deselect teammate by pressing <br></br> ESC.
|
||||
</span> */}
|
||||
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
SPACE
|
||||
</button>
|
||||
</span>
|
||||
|
||||
<img
|
||||
src="/illustrations/undraw_tutorial_video_vtd1.svg"
|
||||
className="h-[10rem]"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<img
|
||||
src="/illustrations/undraw_back_home_nl-5-c.svg"
|
||||
className="h-[10rem]"
|
||||
/>
|
||||
|
||||
<span className="flex flex-col ml-2 items-center">
|
||||
<span className="text-lg text-gray-500">Clear Your View</span>
|
||||
<span className={`text-md text-gray-300 text-center`}>
|
||||
Deselect teammate and <br></br> stop playing audio by
|
||||
pressing ESC.
|
||||
</span>
|
||||
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
ESC
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="flex flex-col px-10">
|
||||
<span className="flex flex-row justify-between items-start mb-10">
|
||||
<FaArrowLeft
|
||||
onClick={() => carouselRef.current.prev()}
|
||||
className="hover:cursor-pointer bg-teal-600 text-white p-1 rounded-full text-xl shrink-0"
|
||||
/>
|
||||
|
||||
<span className="flex flex-col items-center">
|
||||
<span className="text-xl">Drawer</span>
|
||||
<span className="text-md text-gray-300 text-center">
|
||||
Organize your desk and{" "}
|
||||
<span className="text-teal-600">
|
||||
focus on today's priorities.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<img
|
||||
src="/screenshots/drawer.png"
|
||||
className="rounded-lg mt-5"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<FaArrowRight
|
||||
onClick={() => carouselRef.current.next()}
|
||||
className="hover:cursor-pointer bg-teal-600 text-white p-1 rounded-full text-xl shrink-0"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<span className="flex flex-col ml-2 items-start">
|
||||
<span className="text-lg text-gray-500">Add Your Drawer</span>
|
||||
<span className={`text-md text-gray-300 text-left max-w-xs`}>
|
||||
Paste{" "}
|
||||
<span className={`text-teal-600`}>important links:</span>{" "}
|
||||
Jira tickets, ppts, drive files/folders, github, code
|
||||
snippets.
|
||||
</span>
|
||||
|
||||
<span className="flex flex-row items-left">
|
||||
{" "}
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
CTRL
|
||||
</button>{" "}
|
||||
+{" "}
|
||||
<button
|
||||
className={`right-1 rounded-lg py-1 px-2 ml-1
|
||||
shadow-md text-center text-gray-300 text-sm font-bold`}
|
||||
>
|
||||
V
|
||||
</button>{" "}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<img
|
||||
src="/illustrations/undraw_memory_storage_reh0.svg"
|
||||
className="h-[12rem]"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<img
|
||||
src="/illustrations/undraw_team_spirit_re_yl1v.svg"
|
||||
className="h-[12rem]"
|
||||
/>
|
||||
|
||||
<span className="flex flex-col ml-2 items-end max-w-xs">
|
||||
<span className="text-lg text-gray-500">Team Drawer</span>
|
||||
<span className={`text-md text-gray-300 text-right`}>
|
||||
Make sure your team has <br></br> what they need from you.
|
||||
</span>
|
||||
<span className={`text-md text-teal-600 text-right`}>
|
||||
Keep this clean to stay focused.
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className="flex flex-row justify-between items-center">
|
||||
<span className="flex flex-col ml-2 items-start">
|
||||
<span className="text-lg text-gray-500">
|
||||
{"You Decide What You Keep"}
|
||||
</span>
|
||||
<span className={`text-md text-gray-300 text-left`}>
|
||||
Last month's mess is weighing you down.
|
||||
</span>
|
||||
|
||||
<span className={`text-md text-gray-300 text-left`}>
|
||||
Only see{" "}
|
||||
<span className="text-teal-600">
|
||||
this week's files/links
|
||||
</span>{" "}
|
||||
to keep <br></br> your head clear.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<img
|
||||
src="/illustrations/undraw_my_files_swob.svg"
|
||||
className="h-[10rem]"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<Divider />
|
||||
|
||||
<span className={`text-md text-gray-300 text-center`}>
|
||||
NOTE: this is{" "}
|
||||
<span className="text-orange-500">NOT file storage.</span>
|
||||
</span>
|
||||
<span className={`text-md text-gray-300 text-center`}>
|
||||
They are merely bookmarked links <br></br> to your source of
|
||||
truth (Google Drive, Github...).
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</Carousel>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user