Project page added + Overall Improvements

This commit is contained in:
IM23a-spirgif
2025-04-08 20:40:00 +02:00
parent ba67253366
commit 1fb265b604
8 changed files with 190 additions and 7 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

+20
View File
@@ -1,5 +1,6 @@
"use client" "use client"
import {useRef, useState, useEffect} from "react"; import {useRef, useState, useEffect} from "react";
import Link from "next/link";
export default function About() { export default function About() {
const timelineData = [ const timelineData = [
@@ -149,6 +150,8 @@ export default function About() {
width: "100%", width: "100%",
height: "100%", height: "100%",
scrollBehavior: "smooth", scrollBehavior: "smooth",
scrollbarWidth: "none", // Firefox
msOverflowStyle: "none", // IE/Edge
}} }}
> >
{timelineData.map((item, index) => ( {timelineData.map((item, index) => (
@@ -220,6 +223,23 @@ export default function About() {
</div> </div>
))} ))}
</div> </div>
<div style={{marginTop: "3rem"}}>
<Link href="/projects">
<button
className="learnMoreButton"
style={{
padding: "1rem 2rem",
fontSize: "1.25rem",
border: "none",
borderRadius: "5px",
color: "#fff",
cursor: "pointer",
}}
>
View Projects
</button>
</Link>
</div>
</section> </section>
)} )}
</div> </div>
+83
View File
@@ -129,6 +129,13 @@ html {
background-color: #2e002e; background-color: #2e002e;
} }
@keyframes pulsePrompt {
0% { opacity: 0.6; transform: translateY(0); }
50% { opacity: 1; transform: translateY(-5px); }
100% { opacity: 0.6; transform: translateY(0); }
}
.scrollPrompt { .scrollPrompt {
position: fixed; position: fixed;
bottom: 20px; bottom: 20px;
@@ -140,6 +147,7 @@ html {
font-size: 1rem; font-size: 1rem;
z-index: 1000; z-index: 1000;
background: none; background: none;
animation: pulsePrompt 2s infinite ease-in-out;
} }
.fade-in-section.is-visible { .fade-in-section.is-visible {
@@ -151,6 +159,13 @@ html {
display: none; display: none;
} }
.learnMoreButton:hover {
background-color: #2e002e;
transform: scale(1.05);
box-shadow: 0 0 10px #600060;
}
body { body {
-ms-overflow-style: none; -ms-overflow-style: none;
scrollbar-width: none; scrollbar-width: none;
@@ -193,3 +208,71 @@ body {
transform: translateY(8px); transform: translateY(8px);
} }
} }
body {
overflow-x: hidden;
}
@media (max-width: 768px) {
.section {
flex-direction: column;
text-align: center;
}
}
.projectContainer {
min-height: 100vh;
padding: 2rem;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.projectCard {
max-width: 800px;
padding: 2rem;
border-radius: 10px;
border: 2px solid #3d003d;
background-color: rgba(20, 0, 20, 0.4);
transition: opacity 0.3s ease;
}
.projectImage {
border-radius: 10px;
margin: 1.5rem 0;
border: 4px solid #3d003d;
animation: pulseBorder 1.5s infinite alternate ease-in-out;
}
.projectNavigation {
margin-top: 2rem;
display: flex;
gap: 2rem;
}
.arrowButton {
padding: 0.75rem 1.5rem;
font-size: 1.5rem;
background-color: #3d003d;
border: none;
border-radius: 5px;
color: #fff;
cursor: pointer;
transition: background-color 0.3s ease;
}
.arrowButton:hover {
background-color: #2e002e;
}
.fade-in {
opacity: 1;
}
.fade-out {
opacity: 0;
}
+12 -7
View File
@@ -10,17 +10,21 @@ export default function Home() {
const [title, setTitle] = useState("Fretux"); const [title, setTitle] = useState("Fretux");
const [phase, setPhase] = useState("normal"); const [phase, setPhase] = useState("normal");
useEffect(() => { useEffect(() => {
let fadeTimeout;
const interval = setInterval(() => { const interval = setInterval(() => {
setPhase("fadeOut"); setPhase("fadeOut");
setTimeout(() => { fadeTimeout = setTimeout(() => {
setTitle((prev) => (prev === "Fretux" ? "Frederik Spirgi" : "Fretux")); setTitle(prev => prev === "Fretux" ? "Frederik Spirgi" : "Fretux");
setPhase("fadeIn"); setPhase("fadeIn");
setTimeout(() => {
setPhase("normal"); fadeTimeout = setTimeout(() => setPhase("normal"), 500);
}, 500);
}, 500); }, 500);
}, 3000); }, 3000);
return () => clearInterval(interval);
return () => {
clearInterval(interval);
clearTimeout(fadeTimeout);
};
}, []); }, []);
useEffect(() => { useEffect(() => {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
@@ -62,7 +66,8 @@ export default function Home() {
<section className="section"> <section className="section">
<div className="textLeft"> <div className="textLeft">
<p> <p>
I&#39;m a passionate developer exploring web, game, and backend technologies with a focus on innovation and creativity. I&#39;m a passionate developer exploring web, game, and backend technologies with a focus on
innovation and creativity.
</p> </p>
</div> </div>
<div className="imageRight"> <div className="imageRight">
+75
View File
@@ -0,0 +1,75 @@
"use client";
import { useState } from "react";
import Image from "next/image";
const projectData = [
{
title: "Red Lake Stats",
description: "An interactive Javascript and Python application designed to calculate damage statistics for the Roblox game 'The Red Lake'",
image: "/images/portfolio-project1.png",
link: "https://fretux.ch/trlstats",
},
{
title: "SBB-History",
description: "A website about the creation of the SBB (Swiss Train Corporation) with an interactable map!",
image: "/images/portfolio-project2.png",
link: "https://sbb-history.fretux.ch",
},
{
title: "Fretux.ch",
description: "My first portfolio website, gameified for more user interaction.",
image: "/images/portfolio-project3.png",
link: "https://fretux.ch",
},
];
export default function ProjectsPage() {
const [currentIndex, setCurrentIndex] = useState(0);
const [fade, setFade] = useState(false);
const handleNavigation = (direction) => {
setFade(true);
setTimeout(() => {
setCurrentIndex((prev) => {
const newIndex =
direction === "next"
? (prev + 1) % projectData.length
: (prev - 1 + projectData.length) % projectData.length;
return newIndex;
});
setFade(false);
}, 300);
};
const project = projectData[currentIndex];
return (
<div className="projectContainer">
<div className={`projectCard ${fade ? "fade-out" : "fade-in"}`}>
<h2 className="projectTitle">{project.title}</h2>
<Image
src={project.image}
alt={project.title}
width={600}
height={400}
className="projectImage"
/>
<p className="projectDescription">{project.description}</p>
<a href={project.link} target="_blank" rel="noopener noreferrer">
<button className="learnMoreButton" style={{ marginTop: "1.5rem" }}>
View Project
</button>
</a>
</div>
<div className="projectNavigation">
<button onClick={() => handleNavigation("prev")} className="arrowButton">
&larr;
</button>
<button onClick={() => handleNavigation("next")} className="arrowButton">
&rarr;
</button>
</div>
</div>
);
}
View File