Skip to content
This repository has been archived by the owner on Aug 18, 2021. It is now read-only.

Commit

Permalink
Merge pull request #25 from artsy/staging
Browse files Browse the repository at this point in the history
Deploy
  • Loading branch information
zephraph authored Sep 8, 2020
2 parents 50b7864 + d8f39cc commit 6a2e948
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 68 deletions.
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Team Navigator

Artsy's internal team directory.

Team Nav started off as a hackathon project way back in 2015. It's evolved a lot over the years. This repo is its latest iteration, written in 2020 (see the original project [here](https://github.com/artsy/team-navigator)).

## Getting started

**Note**: Team Nav isn't yet configured to be runnable by the open source community

_For Artsy Employees_

1. Copy down the `.env` file from citadel (You'll need proper access)
2. Install dependencies and start the service in dev mode

```
yarn && yarn dev
```

## About Artsy

<a href="https://www.artsy.net/">
<img align="left" src="https://avatars2.githubusercontent.com/u/546231?s=200&v=4"/>
</a>

This project is the work of engineers at [Artsy][footer_website], the world's
leading and largest online art marketplace and platform for discovering art.
One of our core [Engineering Principles][footer_principles] is being [Open
Source by Default][footer_open] which means we strive to share as many details
of our work as possible.

You can learn more about this work from [our blog][footer_blog] and by following
[@ArtsyOpenSource][footer_twitter] or explore our public data by checking out
[our API][footer_api]. If you're interested in a career at Artsy, read through
our [job postings][footer_jobs]!

[footer_website]: https://www.artsy.net/
[footer_principles]: culture/engineering-principles.md
[footer_open]: culture/engineering-principles.md#open-source-by-default
[footer_blog]: https://artsy.github.io/
[footer_twitter]: https://twitter.com/ArtsyOpenSource
[footer_api]: https://developers.artsy.net/
[footer_jobs]: https://www.artsy.net/jobs
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dependencies": {
"@artsy/next-layout": "^0.2.0",
"@artsy/next-palette": "^1.0.0",
"@react-hook/window-size": "^3.0.7",
"await-to-js": "^2.1.1",
"aws-sdk": "^2.668.0",
"csvtojson": "^2.0.10",
Expand All @@ -27,6 +28,7 @@
"pino-http": "^5.2.0",
"react": "^16.13.1",
"react-bytesize-icons": "^0.11.1",
"react-confetti": "^6.0.0",
"react-dom": "^16.13.1",
"sharp": "^0.25.2",
"styled-components": "4"
Expand Down
49 changes: 49 additions & 0 deletions src/components/AwardIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import styled from "styled-components";
import {
compose,
color,
ColorProps,
layout,
LayoutProps,
space,
SpaceProps,
position,
PositionProps,
} from "styled-system";
import { ComponentPropsWithoutRef } from "react";

interface IconProps
extends LayoutProps,
SpaceProps,
PositionProps,
ColorProps {}
const Icon = styled.svg<IconProps>(compose(layout, space, position, color));

interface AwardIconProps extends ComponentPropsWithoutRef<typeof Icon> {}

export function AwardIcon(props: AwardIconProps) {
return (
<Icon
xmlns="http://www.w3.org/2000/svg"
width="28px"
height="28px"
viewBox="0 -2 24 26"
// fill="#6E1FFF"
fill="currentColor"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
{...props}
>
<circle strokeWidth="1" stroke="white" cx="12" cy="8" r="9" />
<polyline points="8.21 13.89 7 23 12 20 17 23 15.79 13.88"></polyline>
<circle cx="12" cy="8" r="7" />
<circle strokeWidth="1.5" stroke="white" cx="12" cy="8" r="5.5" />
</Icon>
);
}

AwardIcon.defaultProps = {
color: "#6E1FFF",
};
38 changes: 26 additions & 12 deletions src/components/TeamMember.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import RouterLink from "next/link";
import { Avatar, Box, Serif, Flex, Link } from "@artsy/palette";
import styled from "styled-components";
import { color } from "styled-system";
import { AwardIcon } from "./AwardIcon";
import { isWeekOf } from "utils/date";

const TeamMemberContainer = styled(Flex)`
border-radius: 5px;
Expand All @@ -18,6 +20,7 @@ const TeamMemberContainer = styled(Flex)`

const AvatarContainer = styled(Box)`
flex-shrink: 0;
position: relative;
`;

const location = ({ city, floor }: { city?: string; floor?: string }) =>
Expand All @@ -40,18 +43,29 @@ export const TeamMember: FC<TeamMemberProps> = (props) => {
<TeamMemberContainer width="390px" p={1} ml={(!showAvatar && -1) || 0}>
{showAvatar && (
<AvatarContainer mr={1}>
{member.avatar ? (
<Avatar
size="md"
src={member.avatar}
lazyLoad={true}
renderFallback={({ diameter }) => (
<AvatarFallback diameter={diameter} />
)}
/>
) : (
<AvatarFallback diameter={"100px"} />
)}
<>
{member.start_date && isWeekOf(new Date(member.start_date)) && (
<AwardIcon
color="#6E1FFF"
bottom="0px"
right="0px"
position="absolute"
zIndex="10"
/>
)}
{member.avatar ? (
<Avatar
size="md"
src={member.avatar}
lazyLoad={true}
renderFallback={({ diameter }) => (
<AvatarFallback diameter={diameter} />
)}
/>
) : (
<AvatarFallback diameter={"100px"} />
)}
</>
</AvatarContainer>
)}

Expand Down
43 changes: 0 additions & 43 deletions src/pages/did-you-know.mdx

This file was deleted.

5 changes: 2 additions & 3 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Avatar, Box, Serif, Flex, Separator } from "@artsy/palette";
import { Box, Flex, Separator } from "@artsy/palette";
import { GetStaticProps } from "next";
import { H1 } from "components/Typography";
import { useRouter } from "next/router";
import { NoResults as DefaultNoResults } from "components/NoResults";
import { FC } from "react";
import Error from "next/error";
import { firstIfMany, useSearchParam } from "utils";
import { useSearchParam } from "utils";
import { getMembers } from "../data/team";
import { TeamMember } from "../components/TeamMember";

Expand Down
51 changes: 43 additions & 8 deletions src/pages/member/[member].tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Box, Serif, ResponsiveImage, Separator } from "@artsy/palette";
import { Flex, Box, Serif, ResponsiveImage, Separator } from "@artsy/palette";
import Error from "next/error";
import { normalizeParam } from "utils";
import { FC } from "react";
import { normalizeParam, useDelay } from "utils";
import { FC, useEffect, useState } from "react";
import { H1 } from "components/Typography";
import { Member as MemberType } from "../index";
import { GetStaticProps, GetStaticPaths } from "next";
import { getMembers, getMemberProperty } from "../../data/team";
import { MemberDetails } from "components/MemberDetails";
import { useAreaGrid } from "components/Grid";
import { isWeekOf, relativeDaysTillAnniversary, isDayOf } from "utils/date";
import { AwardIcon } from "components/AwardIcon";
import { useWindowSize } from "@react-hook/window-size";
import Confetti from "react-confetti";

export const getStaticProps: GetStaticProps = async ({ params }) => {
const members = await getMembers();
Expand Down Expand Up @@ -36,14 +40,14 @@ export const getStaticPaths: GetStaticPaths = async () => {
const area = ["Heading", "Image", "Details", "Summary"] as const;
type AreaType = typeof area[number];

const mobileAreas: AreaType[][] = [
const defaultLayout: AreaType[][] = [
["Heading"],
["Image"],
["Summary"],
["Details"],
];

const largeAreas: AreaType[][] = [
const largeLayout: AreaType[][] = [
["Heading", "Heading"],
["Image", "Details"],
["Summary", "Details"],
Expand All @@ -54,23 +58,54 @@ interface MemberProps {
}

const Member: FC<MemberProps> = ({ member }) => {
const finished = useDelay(10);
const [showConfetti, setShowConfetti] = useState(false);
const [width, height] = useWindowSize({ initialWidth: 0, initialHeight: 0 });
const { Grid, Area } = useAreaGrid(area, {
_: mobileAreas,
xl: largeAreas,
_: defaultLayout,
xl: largeLayout,
});
if (!member) {
return <Error statusCode={404} />;
}

useEffect(() => {
if (member.start_date && !finished) {
setShowConfetti(true);
}
}, [setShowConfetti, member.start_date, finished]);

return (
<>
{showConfetti && isDayOf(new Date(member.start_date!)) && (
<Confetti
width={width}
height={height}
recycle={!finished}
numberOfPieces={400}
/>
)}
<Grid
gridTemplateColumns={{ xl: "300px auto" }}
gridRowGap={2}
gridColumnGap={3}
>
<Area.Heading>
<H1>{member.name}</H1>
<Flex alignItems="center" justifyContent="space-between">
<H1>{member.name}</H1>
{member.start_date && isWeekOf(new Date(member.start_date)) && (
<>
<Flex ml={4}>
<AwardIcon />
<Serif size="4">
Artsyversary{" "}
{relativeDaysTillAnniversary(new Date(member.start_date))}
</Serif>
</Flex>
</>
)}
</Flex>

<Separator mb={2} />
</Area.Heading>
<Area.Image>
Expand Down
1 change: 0 additions & 1 deletion src/pages/team/[team].tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useRouter } from "next/router";
import TeamNav, { ServerProps } from "../index";
import { Spinner } from "@artsy/palette";
import { normalizeParam } from "utils";
import { NoResults } from "components/NoResults";
import { FC } from "react";
Expand Down
42 changes: 42 additions & 0 deletions src/utils/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
isSameWeek,
setYear,
startOfToday,
getYear,
isSameDay,
isAfter,
endOfToday,
differenceInCalendarDays,
} from "date-fns";

export const isWeekOf = (date: Date) => {
return isSameWeek(setYear(date, getYear(startOfToday())), startOfToday(), {
weekStartsOn: 1,
});
};

export const isDayOf = (date: Date) => {
return isSameDay(date, setYear(startOfToday(), getYear(date)));
};

export const isAfterToday = (date: Date) => {
return isAfter(date, setYear(endOfToday(), getYear(date)));
};

export const relativeDaysTillAnniversary = (date: Date) => {
const days = differenceInCalendarDays(
setYear(date, getYear(Date.now())),
Date.now()
);
if (days === 0) {
return "is today";
} else if (days === 1) {
return "is tomorrow";
} else if (days === -1) {
return "was yesterday";
} else if (days > 0) {
return `is in ${days} days`;
} else {
return `was ${days} ago`;
}
};
16 changes: 15 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IncomingMessage } from "http";
import crypto from "crypto";
import { NextRouter, useRouter } from "next/router";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";

export const hash = (source: string) =>
crypto.createHash("md5").update(source).digest("hex");
Expand Down Expand Up @@ -31,3 +32,16 @@ export const useSearchParam = () => {
const router = useRouter();
return getSearchParam(router.asPath);
};

export const useDelay = (delay: number) => {
const [finished, setFinished] = useState(false);

useEffect(() => {
const timeout = setTimeout(() => {
setFinished(true);
}, delay * 1000);
return () => clearTimeout(timeout);
}, [delay]);

return finished;
};
Loading

0 comments on commit 6a2e948

Please sign in to comment.