reorganization of the tree structure

This commit is contained in:
2025-09-02 19:17:00 +02:00
parent cf37db8c88
commit 50485a4f55
22 changed files with 23 additions and 23 deletions
@@ -0,0 +1,157 @@
.single-project {
display: flex;
flex-direction: column;
width: 29%;
margin: 2rem auto;
overflow: hidden;
transition: all 0.3s ease-in-out;
border-radius: 12px;
background-color: #1E1E1E;
}
.single-project:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
.single-project-left {
position: relative;
flex-shrink: 0;
width: 100%;
display: flex;
justify-content: center;
align-items: start;
overflow: hidden;
height: 210px;
}
.single-project-left img {
width: 100%;
height: auto;
display: block;
transition: opacity 0.3s ease-in-out;
opacity: 1;
object-fit: cover;
}
.single-project-left img.fade-out {
opacity: 0;
}
.single-project-right {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 2rem 2rem 2rem 0rem;
align-items: flex-start;
height: 100%;
}
.single-project-right-top {
display: flex;
margin-left: 2rem;
}
.single-project-right-bottom {
margin-left: 2rem;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
}
.single-project-line {
border-radius: 38px;
min-width: 1.5rem;
height: 0.25rem;
margin-top: 1.5rem;
margin-right: 1rem;
}
.color-blue {
background-color: #2556ff;
}
.color-green {
background-color: #36a837;
}
.color-purple {
background-color: #a646d9;
}
.color-red {
background-color: #ff0000;
}
.color-yellow {
background-color: #ffd427;
}
.single-project-title {
font-size: 2rem;
color: #EAEAEA;
margin-top: 0;
margin-bottom: 1rem;
}
.single-project-description {
color: #B0B0B0;
margin-bottom: 1.5rem;
text-align: justify;
}
.single-project-skills-list {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 0;
margin: 0;
gap: 8px;
}
.single-project-link {
color: #B0B0B0;
text-decoration: none;
font-weight: 600;
margin-bottom : 0;
}
.single-project-link:hover {
cursor: pointer;
color: #EAEAEA;
}
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: #EAEAEA;
font-size: 35px;
display: none;
transition: all 0.3s ease;
text-shadow: 0 0 6px rgba(0, 0, 0, 0.7);
}
.arrow:hover {
color: #D95F46;
opacity: 0.8;
transform: translateY(-50%) scale(1.2);
cursor: pointer;
}
.arrow.preview {
left: 10px;
}
.arrow.next {
right: 10px;
}
.single-project-left:hover .arrow {
display: flex;
}
@@ -0,0 +1,80 @@
import { useState, useEffect, useRef } from "react";
import SkillCard from "../SkillCard/SkillCard.jsx";
import "./SingleProject.css";
function SingleProject({ image, title, description, skills, id, nbImage }) {
const [imageID, setImageID] = useState(1);
const [isFading, setIsFading] = useState(true);
const intervalRef = useRef(null);
const color = ["blue", "green", "purple", "red", "yellow"]
const handleChangeImage = (direction) => {
if (nbImage <= 1) return;
setIsFading(false);
setTimeout(() => {
setImageID((prevID) =>
direction === 1
? (prevID % nbImage) + 1
: prevID === 1 ? nbImage : prevID - 1
);
setIsFading(true);
}, 300);
clearInterval(intervalRef.current);
startAutoSlide();
};
const startAutoSlide = () => {
intervalRef.current = setInterval(() => {
handleChangeImage(1);
}, 5000);
};
useEffect(() => {
startAutoSlide();
return () => clearInterval(intervalRef.current);
}, []);
return (
<div className="single-project">
<div className="single-project-left">
<button onClick={() => handleChangeImage(-1)} className="arrow preview">{'<'}</button>
<img
src={`/assets/images/${image}/${image}_${imageID}.png`}
alt={image}
className={isFading ? 'fade-in' : 'fade-out'}
/>
<button onClick={() => handleChangeImage(1)} className="arrow next">{'>'}</button>
</div>
<div className="single-project-right">
<div className="single-project-right-top">
<div className={`single-project-line color-${color[(id-1)%color.length]}`}></div>
<h3 className="single-project-title">{title}</h3>
</div>
<div className="single-project-right-bottom">
<p className="single-project-description" style={{ whiteSpace: "pre-line" }}>
{description}
</p>
<ul className="single-project-skills-list">
{skills.map((skill) => (
<li key={skill}>
<SkillCard text={skill} />
</li>
))}
</ul>
<p className="single-project-link">Learn more</p>
</div>
</div>
</div>
);
}
export default SingleProject;