Skip to content

Commit

Permalink
Add TeamInviteRequest notification (#7828)
Browse files Browse the repository at this point in the history
* Add TeamInviteRequest notification

* Remove unnecessary comments
  • Loading branch information
sannek authored Aug 1, 2023
1 parent 56ab802 commit df8844a
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
14 changes: 14 additions & 0 deletions packages/app/src/app/components/Notifications/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import {
PullRequestReviewReceivedData,
PullRequestReviewRequestData,
TeamInviteData,
TeamInviteRequestData,
TeamAcceptedData,
SandboxInvitationData,
} from './types';

import { PullRequestReviewReceived } from './notifications/PullRequestReviewReceived';
import { PullRequestReviewRequest } from './notifications/PullRequestReviewRequest';
import { SandboxInvitation } from './notifications/SandboxInvitation';
import { TeamInviteRequest } from './notifications/TeamInviteRequest';
import { TeamAccepted } from './notifications/TeamAccepted';
import { TeamInvite } from './notifications/TeamInvite';
import { Mention } from './notifications/Mention';
Expand Down Expand Up @@ -81,6 +83,18 @@ const getNotificationComponent = ({ id, type, data, read, insertedAt }) => {
/>
);
}

if (type === 'team_invite_requested') {
return (
<TeamInviteRequest
insertedAt={insertedAt}
id={id}
read={read}
{...(camelCaseData as TeamInviteRequestData)}
/>
);
}

if (type === 'team_accepted') {
return (
<TeamAccepted
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React, { useState } from 'react';
import css from '@styled-system/css';
import {
Stack,
Element,
Text,
ListAction,
isMenuClicked,
} from '@codesandbox/components';
import { shortDistance } from '@codesandbox/common/lib/utils/short-distance';
import { teamSettingsUrl } from '@codesandbox/common/lib/utils/url-generator';
import { useActions } from 'app/overmind';
import { formatDistanceStrict } from 'date-fns';
import { useHistory } from 'react-router-dom';
import { zonedTimeToUtc } from 'date-fns-tz';
import { Menu } from './Menu';
import { InvitationIcon } from './Icons';

interface ITeamInviteRequestProps {
id: string;
insertedAt: string;
read: boolean;
requesterAvatar: string | null;
requesterEmail: string;
requesterName: string;
teamId: string;
teamName: string;
}

export const TeamInviteRequest = ({
id,
insertedAt,
read,
requesterAvatar,
requesterEmail,
requesterName,
teamId,
teamName,
}: ITeamInviteRequestProps) => {
const {
userNotifications: { updateReadStatus },
setActiveTeam,
} = useActions();
const [hover, setHover] = useState(false);
const history = useHistory();

return (
<ListAction
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
onClick={async event => {
if (isMenuClicked(event)) return;
if (!read) {
await updateReadStatus(id);
}
setActiveTeam({ id: teamId });
history.push(teamSettingsUrl() + `?invite_email=${requesterEmail}`);
}}
key={id}
css={css({ padding: 0 })}
>
<Element
css={css({
opacity: read ? 0.6 : 1,
textDecoration: 'none',
color: 'inherit',
})}
>
<Stack align="center" gap={2} padding={4}>
<Stack gap={4} align="flex-start">
<Element css={css({ position: 'relative' })}>
<Element
as="img"
src={requesterAvatar}
alt={requesterName}
css={css({
width: 32,
height: 32,
display: 'block',
borderRadius: 'small',
})}
/>
<InvitationIcon
read={read}
css={css({
position: 'absolute',
bottom: '-4px',
right: '-4px',
})}
/>
</Element>
<Text size={3} variant="muted">
{requesterName}{' '}
<Text css={css({ color: 'sideBar.foreground' })}>
requested to join your team {teamName}
</Text>
</Text>
</Stack>
<Stack
css={css({ width: 70, flexShrink: 0, justifyContent: 'flex-end' })}
>
{hover ? (
<Menu read={read} id={id} />
) : (
<Text
size={2}
align="right"
block
css={css({ color: 'sideBar.foreground' })}
>
{shortDistance(
formatDistanceStrict(
zonedTimeToUtc(insertedAt, 'Etc/UTC'),
new Date()
)
)}
</Text>
)}
</Stack>
</Stack>
</Element>
</ListAction>
);
};
8 changes: 8 additions & 0 deletions packages/app/src/app/components/Notifications/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ export type TeamInviteData = {
inviterAvatar: string;
};

export type TeamInviteRequestData = {
teamId: string;
teamName: string;
requesterEmail: string;
requesterName: string;
requesterAvatar: string | null;
};

export type TeamAcceptedData = {
teamName: string;
userName: string;
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/utils/url-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export const profileUrl = (username: string) => `/u/${username}`;
export const dashboardUrl = () => `/dashboard`;
export const exploreUrl = () => `/explore`;
export const teamOverviewUrl = (teamId: string) => `/dashboard/teams/${teamId}`;
export const teamSettingsUrl = () => `/dashboard/settings`;
export const profileSandboxesUrl = (username: string, page?: number) =>
`${profileUrl(username)}/sandboxes${page ? `/${page}` : ''}`;
export const profileLikesUrl = (username: string, page?: number) =>
Expand Down

0 comments on commit df8844a

Please sign in to comment.