diff --git a/README.md b/README.md index 861243c..08310a4 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ # To do -- Régler problème de scoll entre page -- Rajouter les images manquantes des projects +- Refaire les images qui vont pas - Faire une page explicative par projet - Faire du responsive ## Plus tard +- Régler problème de scoll entre page - Refaire la section des skills -- Ajouter un fonction de filtrage des projects (en fonction de la date, des skills, school ou non) ## Usefull commands diff --git a/src/components/Filter/Filter.css b/src/components/Filter/Filter.css new file mode 100644 index 0000000..f1e1937 --- /dev/null +++ b/src/components/Filter/Filter.css @@ -0,0 +1,127 @@ +.filter-btn { + position: absolute; + top: 2em; + right: 20px; + border: none; + background: none; + padding: 14px; + cursor: pointer; + z-index: 10; + transition: background-color 0.3s ease; +} + +.filter-btn svg { + color: var(--text-color); + transition: all 0.3s ease; +} + +.filter-btn svg:hover { + color: var(--title-color); + transform: translateY(-2px); +} + + +.filter-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(5px); + z-index: 100; +} + +.filter-sidebar { + position: fixed; + top: 0; + right: -100%; + width: 100%; + max-width: 350px; + height: 100%; + background: rgba(42, 42, 42, 0.5); + backdrop-filter: blur(15px); + border-left: solid rgba(100,100,100,0.5) 1px; + z-index: 101; + display: flex; + flex-direction: column; + transition: right 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + + +.filter-sidebar.visible { + right: 0; +} + +.filter-sidebar-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 1.5rem; + border-bottom: 1px solid rgba(100, 100, 100, 0.5); +} + + +.close-filter-btn { + background: none; + border: none; + color: var(--text-color); + cursor: pointer; + padding: 5px; + display: flex; + align-items: center; + justify-content: center; + transition: color 0.3s ease; +} + +.close-filter-btn:hover { + color: var(--title-color); +} + +.filter-sidebar-content { + padding: 1.5rem; + overflow-y: auto; +} + +.filter-sidebar-content h4 { + color: var(--text-color); + font-size: 0.9rem; + text-transform: uppercase; + letter-spacing: 1px; + margin-top: 0; + margin-bottom: 1rem; + display: flex; + justify-content: start; +} + +.filter-group { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + margin-bottom: 2rem; +} + +.filter-tag { + background-color: transparent; + border: 1px solid var(--text-color); + color: var(--text-color); + padding: 8px 16px; + border-radius: 20px; + cursor: pointer; + font-size: 0.9rem; + font-weight: 600; + text-decoration: none; + transition: all 0.3s ease; +} + +.filter-tag:hover { + background-color: var(--text-color); + color: #1E1E1E; + transform: translateY(-2px); +} + +.filter-tag.active { + background-color: rgba(217, 95, 70, 0.3); + color: var(--important-color); + border-color: var(--important-color); +} \ No newline at end of file diff --git a/src/components/Filter/Filter.jsx b/src/components/Filter/Filter.jsx new file mode 100644 index 0000000..58764b1 --- /dev/null +++ b/src/components/Filter/Filter.jsx @@ -0,0 +1,154 @@ +import './Filter.css'; +import React, {useEffect, useState} from "react"; + +function Filter({ filters, setFilters }) { + const [isFilterVisible, setIsFilterVisible] = useState(false); + const showFilters = () => setIsFilterVisible(true); + const hideFilters = () => setIsFilterVisible(false); + const [skills, setSkills] = useState([]); + const [error, setError] = useState(null); + + + const handleCategoryFilter = (category) => { + setFilters(prev => { + const alreadySelected = prev.category.includes(category); + return { + ...prev, + category: alreadySelected + ? prev.category.filter(c => c !== category) + : [...prev.category, category], + }; + }); + }; + + const toggleTechnologyFilter = (tech) => { + setFilters(prev => { + const alreadySelected = prev.technology.includes(tech); + return { + ...prev, + technology: alreadySelected + ? prev.technology.filter(t => t !== tech) + : [...prev.technology, tech], + }; + }); + }; + + const setYearOrder = (order) => { + setFilters(prev => ({ + ...prev, + yearOrder: prev.yearOrder === order ? null : order + })); + }; + + const resetFilters = () => { + setFilters({ + category: [], + technology: [], + yearOrder: filters.yearOrder, + }); + }; + + + + useEffect(() => { + if (isFilterVisible) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = ''; + } + + return () => { + document.body.style.overflow = ''; + }; + }, [isFilterVisible]); + + + + + useEffect(() => { + const fetchSkills = async () => { + try { + const response = await fetch('/api/skills/'); + if (!response.ok) { + throw new Error(`Erreur HTTP: ${response.status}`); + } + const data = await response.json(); + setSkills(data.data); + } catch (err) { + setError(err.message); + } + }; + fetchSkills(); + }, []); + + if (error) { + return
Here you can find a collection of my work.
+