You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
3.9 KiB

import React from "react";
import { css, cx } from "@emotion/css";
import Container from "../../components/Container";
import { otherProjects, projects, type Project } from "./data/project";
const styles = {
project: css`
position: relative;
background: var(--card-bg);
padding: 1.2rem;
cursor: default;
border-radius: 0.5rem;
display: flex;
flex-direction: column;
transition: all 200ms;
:hover {
filter: invert(0.08);
transform: translateY(-0.2rem);
}
header {
display: flex;
justify-content: space-between;
align-items: center;
}
header {
margin-bottom: 0.5rem;
}
`,
tag: css`
display: inline-block;
padding: 0.1rem 0.4rem;
background: var(--card-tags);
color: var(--text-colour);
border-radius: 0.2rem;
transition: all 200ms;
:hover {
background: var(--card-tags-hover);
}
& + & {
margin-left: 0.6rem;
}
`,
};
const ProjectUnit: React.FC<Project> = unit => {
return (
<div
className={styles.project}
title={unit.title + (unit.wip ? " (WIP)" : "")}>
<a
className={css`
display: flex;
flex-direction: column;
height: 100%;
text-decoration: none;
font-weight: 500;
cursor: ${unit.wip ? "default" : "pointer"};
`}
href={unit.wip ? undefined : unit.url}
target="_blank"
rel="noreferrer">
<header>
<h4>{unit.title}</h4>
<span
className={css`
color: var(--text-subdued);
font-size: 0.8rem;
font-family: monospace;
`}>
{"{"} {unit.cat} {"}"}
</span>
</header>
<p
className={css`
color: #bdbdbd;
margin-bottom: 0.8rem;
font-size: 0.9rem;
`}>
{unit.description}
</p>
<p
className={css`
font-weight: 500;
color: #9f9f9f;
font-size: 0.8rem;
margin-top: auto;
`}>
{unit.tags.map(tag => (
<span key={tag} className={styles.tag}>
{tag}
</span>
))}
</p>
</a>
</div>
);
};
const otherProjectsStyle = css`
width: 100%;
border-collapse: collapse;
border-radius: 0.5rem;
overflow: hidden;
color: var(--text-colour);
* {
border-collapse: collapse;
}
th {
color: var(--text-subdued);
}
th,
td {
padding: 0.9rem 1rem;
text-align: left;
line-height: 1.6;
}
td {
border-top: 1px solid var(--table-border);
}
/* border-bottom: 1px solid var(--table-border); */
td a {
display: block;
min-width: max-content;
}
`;
const Exp: React.FC = () => {
return (
<Container>
<h2>Things I've built</h2>
<p>A few projects I'm proud of:</p>
<div
className={css`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
gap: 1rem;
width: 100%;
`}>
{projects.map(unit => (
<ProjectUnit {...unit} key={unit.title} />
))}
</div>
<hr />
<p>
Apart from the above, I've also built some other interesting stuff over
time using a variety of technologies:
</p>
<table className={otherProjectsStyle}>
<thead>
<tr>
<th>Project</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{otherProjects.map(unit => (
<tr key={unit.title}>
<td
className={css`
vertical-align: top;
`}>
<a
className={cx(
unit.wip &&
css`
color: var(--text-subdued);
cursor: default;
`,
)}
href={unit.wip ? undefined : unit.url}
target="_blank"
rel="noreferrer"
title={unit.title + (unit.wip ? " (WIP)" : "")}>
{unit.title}
</a>
</td>
<td>
{unit.description}
<span
className={css`
margin-top: 0.4rem;
display: block;
color: var(--text-subdued);
font-size: 0.9rem;
font-family: monospace;
`}>
# {unit.tags.join(", ")}
</span>
</td>
</tr>
))}
</tbody>
</table>
</Container>
);
};
export default Exp;