Skip to content

Commit

Permalink
feat: hooking up report user dialog with mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenvong committed Mar 17, 2021
1 parent b7bc668 commit f23e2e6
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ const useStyles = makeStyles((theme) => ({
disabledButton: {
backgroundColor: theme.palette.grey[100],
},
editButton: {
marginBottom: theme.spacing(2),
},
}));

interface AddFriendButtonProps {
Expand Down Expand Up @@ -51,7 +48,7 @@ export default function AddFriendButton({
return (
<Button
startIcon={<PersonAddIcon />}
className={isPending ? classes.disabledButton : classes.editButton}
className={isPending ? classes.disabledButton : void 0}
disabled={isPending}
onClick={() => {
if (!isPending) {
Expand Down
85 changes: 0 additions & 85 deletions app/frontend/src/features/profile/ReportUserDialog.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import Button from "components/Button";
import Menu, { MenuItem } from "components/Menu";
import { useRef, useState } from "react";

import { MORE_PROFILE_ACTIONS, REPORT_USER } from "./constants";
import {
MORE_PROFILE_ACTIONS,
MORE_PROFILE_ACTIONS_A11Y_TEXT,
REPORT_USER,
} from "../constants";
import ReportUserDialog from "./ReportUserDialog";

const MORE_PROFILE_ACTIONS_MENU_ID = "more-profile-actions-menu";
Expand Down Expand Up @@ -31,6 +35,7 @@ export default function ProfileActionsMenu() {
<>
<Button
aria-controls={MORE_PROFILE_ACTIONS_MENU_ID}
aria-label={MORE_PROFILE_ACTIONS_A11Y_TEXT}
innerRef={menuAnchor}
onClick={handleClick("menu")}
>
Expand Down
138 changes: 138 additions & 0 deletions app/frontend/src/features/profile/actions/ReportUserDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { DialogProps, makeStyles, Snackbar } from "@material-ui/core";
import Alert from "components/Alert";
import Button from "components/Button";
import {
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from "components/Dialog";
import TextField from "components/TextField";
import { Empty } from "google-protobuf/google/protobuf/empty_pb";
import { Error as GrpcError } from "grpc-web";
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { useMutation } from "react-query";
import { service } from "service/index";
import type { ReportUserInput } from "service/user";

import {
CANCEL,
getReportDialogTitle,
getReportUserExplainer,
getReportUserSuccessMessage,
REPORT_DETAILS,
REPORT_REASON,
SEND,
} from "../constants";
import { useProfileUser } from "../hooks/useProfileUser";

const REPORT_USER_DIALOG_LABEL_ID = "report-user-dialog-title";

type ReportUserFormData = Omit<ReportUserInput, "userId">;

function SuccessSnackbar({ name }: { name: string }) {
const [open, setOpen] = useState(true);

return (
<Snackbar
autoHideDuration={6000}
open={open}
onClose={() => setOpen(false)}
>
<Alert severity="success">{getReportUserSuccessMessage(name)}</Alert>
</Snackbar>
);
}

const useStyles = makeStyles((theme) => ({
textField: {
"& + &": {
marginBlockStart: theme.spacing(2),
},
},
}));

export default function ReportUserDialog({ onClose, open }: DialogProps) {
const classes = useStyles();
const { name, userId } = useProfileUser();
const {
handleSubmit,
register,
reset: resetForm,
} = useForm<ReportUserFormData>();

const {
error,
isLoading,
isSuccess,
mutate: reportUser,
reset: resetMutation,
} = useMutation<Empty, GrpcError, ReportUserFormData>(
({ description, reason }) =>
service.user.reportUser({ description, reason, userId }),
{
onSuccess: () => {
onClose?.({}, "escapeKeyDown");
},
}
);

const onSubmit = handleSubmit(({ description, reason }) => {
// trigger mutation
reportUser({ description, reason });
});

return (
<>
{isSuccess && <SuccessSnackbar name={name} />}
<Dialog aria-labelledby={REPORT_USER_DIALOG_LABEL_ID} open={open}>
<form onSubmit={onSubmit}>
<DialogTitle id={REPORT_USER_DIALOG_LABEL_ID}>
{getReportDialogTitle("Itsi")}
</DialogTitle>
<DialogContent>
{error && <Alert severity="error">{error.message}</Alert>}
<DialogContentText>
{getReportUserExplainer(name)}
</DialogContentText>
<TextField
className={classes.textField}
id="user-report-reason"
inputRef={register({ required: true })}
label={REPORT_REASON}
name="reason"
fullWidth
/>
<TextField
className={classes.textField}
fullWidth
id="user-report-details"
inputRef={register({ required: true })}
label={REPORT_DETAILS}
multiline
name="description"
rows={4}
rowsMax={4}
/>
</DialogContent>
<DialogActions>
<Button loading={isLoading} onClick={onSubmit} type="submit">
{SEND}
</Button>
<Button
onClick={() => {
resetForm();
resetMutation();
onClose?.({}, "escapeKeyDown");
}}
>
{CANCEL}
</Button>
</DialogActions>
</form>
</Dialog>
</>
);
}
5 changes: 5 additions & 0 deletions app/frontend/src/features/profile/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ const UNSURE = "Ask me";

// User reporting
export const MORE_PROFILE_ACTIONS = "...";
export const MORE_PROFILE_ACTIONS_A11Y_TEXT = "More profile actions";
export const REPORT_USER = "Report this user";
export const REPORT_REASON = "Reason";
export const REPORT_DETAILS = "Details";
export const SEND = "Send";
export const CANCEL = "Cancel";
export const getReportUserExplainer = (name: string) =>
`You can anonymously report ${name} to moderators. Give as much details as you can and are comfortable with.`;
export const getReportUserSuccessMessage = (name: string) =>
`${name} has been reported to the Couchers safety team`;
export const getReportDialogTitle = (name: string) => `Report ${name}`;

export const smokingLocationLabels = {
Expand Down
21 changes: 13 additions & 8 deletions app/frontend/src/features/profile/view/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { editHostingPreferenceRoute, editProfileRoute } from "routes";
import { timestamp2Date } from "utils/date";
import { timeAgo } from "utils/timeAgo";

import ProfileActionsMenu from "../actions/ProfileActionsMenu";

const useStyles = makeStyles((theme) => ({
card: {
flexShrink: 0,
Expand Down Expand Up @@ -73,7 +75,7 @@ export default function Overview({ user }: OverviewProps) {

return (
<Card className={classes.card}>
<Avatar {...{ user }} className={classes.grow} />
<Avatar user={user} className={classes.grow} />
<Typography variant="h1" className={classes.intro}>
{user.name}
</Typography>
Expand All @@ -93,13 +95,16 @@ export default function Overview({ user }: OverviewProps) {
</Button>
</>
) : (
user.friends !== User.FriendshipStatus.FRIENDS && (
<AddFriendButton
isPending={user.friends === User.FriendshipStatus.PENDING}
userId={user.userId}
setMutationError={setMutationError}
/>
)
<>
{user.friends !== User.FriendshipStatus.FRIENDS && (
<AddFriendButton
isPending={user.friends === User.FriendshipStatus.PENDING}
userId={user.userId}
setMutationError={setMutationError}
/>
)}
<ProfileActionsMenu />
</>
)}
</CardActions>
<IconText
Expand Down

0 comments on commit f23e2e6

Please sign in to comment.