Skip to content

Instantly share code, notes, and snippets.

@UdaraJay
Created November 17, 2023 04:03
Show Gist options
  • Save UdaraJay/016d7f3bd17a35cfea3b212bdfbef3fd to your computer and use it in GitHub Desktop.
Save UdaraJay/016d7f3bd17a35cfea3b212bdfbef3fd to your computer and use it in GitHub Desktop.
Portfolio react page example
import { Link } from "gatsby"
import React, { useEffect, useState } from "react"
import * as styles from "./work.module.scss"
import WORK from "./work.json"
const WorkPage = () => {
const [focused, setFocus] = useState(false)
const toggleFocus = src => {
if (focused === false || focused !== src) {
setFocus(src)
return
}
setFocus(false)
}
const renderMedia = media => {
return media.map(m => {
switch (m.type) {
case "image":
return (
<div
className={`${styles.media} ${
focused == m.src && styles.focused
}`}
onClick={() => {
toggleFocus(m.src)
}}
>
<img src={m.src} className={styles.image} loading="eager" />
<div className={styles.des}>{m.des}</div>
</div>
)
case "video":
return (
<div
className={`${styles.media} ${
focused == m.src && styles.focused
}`}
onClick={() => {
toggleFocus(m.src)
}}
>
<video controls>
<source src={m.src} type="video/mp4" />
</video>
<div className={styles.des}>{m.des}</div>
</div>
)
break
case "twitter":
return (
<div
className={`${styles.media} ${
focused == m.src && styles.focused
}`}
onClick={() => {
toggleFocus(m.src)
}}
>
<div
className={styles.twitter}
dangerouslySetInnerHTML={{ __html: m.src }}
></div>
<div className={styles.des}>{m.des}</div>
</div>
)
break
default:
return null
}
})
}
const renderWork = () => {
return WORK.map(w => {
return (
<div className={styles.item} id={w.name}>
<div className={styles.timeline}>
<div className={styles.end}>{w.end_year}</div>
<div className={styles.line}></div>
<div className={styles.start}>{w.start_year}</div>
</div>
<div className={styles.content}>
<div className={styles.info}>
<div className={styles.name}>{w.name}</div>
<div className={styles.des}>{w.des}</div>
</div>
<div className={styles.mediaList}>{renderMedia(w.media)}</div>
</div>
</div>
)
})
}
return (
<div className={styles.container}>
<div className={styles.header}>
<div className={styles.highlight}>
<div className={styles.title}>Highlights</div>
Your description
</div>
</div>
<div className={styles.portfolio}>{renderWork()}</div>
</div>
)
}
export default WorkPage
[
{
"name": "Example",
"des": "Example",
"quote": "Example",
"position": "Example",
"tags": [
"Example",
"Example"
],
"start_year": "2023",
"end_year": "2023",
"media": [
{
"title": "",
"type": "video",
"src": "/example.mp4",
"des": "des"
},
]
}
]
.header {
margin-top: 70px;
margin-bottom: 70px;
margin-left: 46px;
width: 520px;
@media (max-width: 1025px) {
width: 100%;
margin-left: 0px;
}
.highlight {
font-size: 0.92em;
font-weight: 400;
line-height: 1.45;
color: var(--secondary-color);
width: 100%;
column-count: 1;
column-gap: 40px;
column-span: none;
.title {
color: var(--primary-color);
font-size: 1.75em;
font-weight: 600;
margin-bottom: 14px;
font-family: "Satoshi-Variable";
}
}
}
.portfolio {
display: block;
width: 100%;
.item {
display: flex;
.timeline {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
width: 34px;
color: var(--secondary-color);
margin-right: 14px;
.start {
display: inline-flex;
display: none;
transform: rotate(-90deg);
transform-origin: top left;
margin-top: 55px;
margin-left: 16px;
}
.line {
flex: 1 0 auto;
width: 1px;
// background: var(--border-color);
border-left: 1px dotted var(--border-color);
}
.end {
display: inline-flex;
transform: rotate(-90deg);
transform-origin: top left;
margin-top: 55px;
margin-left: 16px;
}
}
&:first-child {
}
.content {
flex: 1 0 auto;
padding: 10px 0;
max-width: calc(100% - 22px);
@media (max-width: 1025px) {
max-width: calc(100% - 30px);
}
.info {
.name {
font-family: "Satoshi-Variable";
font-size: 1.4em;
font-weight: 500;
margin-bottom: 4px;
}
.des {
color: var(--secondary-color);
}
}
.mediaList {
display: flex;
align-items: flex-end;
flex-wrap: wrap;
max-width: 100%;
margin: 24px 0;
gap: 24px;
.media {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 320px;
min-height: 360px;
background: var(--bg-color-secondary);
padding: 8px;
border-radius: 12px;
@media (max-width: 1025px) {
width: auto;
min-height: 180px;
margin-right: 22px;
}
.des {
font-size: 0.88em;
color: var(--secondary-color);
max-width: 380px;
line-height: 1.4;
padding: 5px 4px;
font-family: "Berkeley", monospace;
text-transform: uppercase;
font-weight: 500;
}
&:hover {
cursor: zoom-in;
}
&.focused {
width: 44%;
&:hover {
cursor: zoom-out;
}
}
video {
border-radius: 8px;
width: 100%;
height: auto;
object-fit: fit;
}
img {
border-radius: 8px;
width: 100%;
min-height: 270px;
object-fit: cover;
object-position: left center;
margin: 0;
padding: 0;
}
.twitter {
width: 100%;
padding: 0;
div {
margin: 0 !important;
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment