diff --git a/src/index.css b/src/index.css index 6246007..ce69093 100644 --- a/src/index.css +++ b/src/index.css @@ -65,6 +65,19 @@ body { overflow: hidden; } +.glassBorder{ + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + h1 { font-size: 3.2em; line-height: 1.1; diff --git a/src/pages/Home/HomePage.jsx b/src/pages/Home/HomePage.jsx index fc12601..ae603b2 100644 --- a/src/pages/Home/HomePage.jsx +++ b/src/pages/Home/HomePage.jsx @@ -1,11 +1,181 @@ +import { useState } from "react"; +import { useMemo } from "react"; +import styles from "./HomePage.module.css"; +function HomePage() { + const events = { + "2025-11-07": ["Réunion de projet", "Anniversaire de Marie"], + "2025-11-10": ["Cours de React", "Rendez-vous médecin"], + "2025-11-14": ["Sortie cinéma"], + }; -function HomePage(){ + const monthNames = [ + "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", + "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" + ]; + + const today = new Date(); + const [currentMonth, setCurrentMonth] = useState(today.getMonth()); + const [currentYear, setCurrentYear] = useState(today.getFullYear()); + const [selectedDay, setSelectedDay] = useState(() => { + const year = today.getFullYear(); + const month = String(today.getMonth() + 1).padStart(2, "0"); + const day = String(today.getDate()).padStart(2, "0"); + const key = `${year}-${month}-${day}`; + return { date: key, events: events[key] || [] }; + }); + + const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate(); + const firstDay = new Date(currentYear, currentMonth, 1).getDay(); + const startDay = (firstDay + 6) % 7; + + const days = []; + for (let i = 0; i < startDay; i++) days.push(null); + for (let i = 1; i <= daysInMonth; i++) days.push(i); + + const handlePrevMonth = () => { + let newMonth = currentMonth - 1; + let newYear = currentYear; + + if (newMonth < 0) { + newMonth = 11; + newYear--; + } + + setCurrentMonth(newMonth); + setCurrentYear(newYear); + + const key = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-01`; + setSelectedDay({ date: key, events: events[key] || [] }); + }; + + const handleNextMonth = () => { + let newMonth = currentMonth + 1; + let newYear = currentYear; + + if (newMonth > 11) { + newMonth = 0; + newYear++; + } + + setCurrentMonth(newMonth); + setCurrentYear(newYear); + + const key = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-01`; + setSelectedDay({ date: key, events: events[key] || [] }); + }; + + const handleDayClick = (day) => { + if (!day) return; + const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + setSelectedDay({ date: key, events: events[key] || [] }); + }; + + const sortedEvents = useMemo(() => { + return Object.entries(events) + .map(([dateKey, eventList]) => ({ date: dateKey, events: eventList })) + .sort((a, b) => new Date(a.date) - new Date(b.date)); + }, [events]); + + const formatDate = (dateString) => { + const [year, month, day] = dateString.split('-'); + return `${day} ${monthNames[parseInt(month) - 1]} ${year}`; + }; return ( -
+
+
+
+
+ +

{monthNames[currentMonth]} {currentYear}

+ +
+ + + + + + + + + + + + + + + + {Array.from({ length: Math.ceil(days.length / 7) }).map((_, weekIndex) => ( + + {days.slice(weekIndex * 7, weekIndex * 7 + 7).map((day, index) => { + const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + const hasEvent = events[key]; + + return ( + + ); + })} + + ))} + +
LunMarMerJeuVenSamDim
handleDayClick(day)} + > + {day || ""} +
+ + {selectedDay && ( +
+

Événements du {formatDate(selectedDay.date)}

+ + {selectedDay.events.length > 0 ? ( +
    + {selectedDay.events.map((ev, i) => ( +
  • {ev}
  • + ))} +
+ ) : ( +

Aucun événement ce jour-là.

+ )} +
+ )} +
+
+
+
+

Liste des Événements à Venir

+ {sortedEvents.length > 0 ? ( +
    + {sortedEvents.map((eventGroup) => ( +
  • +
    + {formatDate(eventGroup.date)} +
    +
      + {eventGroup.events.map((event, i) => ( +
    • - {event}
    • + ))} +
    +
  • + ))} +
+ ) : ( +

Aucun événement planifié pour l'instant.

+ )} +
+
- ) + ); } export default HomePage; \ No newline at end of file diff --git a/src/pages/Home/HomePage.module.css b/src/pages/Home/HomePage.module.css index e83a063..7d6a67a 100644 --- a/src/pages/Home/HomePage.module.css +++ b/src/pages/Home/HomePage.module.css @@ -1,3 +1,173 @@ -.title { - color: red; +.calendarContainer { + padding: 20px; + font-family: Arial, sans-serif; + display: flex; + flex-direction: column; + align-items: center; +} + +.calendarHeader { + display: flex; + width: 100%; + flex-direction: row; + justify-content: space-between; + align-items: center; + gap: 10px; +} + +.calendarHeader p { + width: auto; + text-align: center; + font-weight: bold; + font-size: 40px; +} + +.calendarHeader button { + top: 50%; + left: 50%; + width: 40px; + height: 40px; + border-radius: 50%; + border: none; + background: transparent; + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); + font-size: 15px; + color: #019AFF; + cursor: pointer; +} + +.calendar { + border-collapse: collapse; + width: 80%; + max-width: 500px; +} + +.calendar th, .calendar td { + border: none; + padding: 10px; + width: 14.2%; + line-height: 130%; + text-align: center; + cursor: pointer; +} + +.today { + color: #007bff; +} + +.hasEvent { + position: relative; +} + +.hasEvent::before { + content: ""; + position: absolute; + left: 50%; + bottom: 10px; + width: 20px; + height: 2px; + background-color: #007bff; + transform: translateX(-50%); + border-radius: 10px; +} + +.hasEvent.selected::before { + width: 25px; + height: 2px; + bottom: 10px; +} + +.selected { + position: relative; + font-size: 18px; + font-weight: 600; +} + +.selected::after { + content: ""; + position: absolute; + top: 50%; + left: 50%; + width: 40px; + height: 40px; + transform: translate(-50%, -50%); + border-radius: 38%; + pointer-events: none; + background: transparent; + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + +.eventBox { + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + +.eventBox ul { + list-style-type: disc; +} + +.eventGroup{ + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + +.glassCard { + width: 45%; + margin: 16px; + padding: 10px 20px 10px 20px; + height: fit-content; + background: rgba(255, 255, 255, 0.65); + backdrop-filter: blur(3px); + -webkit-backdrop-filter: blur(3px); + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.5), + inset 0 -1px 0 rgba(255, 255, 255, 0.1), + inset 0 0 8px 4px rgba(255, 255, 255, 0.4); + overflow: hidden; +} +.allContent{ + display: flex; + flex-direction: row; +} + +@media (max-width: 768px) { + .glassCard { + width: 100%; + margin: 0px; + margin-top: 16px; + margin-bottom: 16px; + display: flex; + } + + + .allContent{ + display: flex; + flex-direction: column; + } } \ No newline at end of file