diff --git a/src/components/BookAChat/index.tsx b/src/components/BookAChat/index.tsx
index eb1a0a44..a8b8a28a 100644
--- a/src/components/BookAChat/index.tsx
+++ b/src/components/BookAChat/index.tsx
@@ -1,7 +1,7 @@
import { addMinutes } from "date-fns";
import dateFormat from "dateformat";
import _ from "lodash";
-import React, { Fragment, useMemo, useState } from "react";
+import React, { Fragment, useEffect, useMemo, useState } from "react";
import {
CreateChatRequestInput,
DateInterval,
@@ -11,9 +11,11 @@ import {
useGetAvailOverrideDatesQuery,
useGetAvailWeeklysQuery,
useGetChatRequestsQuery,
+ useGetMyUserQuery,
} from "../../generated/graphql";
+import { useCurrentProfile } from "../../hooks";
import useTimezoneConverters from "../../hooks/useTimezoneConverters";
-import { Button, Card, Modal, Text, TextArea } from "../atomic";
+import { Button, Card, Input, Modal, Text, TextArea } from "../atomic";
import Calendar from "../Calendar";
import { getDatesInThisMonth } from "../Calendar/utils";
import OneOptionModal from "../OneOptionModal";
@@ -101,6 +103,8 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
useGetChatRequestsQuery({
variables: { profileId: mentor.profileId },
});
+ const { data: user } = useGetMyUserQuery();
+ const currentProfile = useCurrentProfile();
const [createChatRequest] = useCreateChatRequestMutation({
refetchQueries: [
@@ -112,10 +116,18 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
const [loadingCreateChatRequest, setLoadingCreateChatRequest] =
useState(false);
const [chatRequestMessage, setChatRequestMessage] = useState("");
+ const [location, setlocation] = useState(
+ user?.getMyUser.preferredChatLocation
+ );
+
+ useEffect(() => {
+ setlocation(user?.getMyUser.preferredChatLocation);
+ }, [user?.getMyUser]);
loadingCreateChatRequest; // TODO: Use this variable
- if (!fromUTC || !toUTC) return ;
+ if (!fromUTC || !toUTC || !user || !currentProfile.currentProfile)
+ return ;
const extractDates = (
input: {
@@ -208,19 +220,19 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
return (
-
+
Book a chat with{" "}
{mentor.user.firstName} {mentor.user.lastName}
-
+
If no times are open, the mentor is either completely booked or has not
set availabilities yet.
-
+
@@ -254,14 +266,14 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
/>
-
+
Available Times
-
+
{selectedDate
@@ -270,16 +282,18 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
-
+
{timeslots.map((timeslot) => {
return (
{
setSendChatModalOpen(true);
setSelectedTimeslot(timeslot);
setChatRequestMessage("");
+ setlocation("");
}}
>
{dateFormat(timeslot.startTime, "h:MMtt")} -{" "}
@@ -296,7 +310,7 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
setSendChatModalOpen(false);
}}
>
-
+
Send Chat Request to{" "}
@@ -305,7 +319,7 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
-
+
Date: {" "}
@@ -319,20 +333,39 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
{dateFormat(selectedTimeslot?.endTime, "h:MMtt")}
-
-
+
+
+ Preferred meeting location:
+
+
+ You can set your default preferred location in Profile {">"} My
+ General Profile. Keep in mind that the mentor has the final say on
+ location!
+
+
+
setlocation(e.target.value)}
+ />
+
+
+ Optional Message
+
+
-
+ className="p-2 w-full"
+ placeholder="Hi! My name is John Doe, and I'd love to talk to you about your experience at the circus!"
+ />
+
-
+
{
>
Cancel
-
{
@@ -350,7 +382,9 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
setLoadingCreateChatRequest(true);
const createChatRequestInput: CreateChatRequestInput = {
mentorProfileId: mentor.profileId,
+ menteeProfileId: currentProfile.currentProfile.profileId,
chatRequestMessage: chatRequestMessage,
+ chatLocation: location || "",
chatStartTime: toUTC(selectedTimeslot.startTime).getTime(),
chatEndTime: toUTC(selectedTimeslot.endTime).getTime(),
};
@@ -358,11 +392,13 @@ const BookAChat = ({ mentor }: BookAChatProps) => {
variables: {
data: createChatRequestInput,
},
- }).then(() => {
- setLoadingCreateChatRequest(false);
- setSendChatModalOpen(false);
- _.delay(setChatSentConfirmModalOpen, 250, true);
- });
+ })
+ .catch((err) => console.log(err))
+ .then(() => {
+ setLoadingCreateChatRequest(false);
+ setSendChatModalOpen(false);
+ _.delay(setChatSentConfirmModalOpen, 250, true);
+ });
}}
>
Send
diff --git a/src/components/ProfileModal.tsx b/src/components/ProfileModal.tsx
index 5bf44c79..45a04dd0 100644
--- a/src/components/ProfileModal.tsx
+++ b/src/components/ProfileModal.tsx
@@ -75,15 +75,25 @@ const ProfileModal = ({
-
-
-
- Email:
-
-
- {profile.user.email}
-
-
+
+
+
+
+ Email:
+
+
+ {profile.user.email}
+
+
+
+
+ Preferred Location:
+
+
+ {profile.user.preferredChatLocation}
+
+
+
diff --git a/src/components/ReviewChats/ChatRequestFilterer.tsx b/src/components/ReviewChats/ChatRequestFilterer.tsx
index b08d7ec9..a7a6e9f5 100644
--- a/src/components/ReviewChats/ChatRequestFilterer.tsx
+++ b/src/components/ReviewChats/ChatRequestFilterer.tsx
@@ -16,6 +16,7 @@ import InlineProfileAvatar from "../InlineProfileAvatar";
import ListFilterer from "../ListFilterer";
import OneOptionModal from "../OneOptionModal";
import ProfileModal from "../ProfileModal";
+import TitledInput from "../TitledInput";
import ModifyChatRequestModal from "./ChatRequestMutators";
type ChatRequestPartial = Omit<
@@ -108,12 +109,17 @@ const ChatRequestListItem = ({
chatRequest,
onChatRequestAccept,
}: ChatRequestListItemProps) => {
- const [isRejectModalOpen, setIsRejectModalOpen] = useState(false);
+ const [isRejectModalOpen, setRejectModalOpen] = useState(false);
const [rejectMessage, setRejectMessage] = useState("");
+ const [isSetLocationModalOpen, setSetLocationModalOpen] = useState(false);
+ const [location, setLocation] = useState(
+ chatRequest.mentorProfile.user.preferredChatLocation
+ );
const [acceptChatRequestMutation] = useAcceptChatRequestMutation({
variables: {
chatRequestId: chatRequest.chatRequestId,
+ chatLocation: location,
},
refetchQueries: [
refetchGetChatRequestsQuery({
@@ -138,13 +144,7 @@ const ChatRequestListItem = ({
className="hover:bg-inactive p-1 rounded"
title="Accept Chat Request"
onClick={() => {
- acceptChatRequestMutation().then(() => {
- onChatRequestAccept(
- chatRequest.menteeProfile.user.firstName +
- " " +
- chatRequest.menteeProfile.user.lastName
- );
- });
+ setSetLocationModalOpen(true);
}}
>
@@ -153,7 +153,7 @@ const ChatRequestListItem = ({
className="hover:bg-inactive p-1 rounded"
title="Reject Chat Request"
onClick={() => {
- setIsRejectModalOpen(true);
+ setRejectModalOpen(true);
}}
>
@@ -186,20 +186,70 @@ const ChatRequestListItem = ({
{
- setIsRejectModalOpen(false);
+ setSetLocationModalOpen(false);
}}
>
-
-
-
- Let {chatRequest.menteeProfile.user.firstName} know why you are
- rejecting the request:
-
+
+
+ Accept Chat Request
+
+
+ {chatRequest.menteeProfile.user.firstName} has specified that they
+ prefer to meet here:
+
+ {chatRequest.chatLocation}
+
+
setLocation(e.target.value)}
+ />
+
+ setSetLocationModalOpen(false)}
+ >
+ Cancel
+
+ {
+ acceptChatRequestMutation().then(() => {
+ onChatRequestAccept(
+ chatRequest.menteeProfile.user.firstName +
+ " " +
+ chatRequest.menteeProfile.user.lastName
+ );
+ });
+ setSetLocationModalOpen(false);
+ }}
+ >
+ Confirm
+
-
-
+
+
+
{
+ setRejectModalOpen(false);
+ }}
+ >
+
+
+ Reject Chat Request
+
+
+
+ Let {chatRequest.menteeProfile.user.firstName} know why you are
+ rejecting the request:
+
+
-
+ />
+
-
+
{
- setIsRejectModalOpen(false);
+ setRejectModalOpen(false);
}}
>
Cancel
-
{
@@ -231,7 +280,7 @@ const ChatRequestListItem = ({
chatRejectMessage: rejectMessage,
},
});
- setIsRejectModalOpen(false);
+ setRejectModalOpen(false);
}}
>
Reject
@@ -256,15 +305,17 @@ const ChatRequestsList = ({ title, chatRequests }: ChatRequestsListProps) => {
{title}
-
+
{chatRequests.length > 0 ? (
chatRequests.map((cr) => (
{
- setIsAcceptModalOpen(true);
- setMentee(mentee);
+ setTimeout(() => {
+ setIsAcceptModalOpen(true);
+ setMentee(mentee);
+ }, 250);
}}
/>
))
diff --git a/src/graphql/mutations/chatRequests/acceptChatRequest.graphql b/src/graphql/mutations/chatRequests/acceptChatRequest.graphql
index d0042bd9..bf4d9733 100644
--- a/src/graphql/mutations/chatRequests/acceptChatRequest.graphql
+++ b/src/graphql/mutations/chatRequests/acceptChatRequest.graphql
@@ -1,5 +1,8 @@
-mutation acceptChatRequest($chatRequestId: String!) {
- acceptChatRequest(chatRequestId: $chatRequestId) {
+mutation acceptChatRequest($chatRequestId: String!, $chatLocation: String!) {
+ acceptChatRequest(
+ chatRequestId: $chatRequestId
+ chatLocation: $chatLocation
+ ) {
chatRequestId
}
}
diff --git a/src/graphql/queries/getChatRequests.graphql b/src/graphql/queries/getChatRequests.graphql
index e91dade7..9801c901 100644
--- a/src/graphql/queries/getChatRequests.graphql
+++ b/src/graphql/queries/getChatRequests.graphql
@@ -6,6 +6,7 @@ query getChatRequests($profileId: String!) {
chatEndTime
chatRequestMessage
chatRejectMessage
+ chatLocation
mentorProfileId
mentorProfile {
profileJson
@@ -13,6 +14,7 @@ query getChatRequests($profileId: String!) {
bio
user {
email
+ preferredChatLocation
firstName
lastName
profilePictureUrl
diff --git a/src/graphql/queries/getMyUser.graphql b/src/graphql/queries/getMyUser.graphql
index 763f1709..8844b86e 100644
--- a/src/graphql/queries/getMyUser.graphql
+++ b/src/graphql/queries/getMyUser.graphql
@@ -4,6 +4,7 @@ query getMyUser {
email
firstName
lastName
+ preferredChatLocation
profilePictureUrl
timezone
profiles {
diff --git a/src/graphql/queries/getProfiles.graphql b/src/graphql/queries/getProfiles.graphql
index 909d782e..ff0e4f61 100644
--- a/src/graphql/queries/getProfiles.graphql
+++ b/src/graphql/queries/getProfiles.graphql
@@ -8,6 +8,7 @@ query getProfiles($programId: String!, $profileType: String!) {
user {
userId
email
+ preferredChatLocation
firstName
lastName
profilePictureUrl
diff --git a/src/layouts/AuthorizationWrapper.tsx b/src/layouts/AuthorizationWrapper.tsx
index bfe4bd5e..5ca979ae 100644
--- a/src/layouts/AuthorizationWrapper.tsx
+++ b/src/layouts/AuthorizationWrapper.tsx
@@ -3,6 +3,7 @@ import React, { Fragment } from "react";
import ErrorScreen, { ErrorScreenType } from "../components/ErrorScreen";
import { AuthorizationLevel, useAuthorizationLevel } from "../hooks";
import AuthenticationModal from "../components/Authentication/AuthenticationModal";
+import { useAuth } from "../utils/firebase/auth";
interface AuthorizationWrapperProps {
canView?: AuthorizationLevel[];
@@ -12,9 +13,15 @@ const AuthorizationWrapper: React.FC = ({
children,
canView,
}) => {
+ const { loading } = useAuth();
const router = useRouter();
const authorizationLevel = useAuthorizationLevel();
+ if (loading) {
+ console.log("loading");
+ return <>Loading Screen>;
+ }
+
if (authorizationLevel === AuthorizationLevel.WaitingForUserData)
return ;
diff --git a/src/layouts/TabLayout/NoMatchingProfileTabLayout.tsx b/src/layouts/TabLayout/NoMatchingProfileTabLayout.tsx
index 8c1d18ee..1db0574f 100644
--- a/src/layouts/TabLayout/NoMatchingProfileTabLayout.tsx
+++ b/src/layouts/TabLayout/NoMatchingProfileTabLayout.tsx
@@ -11,7 +11,7 @@ import TabLayout, { BaseTabLayoutProps } from "./TabLayout";
const NoMatchingProfileLayout: React.FC = ({
children,
}) => {
- const { user } = useAuth();
+ const { user, setLoading } = useAuth();
const router = useRouter();
if (user == null) {
@@ -33,6 +33,7 @@ const NoMatchingProfileLayout: React.FC = ({
className={pageItemStyles}
onClick={() => {
LocalStorage.delete("cachedProfileSlug");
+ setLoading(true);
router.push("/");
}}
>
diff --git a/src/layouts/TabLayout/TabLayout.tsx b/src/layouts/TabLayout/TabLayout.tsx
index fa3b4a60..4f443d5b 100644
--- a/src/layouts/TabLayout/TabLayout.tsx
+++ b/src/layouts/TabLayout/TabLayout.tsx
@@ -4,6 +4,7 @@ import { useRouter } from "next/router";
import React, { ReactNode, useEffect, useState } from "react";
import { Text } from "../../components/atomic";
import TabFooterMenu from "../../components/TabFooterMenu";
+import { useAuth } from "../../utils/firebase/auth";
import LocalStorage from "../../utils/localstorage";
import ProgramDropdown from "./ProgramDropdown";
@@ -76,12 +77,16 @@ const TabLayout: React.FC & {
Icon: React.FC>;
}>;
} = ({ children, currentPageChildren }) => {
+ const { loading } = useAuth();
+
return (
-
{children}
+
+ {loading ? <>Loading Screen> : children}
+
{currentPageChildren}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 4b640ceb..254e66cc 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -34,7 +34,9 @@ const BlobCircle = () => {
const IndexPage: PageGetProgramBySlugComp = (_) => {
const router = useRouter();
const authorizationLevel = useAuthorizationLevel();
- const { user } = useAuth();
+ const { user, setLoading } = useAuth();
+ //This is so that universally (wherever you log out from), you'll stop the loading screen here
+ setLoading(false);
if (authorizationLevel === AuthorizationLevel.Unauthenticated) {
if (user)
@@ -183,36 +185,32 @@ type ProgramRowProps = {
profileType: ProfileType;
};
-const ProgramRow = ({ iconUrl, name, route, profileType }: ProgramRowProps) => {
- return (
-
-
-
-
- {name}
-
- {MAP_PROFILETYPE_TO_NAME[profileType]}
-
-
+const ProgramRow = ({ iconUrl, name, route, profileType }: ProgramRowProps) => (
+
+
+
+
+ {name}
+
+ {MAP_PROFILETYPE_TO_NAME[profileType]}
+
-
-
- Go to Homepage
-
-
- );
-};
+
+
+ Go to Homepage
+
+
+
+);
interface ApplicationRowProps {
application: GetMyUserApplicationsQuery["getMyUser"]["applications"][number];
diff --git a/src/pages/my/profile.tsx b/src/pages/my/profile.tsx
index 73a503d8..2fc9bbfa 100644
--- a/src/pages/my/profile.tsx
+++ b/src/pages/my/profile.tsx
@@ -24,6 +24,9 @@ const GeneralProfile: Page = () => {
const [modified, setModified] = useState(false);
const [firstName, setFirstName] = useState(data?.getMyUser.firstName);
const [lastName, setLastName] = useState(data?.getMyUser.lastName);
+ const [location, setLocation] = useState(
+ data?.getMyUser.preferredChatLocation
+ );
const { setSnackbarMessage } = useSnackbar();
const [profilePicture, setProfilePicture] = useState
();
@@ -38,6 +41,7 @@ const GeneralProfile: Page = () => {
setFirstName(data.getMyUser.firstName);
setLastName(data.getMyUser.lastName);
setSrc(data.getMyUser.profilePictureUrl);
+ setLocation(data.getMyUser.preferredChatLocation);
setProfilePicture(null);
setError(null);
}
@@ -81,6 +85,7 @@ const GeneralProfile: Page = () => {
firstName: firstName,
lastName: lastName,
profilePictureUrl: url,
+ preferredChatLocation: location,
},
},
});
@@ -93,7 +98,9 @@ const GeneralProfile: Page = () => {
{data?.getMyUser ? (
-
+
+ {error}
+
Profile Picture
@@ -129,7 +136,16 @@ const GeneralProfile: Page = () => {
}}
/>
-
{error}
+
{
+ setModified(true);
+ setLocation(e.target.value);
+ }}
+ />
) : (
Loading
diff --git a/src/pages/program/[slug]/[profileRoute]/index.tsx b/src/pages/program/[slug]/[profileRoute]/index.tsx
index 21579d0f..336cd3b0 100644
--- a/src/pages/program/[slug]/[profileRoute]/index.tsx
+++ b/src/pages/program/[slug]/[profileRoute]/index.tsx
@@ -2,7 +2,7 @@ import { RawDraftContentState } from "draft-js";
import type { GetServerSideProps } from "next";
import Link from "next/link";
import { useRouter } from "next/router";
-import React, { HTMLAttributes } from "react";
+import React, { Fragment, HTMLAttributes } from "react";
import { Button, Card, Text } from "../../../../components/atomic";
import ErrorScreen, {
ErrorScreenType,
@@ -27,6 +27,7 @@ import { useSnackbar } from "../../../../notifications/SnackbarContext";
import Page from "../../../../types/Page";
import { parseParam } from "../../../../utils";
import { MAP_PROFILETYPE_TO_ROUTE } from "../../../../utils/constants";
+import { useAuth } from "../../../../utils/firebase/auth";
import LocalStorage from "../../../../utils/localstorage";
function getRawContentState(json: string): RawDraftContentState {
@@ -189,10 +190,13 @@ const ReadOnlyHome = ({
//TODO: Change type of this to not any
const ProgramPage: PageGetProgramBySlugComp & Page = (props: any) => {
+ const { loading } = useAuth();
const authorizationLevel = useAuthorizationLevel();
const program = props.data?.getProgramBySlug;
+ if (loading) return ;
+
if (!program) {
return ;
}
diff --git a/src/utils/firebase/auth.tsx b/src/utils/firebase/auth.tsx
index 2fe0e12e..36981476 100644
--- a/src/utils/firebase/auth.tsx
+++ b/src/utils/firebase/auth.tsx
@@ -5,6 +5,7 @@ import firebase from "./firebase";
interface AuthContext {
user: firebase.User | null;
loading: boolean;
+ setLoading: (b: boolean) => void;
//TODO: customize the forget password flow instead of directly through firebase's ugly ui
// confirmPasswordReset: (c: string, n: string) => Promise;
sendPasswordResetEmail: (e: string) => Promise;
@@ -75,8 +76,9 @@ function useProvideAuth() {
.auth()
.signOut()
.then(() => {
- clearCache();
+ setLoading(true);
setUser(null);
+ clearCache();
});
};
@@ -93,6 +95,7 @@ function useProvideAuth() {
return {
user,
loading,
+ setLoading,
// confirmPasswordReset,
sendPasswordResetEmail,
signUpWithEmail,