Projects done

This commit is contained in:
HangerThem 2024-08-12 12:53:20 +02:00
parent a4299d0fc4
commit 58bd6769d0
6 changed files with 184 additions and 60 deletions

View file

@ -168,6 +168,14 @@ const SocialLinksContainer = styled.div`
color: rgb(var(--white));
}
}
@media (min-width: 768px) {
display: none;
}
@media (min-width: 820px) {
display: flex;
}
`
const Topbar = styled.div`

View file

@ -5,6 +5,7 @@ import { useState } from "react"
import { CaretLeftFill, CaretRightFill, Git } from "react-bootstrap-icons"
import projects from "@/data/projects"
import Link from "next/link"
import Image from "next/image"
const ProjectsContainer = styled.section`
width: 100%;
@ -15,6 +16,11 @@ const ProjectsContainer = styled.section`
align-items: center;
justify-content: center;
gap: 2rem;
@media (max-width: 1200px) {
padding: 1rem;
gap: 1rem;
}
`
const ProjectsContent = styled.div`
@ -27,23 +33,36 @@ const ProjectsContent = styled.div`
h2 {
font-size: 3rem;
font-weight: 600;
@media (max-width: 1200px) {
font-size: 2rem;
}
}
p {
font-size: 1.2rem;
font-weight: 400;
}
`
const CarouselContainer = styled.div`
width: 100%;
position: relative;
@media (max-width: 1200px) {
font-size: 1rem;
}
}
`
const CarouselWrapper = styled.div`
display: flex;
transition: transform 0.5s ease-in-out;
gap: 2rem;
@media (max-width: 1200px) {
flex-direction: column;
align-items: center;
}
`
const CarouselContainer = styled.div`
width: 100%;
position: relative;
`
const ProjectCard = styled.div`
@ -61,52 +80,42 @@ const ProjectCard = styled.div`
h3 {
font-size: 2rem;
font-weight: 600;
@media (max-width: 1200px) {
font-size: 1.5rem;
}
}
p {
font-size: 1.2rem;
font-weight: 400;
}
a {
font-size: 1.2rem;
font-weight: 600;
color: rgb(var(--white));
background-color: rgb(var(--blue));
padding: 0.5rem 1rem;
border-radius: 0.25rem;
text-decoration: none;
transition: background-color 0.2s;
&:hover {
background-color: rgb(var(--light-blue));
@media (max-width: 1200px) {
font-size: 1rem;
}
}
img {
width: 200px;
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 1rem;
@media (max-width: 1200px) {
height: 150px;
}
}
&:not(.active) {
opacity: 0.5;
transform: scale(0.8);
}
`
const StateIndicator = styled.div`
position: absolute;
top: -1rem;
right: -1rem;
font-size: 1.5rem;
text-align: center;
line-height: 3rem;
background-color: rgba(var(--white));
border-radius: 50%;
width: 3rem;
height: 3rem;
@media (max-width: 1200px) {
width: 100%;
height: auto;
padding: 1rem;
}
`
const NavigationButton = styled.button`
@ -124,6 +133,10 @@ const NavigationButton = styled.button`
&:hover {
color: rgb(var(--white));
}
@media (max-width: 1200px) {
display: none;
}
`
const PrevButton = styled(NavigationButton)`
@ -139,6 +152,10 @@ const CarouselIndicator = styled.div`
justify-content: center;
gap: 0.5rem;
margin-top: 1rem;
@media (max-width: 1200px) {
margin-top: 0.5rem;
}
`
const IndicatorDot = styled.div`
@ -151,6 +168,11 @@ const IndicatorDot = styled.div`
&.active {
background-color: rgb(var(--white));
}
@media (max-width: 1200px) {
width: 8px;
height: 8px;
}
`
const TechStack = styled.div`
@ -159,14 +181,72 @@ const TechStack = styled.div`
gap: 0.5rem;
span {
font-size: 1rem;
font-size: 0.8rem;
font-weight: 400;
background-color: rgba(var(--white), 0.1);
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
@media (max-width: 1200px) {
font-size: 0.7rem;
padding: 0.2rem 0.4rem;
}
}
`
const Links = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 1rem;
margin-top: auto;
`
const ViewLink = styled(Link)`
font-size: 1.2rem;
font-weight: 600;
color: rgb(var(--white));
background-color: rgba(var(--primary), 0.8);
padding: 0.5rem 1rem;
border-radius: 0.25rem;
text-decoration: none;
transition: background-color 0.2s;
&:hover {
background-color: rgb(var(--primary));
}
@media (max-width: 1200px) {
font-size: 1rem;
padding: 0.4rem 0.8rem;
}
`
const SourceLink = styled(Link)`
svg {
transition: color 0.3s;
color: rgba(var(--white), 0.8);
}
&:hover svg {
color: rgb(var(--white));
}
@media (max-width: 1200px) {
svg {
width: 25px;
height: 25px;
}
}
`
const StateIndicator = styled.div`
position: absolute;
top: 1rem;
right: 1rem;
font-size: 1.5rem;
`
const Projects = () => {
const [currentIndex, setCurrentIndex] = useState(0)
const projectCount = projects.length
@ -188,7 +268,7 @@ const Projects = () => {
}
return (
<ProjectsContainer>
<ProjectsContainer id="projects">
<ProjectsContent>
<h2>📂 My Projects</h2>
<p>Here are some of the projects I&apos;ve worked on recently</p>
@ -206,12 +286,17 @@ const Projects = () => {
}
}}
>
<StateIndicator>
<StateIndicator title="Project State">
{project.state === "wip" ? "🔄" : "✅"}
</StateIndicator>
<h3>{project.title}</h3>
{project.image && (
<img src={project.image} alt={project.title} />
<Image
src={project.image}
alt={project.title}
width={400}
height={200}
/>
)}
<p>{project.description}</p>
<TechStack>
@ -219,10 +304,24 @@ const Projects = () => {
<span key={index}>{tech}</span>
))}
</TechStack>
{project.href && <Link href={project.href}>View Project</Link>}
<Link href={project.source}>
<Git />
</Link>
<Links>
{project.href && (
<ViewLink
href={project.href}
target="_blank"
title="View Project"
>
View Project
</ViewLink>
)}
<SourceLink
href={project.source}
target="_blank"
title="View Source"
>
<Git size={30} />
</SourceLink>
</Links>
</ProjectCard>
))}
</CarouselWrapper>

View file

@ -32,6 +32,7 @@ const Categories = styled.div`
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 2rem;
@ -48,6 +49,7 @@ const SkillCategory = styled.div`
flex-direction: column;
align-items: center;
gap: 2rem;
flex: 1;
h3 {
font-size: 1.75rem;

View file

@ -20,6 +20,11 @@ const links: Link[] = [
href: "#skills",
text: "Skills",
},
{
id: "projects",
href: "#projects",
text: "Projects",
},
{
id: "contact",
href: "#contact",

View file

@ -9,6 +9,24 @@ type Project = {
}
const projects: Project[] = [
{
title: "Ephemr",
description:
"A simple social network, a place to share your thoughts with the world.",
image: "/ephemr.png",
techStack: [
"Next.js",
"TypeScript",
"Styled Components",
"Socket.IO",
"Prisma",
"PostgreSQL",
"JWT",
],
href: "https://ephemr.net",
source: "https://github.com/HangerThem/ephemr",
state: "wip",
},
{
title: "HangerThem Portfolio",
description: "This very website and my personal portfolio.",
@ -28,16 +46,6 @@ const projects: Project[] = [
source: "https://github.com/HangerThem/linkboard",
state: "done",
},
{
title: "Ephemr",
description:
"A simple social network, a place to share your thoughts with the world.",
image: "/ephemr.png",
techStack: ["Next.js", "TypeScript", "Styled Components", "Socket.IO"],
href: "https://ephemr.net",
source: "https://github.com/HangerThem/ephemr",
state: "wip",
},
{
title: "Evolution algorithm Flappy Bird",
description:
@ -48,13 +56,7 @@ const projects: Project[] = [
source: "https://github.com/HangerThem/js-flappy-bird-ea",
state: "done",
},
{
title: "Peer to Peer Chat",
description: "A simple peer-to-peer chat application.",
techStack: ["Python"],
source: "https://github.com/HangerThem/python-p2p-real-time-chat",
state: "wip",
},
{
title: "Simple 2D physics engine",
description: "A simple 2D physics engine written in JavaScript.",
@ -64,6 +66,13 @@ const projects: Project[] = [
source: "https://hangerthem.github.io/js-2D-physic-engine/",
state: "wip",
},
{
title: "Peer to Peer Chat",
description: "A simple peer-to-peer chat application.",
techStack: ["Python"],
source: "https://github.com/HangerThem/python-p2p-real-time-chat",
state: "wip",
},
]
export default projects

9
package-lock.json generated
View file

@ -947,9 +947,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001584",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001584.tgz",
"integrity": "sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==",
"version": "1.0.30001651",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
"funding": [
{
"type": "opencollective",
@ -963,7 +963,8 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
],
"license": "CC-BY-4.0"
},
"node_modules/canvas-confetti": {
"version": "1.9.3",