ent en cours

This commit is contained in:
trochas
2026-01-06 15:06:48 +01:00
parent defefd2c79
commit d5ea854dcb
13 changed files with 256 additions and 101 deletions

View File

@@ -1,38 +1,6 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
background-color: var(--tint4);
color: var(--text);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -1,11 +1,11 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
import { ReactKeycloakProvider } from '@react-keycloak/web'
import keycloak from './keycloak'
import Login from './components/login';
import { LocalDataProvider } from './provider/LocalDataProvider';
import ENT from './components/ent';
import SwitchThemeColor from './components/SwitchThemeColor';
const keycloakInitOptions = {
@@ -18,22 +18,10 @@ function App() {
<ReactKeycloakProvider authClient={keycloak} /*initOptions={keycloakInitOptions}*/>
<LocalDataProvider>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<SwitchThemeColor/>
<h1>Frisbyee</h1>
<Login/>
<ENT/>
</header>
</div>
</LocalDataProvider>
</ReactKeycloakProvider>

View File

@@ -3,7 +3,7 @@ export type Groupe = "Entrainement" | "Competition" | "Loisir";
export class User{
id!: number;
nom!: String;
sessions!: Session[]; //nb: Admin liaison non symétrique /!\
sessions: Session[] = []; //nb: Admin liaison non symétrique /!\
}
export class Admin extends User{
@@ -23,7 +23,7 @@ export class Session{
id!: number;
activites!: Activite[];
isRecurent! : Boolean;
Creneau!: Date;
creneau!: Date;
coach!: Coach;
athletes!: Athlete[]
duree! : number;
@@ -36,6 +36,27 @@ export class Activite{
session!: Session;
theme!: String;
data!: Map<String,String>;
Duree!: number;
duree!: number;
}
}
export function getUserTest():User{
const user = new User();
const s1 = new Session();
const s2 = new Session();
const s3 = new Session();
user.id = 0;
user.nom = "Emilien-Yee NootNoot";
s1.creneau = new Date();
s1.id = 1;
var date2 = new Date();
date2.setDate(date2.getDate() + 2);
s2.creneau = date2;
s2.id = 2;
s3.creneau = date2;
s3.id = 3;
user.sessions.push(s1);
user.sessions.push(s2);
user.sessions.push(s3);
return user;
}

View File

@@ -0,0 +1,38 @@
import { useState,useEffect } from 'react';
import './style/SwitchThemeColor.css';
const SwitchThemeColor = () => {
const [theme, setTheme] = useState<'light' | 'dark'>('dark');
/*
Inverse le thème actuel
*/
function switchTheme(){
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'light' ? 'dark' : 'light'
//const newTheme = window.matchMedia("(prefers-color-scheme: dark)").matches? "dark": "light";
setTheme(newTheme)
document.documentElement.setAttribute('data-theme', newTheme);
}
/*
détecte automatiquement le thème du navigateur au démarrage
*/
useEffect(() => {
const newTheme = window.matchMedia("(prefers-color-scheme: dark)").matches? "dark": "light";
setTheme(newTheme)
document.documentElement.setAttribute('data-theme', newTheme);
}, []);
return (
<div>
<button className="ButtonTheme" onClick={switchTheme}>
{theme === 'light' ? '𖤓' : '☾'}
</button>
</div>
);
};
export default SwitchThemeColor;

View File

@@ -1,5 +0,0 @@
.ent_colonne {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 16px;
}

View File

@@ -1,63 +1,119 @@
import { useState } from "react"
import { Session, User } from "../classes"
import { useEffect, useState } from "react"
import { getUserTest, Session, User } from "../classes"
import { useLocalData } from "../context/useLocalData"
import './ent.css';
//import {updateSessionsOfUser } from "../requetes";
import './style/ent.css';
import {updateSessionsOfUser } from "../requetes";
export const ENT =() =>{
const {user} = useLocalData()
const {user,setUser} = useLocalData()
const [sessions, setSessions] = useState<Session[]>([])
const [week,setWeek] = useState<Date>(new Date());
const [week,setWeek] = useState<Date>(getFirstDay(new Date()));
const week_days:String[] = ["Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"];
const week_days_nums:number[] = [1,2,3,4,5,6,0];
function updateSessions(){
function loadSessions(date:Date){
var maxDate = getNextDay(date,6)
var newWeek: Session[] = []
user.sessions.forEach(session => {
newWeek.push(session);
if(session.creneau >= date && session.creneau <= maxDate){
newWeek.push(session);
}
});
setSessions(newWeek);
}
function changeWeek(){
updateSessions()
setWeek(new Date());
function changeWeek(date:Date){
setWeek(date);
loadSessions(date)
}
useEffect(() => {
updateWeek();
},[week])
async function updateWeek(){
//TODO updateSession
//await updateSessionsOfUser(user,null,null);
var newWeek: Session[] = []
user.sessions.forEach(session => {
newWeek.push(session);
});
setSessions(newWeek);
loadSessions(week);
setUser(getUserTest())
}
function handlePrev(): void {
changeWeek(getNextDay(week,-7));
}
function handleNext(): void {
changeWeek(getNextDay(week,7));
}
function getFirstDay(date:Date):Date{
const numWeek = date.getDay();
var firstDate:Date;
if(numWeek == 0){
firstDate = getNextDay(date,-6);
}
else{
firstDate = getNextDay(date,-numWeek+1);
}
return firstDate;
}
function getNextDay(date:Date,nb:number):Date{
var newDate = new Date(date);
newDate.setDate(newDate.getDate() + nb);
return newDate;
}
function dateToString(date:Date){
const dd_prefix = date.getDate()<10 ? "0" : "";
const mm_prefix = date.getMonth()+1<10 ? "0" : "";
const dd:String = dd_prefix+date.getDate().toString();
const mm:String = mm_prefix+(date.getMonth()+1).toString();
const yyyy:String = date.getFullYear().toString();
return dd+"/"+mm+"/"+yyyy;
}
function hoursToString(date:Date){
const hh_prefix = date.getDate()<10 ? "0" : "";
const mm_prefix = date.getMonth()+1<10 ? "0" : "";
const hh:String = hh_prefix+date.getHours().toString();
const mm:String = mm_prefix+date.getMinutes().toString();
return hh+"h"+mm;
}
function displaySession(session:Session){
const sDate = session.creneau;
return(
<div className="ent_session">
<div>{sDate.getHours()+"h"+sDate.getMinutes()}</div>
{dateToString(sDate)}
<div>{session.id}</div>
</div>
)
}
return(
<div className="ent">
<div className="ent_colonne">
<div>
Lundi
</div>
<div>
Mardi
</div>
<div>
Mercredi
</div>
<div>
Jeudi
</div>
<div>
Vendredi
</div>
<div>
Samedi
</div>
<div>
Dimanche
</div>
<div className="ent_header">
<button className="ent_button" onClick={() =>handlePrev()}>Prev</button>
<button className="ent_button" onClick={() => handleNext()}>Next</button>
</div>
<div className="ent_colonnes">
{week_days_nums.map((num,index)=>(
<div className="ent_lines">
{week_days[index]} {dateToString(getNextDay(week,index))}
{sessions.map((session,index2)=>(
session.creneau.getDay()===num &&
displaySession(session)
))}
</div>
))}
</div>
</div>

View File

@@ -0,0 +1,11 @@
.ButtonTheme{
height: 35px;
width: 39px;
color: var(--text);
background-color: var(--tint3);
border-radius: 10px;
margin: 0px;
font-size: 20px;
display: inline;
border-color: var(--accent1);
}

View File

@@ -0,0 +1,46 @@
.ent{
justify-content: center;
/* background-color: #FF0000; */
padding: 10px;
}
.ent_header{
justify-content: center;
display: grid;
grid-template-columns: repeat(2, 1fr);
/* background-color: #0000FF; */
padding-bottom: 10px;
gap: 30%;
}
.ent_colonnes {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 16px;
color: var(--text);
/* background-color: #00FF00; */
width: 100%;
}
.ent_lines {
display: grid;
gap: 16px;
background-color: var(--tint2);
padding: 8px;
border-radius: 20px;
}
.ent_session {
gap: 5px;
background-color: var(--tint3);
border-radius: 20px;
padding: 8px;
}
.ent_button{
background-color: var(--tint3);
color: var(--text);
height: 30px;
border-radius: 20px;
}

View File

@@ -1,3 +1,35 @@
[data-theme='dark']{
--tint1: #000000;
--tint2: #191c20;
--tint3: #282c34;
--tint4: rgb(53, 59, 72);
--text: #FFFFFF;
--text2:#000000;
--accent1: #44c1ee;
--accent2: #0b235f;
--disable: #030918;
}
[data-theme='light']{
--tint1: #FFFFFF;
--tint2: #E8E8EE;
--tint3: #D0D0DD;
--tint4: rgb(181, 181, 194);
--text: #000000;
--text2:#FFFFFF;
--accent1: #44c1ee;
--accent2: #113388;
--disable: #061231;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',

View File

@@ -1,5 +1,5 @@
import { Activite, Athlete, Coach, Session, User } from "./classes";
/*import { useKeycloak } from '@react-keycloak/web'
import { useKeycloak } from '@react-keycloak/web'
const { keycloak } = useKeycloak()
@@ -7,7 +7,7 @@ const useAuthHeader = () => {
return keycloak?.token
? { Authorization: `Bearer ${keycloak.token}` }
: {}
}*/
}
//UPDATE /////////////////////////////////////////////////////////