diff --git a/src/components/Exp/Content.tsx b/src/components/Exp/Content.tsx new file mode 100644 index 0000000..098492e --- /dev/null +++ b/src/components/Exp/Content.tsx @@ -0,0 +1,101 @@ +import { css } from "@emotion/css"; +import React from "react"; +import { setupDynamicGradient } from "../../util"; +import { Experience } from "./types"; + +const Circle: React.FC = () => ( +
+
+
+
+); + +const btn = css` + display: flex; + flex-direction: column; + gap: 0.6rem; + cursor: pointer; + padding: 1rem var(--item-padding); + border-radius: 0.5rem; + position: relative; + height: max-content; + width: 100%; + + background-color: transparent; + border: none; + text-align: left; + display: inherit; + + & > * { + z-index: 10; + } + + @media (pointer: fine) { + &:hover { + background-color: var(--card-hover); + z-index: 1000; + box-shadow: 0 0 25rem 2rem rgba(190, 190, 190, 0.1); + } + } + + & .timeline-segment { + position: absolute; + } + + & .position { + color: var(--text-colour); + } + + & .year, + & h5 { + font-size: 0.8rem; + font-weight: 300; + color: var(--text-subdued); + } + + & h5 { + font-weight: 400; + margin-block-start: 0.2rem; + } +`; + +export const Content = ({ + onClick, + title, + year, + position, + location, +}: Experience) => { + return ( + + ); +}; diff --git a/src/components/Exp/Story.tsx b/src/components/Exp/Story.tsx new file mode 100644 index 0000000..48a7b52 --- /dev/null +++ b/src/components/Exp/Story.tsx @@ -0,0 +1,66 @@ +import React from "react"; +import { css, cx } from "@emotion/css"; +import { Experience } from "./types"; + +const story = css` + position: absolute; + left: 0; + width: 100%; + border-radius: 0.5rem; + display: flex; + + overflow: hidden; + + & .contents { + padding: 1.5rem; + line-height: 1.25rem; + display: flex; + flex-direction: row; + align-items: flex-start; + gap: 2rem; + margin-block-start: 1rem; + height: var(--story-height); + + & ul { + max-height: 100%; + margin: 0; + column-count: 3; + column-gap: 2rem; + color: var(--text-subdued); + font-weight: 400; + + & li + li { + margin-block-start: 0.5rem; + } + + & li::marker { + content: ""; + font-weight: 800; + padding-top: 1rem; + } + } + } +`; + +export const Story = ({ description, logo }: Experience) => { + return ( +
+
+ + +
+
+ ); +}; diff --git a/src/components/Exp/Unit.tsx b/src/components/Exp/Unit.tsx new file mode 100644 index 0000000..0951406 --- /dev/null +++ b/src/components/Exp/Unit.tsx @@ -0,0 +1,70 @@ +import React from "react"; +import { css, cx } from "@emotion/css"; +import { Story } from "./Story"; +import { Experience } from "./types"; +import { Content } from "./Content"; + +const expUnit = css` + --final-height: 20rem; + --unit-height: 9rem; + --story-height: calc(var(--final-height) - var(--unit-height)); + --transition-time: 300ms; + + & > * { + line-height: 1em; + font-size: 1rem; + } + + & button { + border: 1px solid transparent; + transition: all calc(var(--transition-time) * 2); + } + + &.active button { + background-color: var(--card-active); + border: 1px solid var(--card-active-border); + box-shadow: 0 0 50rem 0 rgba(190, 190, 190, 0.5); + z-index: 800; + + & .year, + & h5 { + color: var(--text-colour); + } + } + + margin-block-end: 0.5rem; + + /* -- Animation stuff -- */ + + height: var(--unit-height); + transition: height var(--transition-time) ease-in-out; + + & .story { + opacity: 0; + transition: opacity var(--transition-time) ease-in-out; + transition-delay: 0; + } + + &.active { + height: var(--final-height); + transition-delay: 0; + transition-delay: var(--transition-time); + + .story { + opacity: 1; + transition: opacity calc(var(--transition-time) * 2) ease-in-out; + transition-delay: var(--transition-time); + } + } + + /* -- */ +`; + +export const ExpUnit = (props: Experience) => { + return ( +
+ + +
+ ); +}; diff --git a/src/components/Exp/types.ts b/src/components/Exp/types.ts new file mode 100644 index 0000000..9f58d7f --- /dev/null +++ b/src/components/Exp/types.ts @@ -0,0 +1,10 @@ +export interface Experience { + active: boolean; + title: string; + location: string; + position: string; + year: string; + description: React.ReactElement | string; + logo: string; + onClick?: (e: React.MouseEvent) => void; +} diff --git a/src/pages/main/Exp.tsx b/src/pages/main/Exp.tsx index 4199bde..cf3ac7c 100644 --- a/src/pages/main/Exp.tsx +++ b/src/pages/main/Exp.tsx @@ -1,163 +1,22 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { css } from "@emotion/css"; import Container from "../../components/Container"; +import { ExpUnit } from "../../components/Exp/Unit"; +import { age, experience } from "./data/experience"; -const exp = [ - { - title: "The Feathers", - location: "Chennai (formerly Tirunelveli and Ooty)", - position: "Founder", - year: "2011-19", - }, - { - title: "StudioFlicks", - location: "Remote (Coimbatore)", - position: "Co-founder & Creative Head", - year: "2013-15", - }, - { - title: "Vinzas", - location: "Chennai", - position: "Architectural Intern", - year: "2014", - }, - { - title: "Blue Cube", - location: "Chennai", - position: "Architectural Intern", - year: "2015", - }, - { - title: "OutFocus Magazine", - location: "Ooty", - position: "Editor / developer", - year: "2014-17", - }, - { - title: "Zoho", - location: "Chennai", - position: "Technical Content Writer", - year: "2017", - }, - { - title: "Manoj Exports", - location: "Chennai", - position: "Designer & web dev", - year: "2017", - }, - { - title: "Klenty", - location: "Chennai", - position: "Full stack developer", - year: "2018", - }, - { - title: "Hugo's Way", - location: "Remote (Dublin)", - position: "Full stack developer", - year: "2018-19", - }, - { - title: "Navana Tech", - location: "Remote (Mumbai)", - position: "Lead webdev & architect", - year: "2021-22", - }, - { - title: "Feathers Studio", - location: "Chennai", - position: "Chief Maker", - year: "2019-present", - }, -].reverse(); - -const Circle: React.FC = () => ( -
-
-
-
-); - -type Experience = { - title: string; - location?: string; - position: string; - year: string; -}; +const Exp: React.FC = () => { + const [active, setActive] = useState(-1); -const ExpUnit: React.FC = ({ title, location, position, year }) => { - return ( -
- -

{title}

-
- - {position} - - {" . "} - - {year} - -
-
{location}
-
- ); -}; + useEffect(() => { + const handler = (e: KeyboardEvent) => { + if (e.key === "Escape") setActive(-1); + }; -const getAge = (date: string) => { - var today = new Date(); - var birthDate = new Date(date); - var age = today.getFullYear() - birthDate.getFullYear(); - var m = today.getMonth() - birthDate.getMonth(); - if (m < 0) return age - 1; - if (m === 0 && today.getDate() < birthDate.getDate()) return age - 1; - return age; -}; + window.addEventListener("keydown", handler); -const age = getAge("27 May 1995"); + return () => window.removeEventListener("keydown", handler); + }, []); -const Exp: React.FC = () => { return (

@@ -169,7 +28,6 @@ const Exp: React.FC = () => { Here are some places I’ve worked at{" "} (recent first) @@ -179,17 +37,25 @@ const Exp: React.FC = () => {
* { - padding-top: 4rem; + padding-top: 3rem; } `}> - {exp.map(unit => ( - + {experience.map((unit, i) => ( + setActive(active === i ? -1 : i)} + /> ))}