Skip to content

Commit

Permalink
improvements for careerfair testing (#129)
Browse files Browse the repository at this point in the history
* increase max video-record time to 5 min (#110)

* If setup is not complete, redirect to setup page from home page: (#96)

* move curAnswer to state (#105)

* thumbnail data in redux (#109)

* tests for simple mentor change & switch functions

* prompts user to upload video if leaving page, other small bug fix (#112)

* visual indication when mentor isn't owned by user

* Only admin can see mentor selection tools.

* login query grabs default mentor id for user

* fetchbyid uses findone query

* must fix cypress tests

* Mentor always fetched by ID, no me query in fetch

* separate use[Active]Mentor (redux) from useMentorEdits (useState hook) (#120)



Co-authored-by: Jim Alvarez <[email protected]>

* merges main back to integration branch (#123)


Co-authored-by: kycarr <[email protected]>
Co-authored-by: Aaron shiel <[email protected]>
Co-authored-by: larry kirschner <[email protected]>
Co-authored-by: aaronshiel <[email protected]>
Co-authored-by: aaronshiel <[email protected]>
Co-authored-by: Jim Alvarez <[email protected]>

* impr: switches to mentorpal docker account from uscictdocker (#127)

* fixes: lint error

Co-authored-by: kycarr <[email protected]>
Co-authored-by: Aaron shiel <[email protected]>
Co-authored-by: Jim Alvarez <[email protected]>
Co-authored-by: Jaime Alvarez <[email protected]>
Co-authored-by: aaronshiel <[email protected]>
Co-authored-by: aaronshiel <[email protected]>
  • Loading branch information
7 people authored Aug 25, 2021
1 parent 08afb5b commit ce5f7d8
Show file tree
Hide file tree
Showing 31 changed files with 694 additions and 428 deletions.
15 changes: 9 additions & 6 deletions client/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,18 +606,18 @@ export async function updateUserQuestion(
);
}

export async function fetchMentor(
export async function fetchMentorById(
accessToken: string,
mentorId: string,
subject?: string,
topic?: string,
status?: string
): Promise<Mentor> {
return execGql<Mentor>(
{
query: `
query Mentor($subject: ID!, $topic: ID!, $status: String!) {
me {
mentor {
query MentorFindOne($mentor: ID!, $subject: ID!, $topic: ID!, $status: String!) {
mentor (id: $mentor){
_id
name
firstName
Expand Down Expand Up @@ -698,15 +698,15 @@ export async function fetchMentor(
}
}
}
}
`,
variables: {
mentor: mentorId,
subject: subject || "",
topic: topic || "",
status: status || "",
},
},
{ dataPath: ["me", "mentor"], accessToken }
{ dataPath: ["mentor"], accessToken }
);
}

Expand Down Expand Up @@ -908,6 +908,9 @@ export async function login(accessToken: string): Promise<UserAccessToken> {
_id
name
userRole
defaultMentor{
_id
}
}
accessToken
}
Expand Down
101 changes: 82 additions & 19 deletions client/src/components/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
ListItem,
MenuItem,
Select,
TextField,
Toolbar,
Typography,
} from "@material-ui/core";
Expand All @@ -30,9 +31,12 @@ import withAuthorizationOnly from "hooks/wrap-with-authorization-only";
import { useWithReviewAnswerState } from "hooks/graphql/use-with-review-answer-state";
import { ErrorDialog, LoadingDialog } from "components/dialog";
import MyMentorCard from "components/my-mentor-card";
import { User } from "types";
import { Subject, User, UserRole } from "types";
import { launchMentor } from "helpers";
import { useWithSetup } from "hooks/graphql/use-with-setup";
import useActiveMentor, {
useActiveMentorActions,
} from "store/slices/mentor/useActiveMentor";

const useStyles = makeStyles((theme) => ({
toolbar: theme.mixins.toolbar,
Expand Down Expand Up @@ -78,7 +82,6 @@ function HomePage(props: {
search: { subject?: string };
user: User;
}): JSX.Element {
const classes = useStyles();
const {
useMentor,
isLoading,
Expand All @@ -92,18 +95,33 @@ function HomePage(props: {
saveChanges,
startTraining,
} = useWithReviewAnswerState(props.accessToken, props.search);
const { mentor, isMentorEdited } = useMentor;
const defaultMentor = props.user.defaultMentor._id;

const mentorId = useActiveMentor((m) => m.data?._id || "");
const { loadMentor } = useActiveMentorActions();
const { isMentorEdited } = useMentor;
const { setupStatus, navigateToMissingSetup } = useWithSetup();
const [showSetupAlert, setShowSetupAlert] = useState(true);

const [activeMentorId, setActiveMentorId] = useState(defaultMentor);
const mentorOwnership = defaultMentor === mentorId;
const classes = useStyles();
const mentorIsDirty = useActiveMentor((m) => Boolean(m.data?.isDirty));
const mentorSubjectNamesById: Record<string, string> = useActiveMentor((m) =>
(m.data?.subjects || []).reduce(
(acc: Record<string, string>, cur: Subject) => {
acc[cur._id] = cur.name;
return acc;
},
{}
)
);
React.useEffect(() => {
if (!setupStatus || !showSetupAlert) {
return;
}
setShowSetupAlert(!setupStatus.isSetupComplete);
}, [setupStatus]);

if (!mentor || !setupStatus) {
if (!(mentorId && setupStatus)) {
return (
<div>
<NavBar title="Mentor Studio" mentorId={""} />
Expand All @@ -115,30 +133,75 @@ function HomePage(props: {
navigate("/setup");
}

if (!setupStatus.isMentorInfoDone) {
navigate("/setup");
}

const continueAction = () =>
mentor.isDirty ? startTraining(mentor._id) : launchMentor(mentor._id);
mentorIsDirty ? startTraining(mentorId) : launchMentor(mentorId);

return (
<div className={classes.root}>
<div
data-cy="my-mentor-wrapper"
className={classes.root}
style={{ background: mentorOwnership ? "white" : "black" }}
>
<div>
<NavBar
title="My Mentor"
mentorId={mentor?._id}
mentorId={mentorId}
userRole={props.user.userRole}
/>
<MyMentorCard
accessToken={props.accessToken}
editDisabled={!mentorOwnership}
continueAction={continueAction}
useMentor={useMentor}
/>
{props.user.userRole === UserRole.ADMIN && (
<div data-cy="mentor-select">
<TextField
data-cy="switch-mentor-id"
label="Active Mentor Id"
value={activeMentorId}
onChange={(e) => setActiveMentorId(e.target.value)}
/>
<Fab
data-cy="switch-mentor-button"
variant="extended"
color="secondary"
onClick={() => loadMentor(activeMentorId)}
className={classes.fab}
>
Switch Mentor
</Fab>
<Fab
data-cy="default-mentor-button"
variant="extended"
color="primary"
onClick={() => {
setActiveMentorId(defaultMentor);
loadMentor();
}}
className={classes.fab}
>
Default Mentor
</Fab>
</div>
)}

<Select
data-cy="select-subject"
value={mentor?.subjects.find((s) => s._id === selectedSubject)}
value={
selectedSubject
? mentorSubjectNamesById[selectedSubject]
: undefined
}
displayEmpty
renderValue={() => (
<Typography variant="h6" className={classes.title}>
{mentor?.subjects.find((s) => s._id === selectedSubject)?.name ||
"All Answers"}{" "}
{selectedSubject
? mentorSubjectNamesById[selectedSubject]
: "All Answers"}{" "}
({progress.complete} / {progress.total})
</Typography>
)}
Expand All @@ -151,9 +214,9 @@ function HomePage(props: {
<MenuItem data-cy="all-subjects" value={undefined}>
Show All Subjects
</MenuItem>
{mentor?.subjects.map((s) => (
<MenuItem key={s._id} data-cy={`select-${s._id}`} value={s._id}>
{s.name}
{Object.entries(mentorSubjectNamesById).map(([id, name]) => (
<MenuItem key={id} data-cy={`select-${id}`} value={id}>
{name}
</MenuItem>
))}
</Select>
Expand All @@ -170,7 +233,7 @@ function HomePage(props: {
<RecordingBlockItem
classes={classes}
block={b}
mentorId={mentor?._id || ""}
mentorId={mentorId || ""}
/>
</ListItem>
))}
Expand Down Expand Up @@ -198,11 +261,11 @@ function HomePage(props: {
data-cy="train-button"
variant="extended"
color="primary"
disabled={!mentor || isTraining || isLoading || isSaving}
disabled={!mentorId || isTraining || isLoading || isSaving}
onClick={continueAction}
className={classes.fab}
>
{mentor.isDirty ? "Build Mentor" : "Preview Mentor"}
{mentorIsDirty ? "Build Mentor" : "Preview Mentor"}
</Fab>
</Toolbar>
</AppBar>
Expand Down
38 changes: 23 additions & 15 deletions client/src/components/my-mentor-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ import { HelpOutline } from "@material-ui/icons";
import { useWithThumbnail } from "hooks/graphql/use-with-thumbnail";
import RecommendedActionButton from "./recommended-action-button";
import StageProgress from "./stage-progress";
import parseMentor from "./mentor-info";
import parseMentor, { defaultMentorInfo } from "./mentor-info";
import { ErrorDialog, LoadingDialog } from "components/dialog";
import { MentorType } from "types";
import { UseWithMentor } from "store/slices/mentor/useWithMentor";
import { UseMentorEdits } from "store/slices/mentor/useMentorEdits";
import useActiveMentor, {
isActiveMentorLoading,
isActiveMentorSaving,
} from "store/slices/mentor/useActiveMentor";

const useStyles = makeStyles(() => ({
homeThumbnail: {
Expand All @@ -50,23 +54,22 @@ const useStyles = makeStyles(() => ({
}));

export default function MyMentorCard(props: {
accessToken: string;
editDisabled: boolean;
continueAction: () => void;
useMentor: UseWithMentor;
useMentor: UseMentorEdits;
}): JSX.Element {
const {
mentor,
isMentorLoading,
isMentorSaving,
mentorError,
editedMentor,
editMentor,
} = props.useMentor;
const mentorError = useActiveMentor((ms) => ms.error);
const isMentorLoading = isActiveMentorLoading();
const isMentorSaving = isActiveMentorSaving();
const { editedMentor, editMentor } = props.useMentor;
const mentorId = useActiveMentor((ms) => ms.data?._id || "");

if (!mentor || !editedMentor) {
if (!mentorId || !editedMentor) {
return <div />;
}
const mentorInfo = parseMentor(mentor);
const mentorInfo = useActiveMentor((ms) =>
ms.data ? parseMentor(ms.data) : defaultMentorInfo
);
const classes = useStyles();
const [thumbnail, updateThumbnail] = useWithThumbnail();

Expand All @@ -89,13 +92,15 @@ export default function MyMentorCard(props: {
value={editedMentor.name}
onChange={(e) => editMentor({ name: e.target.value })}
className={classes.inputField}
disabled={props.editDisabled}
/>
<TextField
data-cy="mentor-job-title"
label="Job Title"
value={editedMentor.title}
onChange={(e) => editMentor({ title: e.target.value })}
className={classes.inputField}
disabled={props.editDisabled}
/>
<Grid
justify="center"
Expand Down Expand Up @@ -138,6 +143,7 @@ export default function MyMentorCard(props: {
value={editedMentor.firstName}
onChange={(e) => editMentor({ firstName: e.target.value })}
className={classes.inputField}
disabled={props.editDisabled}
/>
<TextField
data-cy="mentor-email"
Expand All @@ -146,6 +152,7 @@ export default function MyMentorCard(props: {
value={editedMentor.email}
onChange={(e) => editMentor({ email: e.target.value })}
className={classes.inputField}
disabled={props.editDisabled}
/>
<FormControlLabel
control={
Expand All @@ -157,6 +164,7 @@ export default function MyMentorCard(props: {
})
}
color="secondary"
disabled={props.editDisabled}
/>
}
label="Allow people to contact me"
Expand All @@ -168,6 +176,7 @@ export default function MyMentorCard(props: {
<Select
data-cy="select-chat-type"
label="Mentor Type"
disabled={props.editDisabled}
value={editedMentor.mentorType}
style={{ width: 200 }}
onChange={(
Expand Down Expand Up @@ -254,7 +263,6 @@ export default function MyMentorCard(props: {
</Grid>
<Grid xs={12} md={2}>
<RecommendedActionButton
mentor={mentor}
setThumbnail={updateThumbnail}
continueAction={props.continueAction}
/>
Expand Down
23 changes: 23 additions & 0 deletions client/src/components/my-mentor-card/mentor-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,29 @@ interface MentorInfo {
value: number;
currentStage: Stage;
}
export const defaultMentorInfo: MentorInfo = {
mentorId: "",
name: "",
type: MentorType.CHAT,
title: "",
lastTrainedAt: "",
value: 0,
currentStage: {
name: "Incomplete",
index: 0,
description: "This Mentor can't be built yet.",
floor: 0,
max: 5,
percent: 0,
next: {
name: "Incomplete",
index: 0,
description: "This Mentor can't be built yet.",
floor: 0,
max: 5,
},
},
};

function StageSelect(value: number): Stage {
const stages = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ The full terms of this copyright and license should always be found in the root
import { Button, Typography } from "@material-ui/core";
import { DoubleArrow } from "@material-ui/icons";
import React from "react";
import { Mentor } from "types";
import { UseWithRecommendedAction } from "./use-with-recommended-action";
export default function RecommendedActionButton(props: {
setThumbnail: (file: File) => void;
continueAction: () => void;
mentor: Mentor;
}): JSX.Element {
const [recommendedAction, skipRecommendation] = UseWithRecommendedAction(
props.mentor,
props.continueAction
);

Expand Down
Loading

0 comments on commit ce5f7d8

Please sign in to comment.