2020-01-07 20:23:53 +00:00
|
|
|
import React from 'react';
|
2020-01-08 16:25:18 +00:00
|
|
|
import PropTypes from 'prop-types';
|
2020-01-07 20:23:53 +00:00
|
|
|
import { name } from 'country-emoji';
|
2020-01-07 22:58:15 +00:00
|
|
|
import styled from 'styled-components';
|
2020-01-08 15:21:46 +00:00
|
|
|
import { Tag, Tags } from './Topics';
|
2020-01-08 16:06:32 +00:00
|
|
|
import * as icons from '../util/icons';
|
2020-01-07 20:23:53 +00:00
|
|
|
|
|
|
|
|
export default function Person({ person, currentTag }) {
|
|
|
|
|
const url = new URL(person.url);
|
|
|
|
|
const img = `https://logo.clearbit.com/${url.host}`;
|
|
|
|
|
return (
|
2020-01-07 22:58:15 +00:00
|
|
|
<PersonWrapper>
|
|
|
|
|
<PersonInner>
|
|
|
|
|
<header>
|
2020-01-07 21:38:31 +00:00
|
|
|
<img width="50" height="50" src={img} alt={person.name} />
|
|
|
|
|
<h3>
|
|
|
|
|
<a href={person.url} target="_blank" rel="noopener noreferrer">
|
|
|
|
|
{person.name} {person.emoji}
|
|
|
|
|
</a>
|
|
|
|
|
</h3>
|
|
|
|
|
<a
|
|
|
|
|
className="displayLink"
|
|
|
|
|
href={person.url}
|
|
|
|
|
>{`${url.host}${url.pathname}`}</a>
|
|
|
|
|
</header>
|
2020-01-07 20:23:53 +00:00
|
|
|
<p>{person.description}</p>
|
2020-01-08 15:21:46 +00:00
|
|
|
<Tags>
|
2020-01-07 20:23:53 +00:00
|
|
|
{person.tags.map(tag => (
|
2020-01-08 15:21:46 +00:00
|
|
|
<Tag key={tag} as="li" currentTag={tag === currentTag} small>
|
2020-01-07 20:23:53 +00:00
|
|
|
{tag}
|
2020-01-08 15:21:46 +00:00
|
|
|
</Tag>
|
2020-01-07 20:23:53 +00:00
|
|
|
))}
|
2020-01-08 15:21:46 +00:00
|
|
|
</Tags>
|
2020-01-07 22:58:15 +00:00
|
|
|
</PersonInner>
|
|
|
|
|
<PersonDeets>
|
2020-01-07 20:23:53 +00:00
|
|
|
<span className="country" title={name(person.country)}>
|
|
|
|
|
{person.country}
|
|
|
|
|
</span>
|
|
|
|
|
{person.computer && (
|
|
|
|
|
<span title={`Computer: ${person.computer}`}>
|
|
|
|
|
<img
|
|
|
|
|
height="40"
|
|
|
|
|
src={icons[person.computer]}
|
|
|
|
|
alt={person.computer}
|
|
|
|
|
/>
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
{person.phone && (
|
|
|
|
|
<span title={`Uses an ${person.phone}`}>
|
|
|
|
|
<img height="50" src={icons[person.phone]} alt={person.phone} />
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{person.twitter && (
|
2020-01-08 16:58:45 +00:00
|
|
|
<TwitterHandle>
|
2020-01-07 21:07:32 +00:00
|
|
|
<a
|
|
|
|
|
href={`https://twitter.com/${person.twitter}`}
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
|
>
|
2020-01-07 20:23:53 +00:00
|
|
|
<span className="at">@</span>
|
|
|
|
|
{person.twitter.replace('@', '')}
|
|
|
|
|
</a>
|
2020-01-08 16:58:45 +00:00
|
|
|
</TwitterHandle>
|
2020-01-07 20:23:53 +00:00
|
|
|
)}
|
2020-01-07 22:58:15 +00:00
|
|
|
</PersonDeets>
|
|
|
|
|
</PersonWrapper>
|
2020-01-07 20:23:53 +00:00
|
|
|
);
|
|
|
|
|
}
|
2020-01-07 22:58:15 +00:00
|
|
|
|
2020-01-08 16:25:18 +00:00
|
|
|
Person.propTypes = {
|
|
|
|
|
currentTag: PropTypes.string,
|
|
|
|
|
person: PropTypes.shape({
|
|
|
|
|
github: PropTypes.string,
|
|
|
|
|
name: PropTypes.string,
|
|
|
|
|
url: PropTypes.string,
|
|
|
|
|
emoji: PropTypes.string,
|
|
|
|
|
description: PropTypes.string,
|
|
|
|
|
tags: PropTypes.arrayOf(PropTypes.string),
|
|
|
|
|
computer: PropTypes.oneOf(['apple', 'windows', 'linux']),
|
|
|
|
|
phone: PropTypes.oneOf(['iphone', 'android']),
|
|
|
|
|
twitter(props, propName, componentName) {
|
|
|
|
|
if (!/^@?(\w){1,15}$/.test(props[propName])) {
|
|
|
|
|
return new Error(
|
|
|
|
|
`Invalid prop \`${propName}\` supplied to` +
|
|
|
|
|
` \`${componentName}\`. This isn't a legit twitter handle.`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-07 22:58:15 +00:00
|
|
|
// Component Styles
|
|
|
|
|
const PersonWrapper = styled.div`
|
|
|
|
|
border: 1px solid var(--vape);
|
|
|
|
|
border-radius: 5.34334px;
|
|
|
|
|
box-shadow: 10px -10px 0 var(--blue2);
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-rows: 1fr auto auto;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const PersonInner = styled.div`
|
|
|
|
|
padding: 2rem;
|
|
|
|
|
h3 {
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
header {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-rows: auto auto;
|
|
|
|
|
grid-template-columns: auto 1fr;
|
|
|
|
|
grid-gap: 0 1rem;
|
2020-01-08 18:32:10 +00:00
|
|
|
@media all and (max-width: 400px) {
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
}
|
2020-01-08 15:21:46 +00:00
|
|
|
img {
|
|
|
|
|
grid-row: 1 / -1;
|
|
|
|
|
background: var(--lightblue);
|
|
|
|
|
font-size: 1rem;
|
|
|
|
|
}
|
|
|
|
|
.displayLink {
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
color: var(--vape);
|
|
|
|
|
letter-spacing: 1px;
|
|
|
|
|
font-size: 1.2rem;
|
|
|
|
|
:hover {
|
|
|
|
|
color: var(--pink);
|
|
|
|
|
}
|
2020-01-07 22:58:15 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const PersonDeets = styled.div`
|
|
|
|
|
display: flex;
|
2020-01-08 18:54:07 +00:00
|
|
|
border-top: 1px solid var(--vape);
|
2020-01-07 22:58:15 +00:00
|
|
|
> * {
|
|
|
|
|
flex: 1;
|
2020-01-08 18:54:07 +00:00
|
|
|
border-left: 1px solid var(--vape);
|
2020-01-07 22:58:15 +00:00
|
|
|
text-align: center;
|
|
|
|
|
padding: 1rem;
|
|
|
|
|
display: grid;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
grid-template-columns: auto auto;
|
2020-01-08 18:54:07 +00:00
|
|
|
&:first-child {
|
|
|
|
|
border-left: 0;
|
|
|
|
|
}
|
2020-01-07 22:58:15 +00:00
|
|
|
}
|
|
|
|
|
a {
|
|
|
|
|
color: var(--vape);
|
|
|
|
|
}
|
|
|
|
|
.country {
|
|
|
|
|
font-size: 3rem;
|
|
|
|
|
}
|
|
|
|
|
.phone {
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
2020-01-08 18:32:10 +00:00
|
|
|
@media all and (max-width: 400px) {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
2020-01-09 16:42:47 +00:00
|
|
|
> *:nth-child(1),
|
|
|
|
|
> *:nth-child(2) {
|
2020-01-08 18:32:10 +00:00
|
|
|
/* lol */
|
2020-01-09 16:42:47 +00:00
|
|
|
border-bottom: 1px solid var(--vape);
|
2020-01-08 18:32:10 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-01-07 22:58:15 +00:00
|
|
|
`;
|
2020-01-08 16:58:45 +00:00
|
|
|
|
|
|
|
|
const TwitterHandle = styled.span`
|
|
|
|
|
font-size: 1.24323423426928098420394802rem;
|
|
|
|
|
.at {
|
|
|
|
|
color: var(--yellow);
|
|
|
|
|
margin-right: 2px;
|
|
|
|
|
}
|
|
|
|
|
`;
|