fix style

This commit is contained in:
trochas
2026-01-10 19:50:41 +01:00
parent e85f76c810
commit 62b9231d38
9 changed files with 144 additions and 138 deletions

View File

@@ -54,6 +54,12 @@ body {
transition: background-color 0.3s ease, color 0.3s ease; transition: background-color 0.3s ease, color 0.3s ease;
} }
.padding{
padding: 10px
}
code { code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace; monospace;
@@ -69,6 +75,14 @@ code {
background: linear-gradient(180deg, var(--tint0) 0%, var(--tint1) 100%); background: linear-gradient(180deg, var(--tint0) 0%, var(--tint1) 100%);
} }
.composant-container{
background-color: var(--tint2);
border-radius: 30px;
padding: 10px;
border: 2px solid var(--tint4);
box-shadow: 0 4px 6px rgba(16, 185, 129, 0.1);
}
/* Header / Navigation */ /* Header / Navigation */
.app-header { .app-header {
background-color: var(--tint1); background-color: var(--tint1);
@@ -145,7 +159,7 @@ input[type="time"],
input[type="search"], input[type="search"],
input[type="datetime-local"], input[type="datetime-local"],
textarea { textarea {
background-color: var(--tint2); background-color: var(--tint3);
color: var(--text); color: var(--text);
border: 2px solid var(--tint5); border: 2px solid var(--tint5);
border-radius: 8px; border-radius: 8px;
@@ -379,9 +393,9 @@ button.add:hover,
table { table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
background-color: var(--tint1);
border-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
width: fit-content;
} }
thead { thead {
@@ -402,9 +416,6 @@ td {
color: var(--text); color: var(--text);
} }
tr:hover {
background-color: var(--tint2);
}
/* Lists */ /* Lists */
ul, ol { ul, ol {

View File

@@ -4,10 +4,9 @@ import { calculStatsAthlete, niveauAlerte, StatsAthlete } from "../utils/athlete
interface AthleteStatsProps { interface AthleteStatsProps {
athlete: Athlete; athlete: Athlete;
sessions: Session[];
} }
function StatAthlete({ athlete, sessions }: AthleteStatsProps) { function StatAthlete({ athlete }: AthleteStatsProps) {
const [dateDebut, setDateDebut] = React.useState(new Date()); const [dateDebut, setDateDebut] = React.useState(new Date());
const [dateFin, setDateFin] = React.useState(new Date()); const [dateFin, setDateFin] = React.useState(new Date());
const [seuilCritique, setSeuilCritique] = React.useState(0); const [seuilCritique, setSeuilCritique] = React.useState(0);
@@ -20,49 +19,34 @@ function StatAthlete({ athlete, sessions }: AthleteStatsProps) {
}; };
const handleCalculerStats = () => { const handleCalculerStats = () => {
const statsCalculees = calculStatsAthlete(sessions, athlete, dateDebut, dateFin); const statsCalculees = calculStatsAthlete(athlete.sessions, athlete, dateDebut, dateFin);
setStats(statsCalculees); setStats(statsCalculees);
}; };
return ( return (
<div className="creneau-stats"> <div className="creneau-stats">
<label> <div>Nb Session : {athlete.sessions.length};</div>
Début : <table>
<input <tr>
type="datetime-local" <th>Début :</th>
value={dateToDatetimeLocal(dateDebut)} <th><input type="datetime-local" value={dateToDatetimeLocal(dateDebut)} onChange={e => setDateDebut(new Date(e.target.value))}/></th>
onChange={e => setDateDebut(new Date(e.target.value))} </tr>
/>
</label>
<label> <tr>
Fin : <th>Fin :</th>
<input <th><input type="datetime-local" value={dateToDatetimeLocal(dateFin)} onChange={e => setDateFin(new Date(e.target.value))}/></th>
type="datetime-local" </tr>
value={dateToDatetimeLocal(dateFin)}
onChange={e => setDateFin(new Date(e.target.value))}
/>
</label>
<label> <tr>
Seuil critique : <th>Seuil critique :</th>
<input <th><input type="number" value={seuilCritique} min={1} onChange={e => setSeuilCritique(Number(e.target.value))}/></th>
type="number" </tr>
value={seuilCritique}
min={1}
onChange={e => setSeuilCritique(Number(e.target.value))}
/>
</label>
<label> <tr>
Seuil max : <th>Seuil max :</th>
<input <th><input type="number" value={seuilMax} min={1} onChange={e => setSeuilMax(Number(e.target.value))}/></th>
type="number" </tr>
value={seuilMax} </table>
min={1}
onChange={e => setSeuilMax(Number(e.target.value))}
/>
</label>
<button onClick={handleCalculerStats}>Calculer les statistiques</button> <button onClick={handleCalculerStats}>Calculer les statistiques</button>

View File

@@ -3,6 +3,7 @@ import { Session, User, Coach, Activite, Groupe } from "../classes";
import { useLocalData } from "../context/useLocalData"; import { useLocalData } from "../context/useLocalData";
import { activiteService, sessionService } from "../api"; import { activiteService, sessionService } from "../api";
import { createSessionAPI, postSession } from "../requetes"; import { createSessionAPI, postSession } from "../requetes";
import './style/createSession.css';
export const CreateSession = () => { export const CreateSession = () => {
const {user} = useLocalData(); const {user} = useLocalData();
@@ -64,41 +65,48 @@ export const CreateSession = () => {
return ( return (
<div className="ent"> <div className="composant-container">
<h2>Créer une session</h2> <h2>Créer une session</h2>
<label> <table>
Nom: <tr>
<input type="text" value={name} onChange={e => setName(e.target.value)} /> <th>Nom:</th>
</label> <th><input type="text" value={name} onChange={e => setName(e.target.value)} /></th>
<label> </tr>
Groupe: <tr>
</label> <th>Groupe:</th>
<label> </tr>
Creneau: <tr>
<input type="datetime-local" value={creneau.toISOString().slice(0, 16)} onChange={e => setCreneau(new Date(e.target.value))} /> <th>Creneau:</th>
</label> <th><input type="datetime-local" value={creneau.toISOString().slice(0, 16)} onChange={e => setCreneau(new Date(e.target.value))} /></th>
<label> </tr>
Duree (minutes): <tr>
<input type="number" value={duree} onChange={e => setDuree(Number(e.target.value))} /> <th>Duree (minutes):</th>
</label> <th><input type="number" value={duree} onChange={e => setDuree(Number(e.target.value))} /></th>
<label> </tr>
Recurrent: <tr>
<input type="checkbox" checked={isRecurent} onChange={e => setIsRecurent(e.target.checked)} /> <th>Recurrent:</th>
</label> <th><input type="checkbox" checked={isRecurent} onChange={e => setIsRecurent(e.target.checked)} /></th>
<h3>Ajouter une activité : </h3> </tr>
<label> </table>
Nom de l'activitée: <div className="createActivite">
<input type="text" value={activiteNom} onChange={e => setActiviteNom(e.target.value)} /> <h3>Ajouter une activité : </h3>
</label>
<label> <table>
Theme: <tr>
<input type="text" value={activiteTheme} onChange={e => setActiviteTheme(e.target.value)} /> <th>Nom de l'activitée:</th>
</label> <th><input type="text" value={activiteNom} onChange={e => setActiviteNom(e.target.value)} /></th>
<label> </tr>
Duree (minutes): <tr>
<input type="number" value={activiteDuree} onChange={e => setActiviteDuree(Number(e.target.value))} /> <th>Theme:</th>
</label> <th><input type="text" value={activiteTheme} onChange={e => setActiviteTheme(e.target.value)} /></th>
<button type="button" onClick={addAcitivte}>Ajouter</button> </tr>
<tr>
<th>Duree (minutes):</th>
<th><input type="number" value={activiteDuree} onChange={e => setActiviteDuree(Number(e.target.value))} /></th>
</tr>
</table>
<button type="button" onClick={addAcitivte}>Ajouter</button>
</div>
<ul> <ul>
{activities.map((act, idx) => ( {activities.map((act, idx) => (

View File

@@ -130,7 +130,7 @@ export const EDT =() =>{
} }
return( return(
<div className="edt"> <div className="composant-container">
<div className="edt_header"> <div className="edt_header">
<button className="edt_button_week_select" onClick={() =>handlePrev()}>Prev</button> <button className="edt_button_week_select" onClick={() =>handlePrev()}>Prev</button>
<button onClick={()=>refresh()}>Actualiser</button> <button onClick={()=>refresh()}>Actualiser</button>
@@ -139,8 +139,8 @@ export const EDT =() =>{
<div className="edt_colonnes"> <div className="edt_colonnes">
<div className="top_left_loading">{loading && <Loading/>}</div> <div className="top_left_loading">{loading && <Loading/>}</div>
{week_days_nums.map((num,index)=>( {week_days_nums.map((num,index)=>(
<div className={`edt_colonne ${sameDay(getNextDay(week, index), new Date()) ? "today" : ""}`}> <div className={`edt_colonne`}>
<div className="edt_day_header"> <div className={`edt_day_header ${sameDay(getNextDay(week, index), new Date()) ? "today" : ""}`}>
<div> {week_days[index]} </div> <div> {week_days[index]} </div>
<div className="edt_date"> {dateToString(getNextDay(week,index))} </div> <div className="edt_date"> {dateToString(getNextDay(week,index))} </div>
</div> </div>

View File

@@ -4,62 +4,48 @@ import { dateToString, hoursToString } from '../edt';
import '../style/objectList.css'; import '../style/objectList.css';
import { Modal } from '../Modal'; import { Modal } from '../Modal';
import Loading from '../loading'; import Loading from '../loading';
import {delay} from "../../requetes"; import {delay, getSessionsOfUserAPI} from "../../requetes";
import CreateActivite from '../createActivite'; import CreateActivite from '../createActivite';
import { useLocalData } from '../../context/useLocalData'; import { useLocalData } from '../../context/useLocalData';
import ObjectSession from './session'; import ObjectSession from './session';
import StatAthlete from '../StatsAthlete'; import StatAthlete from '../StatsAthlete';
type Props = { type Props = {
admin?:Admin|null; user:User;
athlete?:Athlete|null;
coach?:Coach|null;
} }
function ObjectUser({admin=null,athlete=null,coach=null}:Props){ function ObjectUser({user}:Props){
const {user,setUser} = useLocalData() //const {user,setUser} = useLocalData());
const[user2,setUser2]= useState<User>(getUser());
const [open, setOpen] = useState<boolean>(false); const [open, setOpen] = useState<boolean>(false);
const [open2, setOpen2] = useState<boolean>(false); const [open2, setOpen2] = useState<boolean>(false);
const [loading,setLoading] = useState<boolean>(false); const [loading,setLoading] = useState<boolean>(false);
const [sessions,setSessions] = useState<Session[]>([]); const [sessions,setSessions] = useState<Session[]>([]);
function getUser(): User{
if(admin!=null) return admin;
if(athlete!=null) return athlete;
if(coach!=null) return coach;
else return new User();
}
function handleOpen(): void { function handleOpen(): void {
setOpen(!open); setOpen(!open);
} }
function handleDeleteSession(session:Session): void { function handleDeleteSession(session:Session): void {
if(athlete!==null){ if(user instanceof Coach || user instanceof Athlete){
athlete.sessions.splice(athlete.sessions.indexOf(session), 1); user.sessions.splice(user.sessions.indexOf(session), 1);
setSessions([...athlete.sessions]) setSessions([...user.sessions])
} }
if(coach!==null){
coach.sessions.splice(coach.sessions.indexOf(session), 1);
setSessions([...coach.sessions])
}
} }
function handleAddSession(): void { function handleAddSession(): void {
if(athlete!==null){ if(user instanceof Athlete){
setOpen2(true) setOpen2(true)
} }
} }
async function updateSession(){ async function updateSession(){
if(athlete!==null){ if(user instanceof Athlete || user instanceof Coach){
//TODO user.sessions = await getSessionsOfUserAPI(user);
await delay(2000);
//await update ... (athlete);
setLoading(false); setLoading(false);
} }
} }
@@ -74,11 +60,11 @@ function ObjectUser({admin=null,athlete=null,coach=null}:Props){
useEffect(() => { useEffect(() => {
if(!loading){ if(!loading){
if(athlete!==null){ if(user instanceof Athlete){
setSessions([...athlete.sessions]) setSessions([...user.sessions])
} }
if(coach!==null){ if(user instanceof Coach){
setSessions([...coach.sessions]) setSessions([...user.sessions])
} }
} }
},[loading]) },[loading])
@@ -86,13 +72,13 @@ function ObjectUser({admin=null,athlete=null,coach=null}:Props){
function returnSession(session: Session|null){ function returnSession(session: Session|null){
if(session!==null){ if(session!==null){
if(athlete!==null){ if(user instanceof Athlete){
athlete.sessions.push(session); user.sessions.push(session);
setSessions([...athlete.sessions]) setSessions([...user.sessions])
} }
if(coach!==null){ if(user instanceof Coach){
coach.sessions.push(session); user.sessions.push(session);
setSessions([...coach.sessions]) setSessions([...user.sessions])
} }
} }
setOpen2(false); setOpen2(false);
@@ -101,23 +87,29 @@ function ObjectUser({admin=null,athlete=null,coach=null}:Props){
return( return(
<div> <div>
<div className="object" onClick={() => handleOpen()}> <div className="object" onClick={() => handleOpen()}>
<div>{user2.nom}</div> <div>{user.nom}</div>
{/* <div>{user2.role}</div> */} {/* <div>{user2.role}</div> */}
</div> </div>
{open && {open &&
<Modal isOpen={open} onClose={() => setOpen(false)}> <Modal isOpen={open} onClose={() => setOpen(false)}>
<div className="object_modal"> <div className="object_modal">
<div>{user2.nom}</div> <div>{user.prenom}</div>
<div>{user2.email}</div> <div>{user.nom}</div>
<div className='list_object'> {(user instanceof Athlete || user instanceof Coach) &&
<div>Sessions :</div> <div className='padding'>
{/* TODO */} <div className='list_object_modal'>
<div>Sessions :</div>
{user.sessions.map((session,index)=>(
<ObjectSession session={session}></ObjectSession>
))}
</div>
</div>
}
</div> {user instanceof Athlete && (
{athlete !== null && (
<div className="stats-container"> <div className="stats-container">
<StatAthlete athlete={athlete} sessions={sessions} /> <StatAthlete athlete={user}/>
</div> </div>
)} )}
</div> </div>

View File

@@ -70,7 +70,7 @@ import ObjectLigne from "./object/lignes";
return ( return (
<div className="ressource_panel"> <div className="composant-container">
{(user instanceof Admin || user instanceof Coach) && {(user instanceof Admin || user instanceof Coach) &&
<div> <div>
@@ -98,7 +98,7 @@ import ObjectLigne from "./object/lignes";
<div className="list_object"> <div className="list_object">
{value==="athletes" && ( {value==="athletes" && (
allAthletes.map((athlete) => ( allAthletes.map((athlete) => (
<ObjectUser athlete={athlete}/> <ObjectUser user={athlete}/>
)) ))
)} )}
{value==="activites" && ( {value==="activites" && (
@@ -108,7 +108,7 @@ import ObjectLigne from "./object/lignes";
)} )}
{value==="coachs" && ( {value==="coachs" && (
allCoachs.map((coach) => ( allCoachs.map((coach) => (
<ObjectUser coach={coach}/> <ObjectUser user={coach}/>
)) ))
)} )}
{value==="sessions" && ( {value==="sessions" && (

View File

@@ -0,0 +1,5 @@
.createActivite{
background: var(--tint1);
padding: 15px;
border-radius: 15px;
}

View File

@@ -1,9 +1,8 @@
.edt{ .edt{
justify-content: center; background-color: var(--tint2);
background-color: var(--tint1);
border-radius: 30px; border-radius: 30px;
padding: 10px; padding: 10px;
border: 2px solid var(--green-primary); /* Bordure verte */ border: 2px solid var(--tint4);
box-shadow: 0 4px 6px rgba(16, 185, 129, 0.1); box-shadow: 0 4px 6px rgba(16, 185, 129, 0.1);
} }
@@ -40,10 +39,6 @@
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.edt_colonne:hover {
border-color: var(--green-primary);
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.15);
}
.edt_day_header{ .edt_day_header{
font-size: clamp(5px, 1vw, 18px); font-size: clamp(5px, 1vw, 18px);
@@ -52,12 +47,13 @@
height: fit-content; height: fit-content;
text-align: center; text-align: center;
font-size: 1em; font-size: 1em;
background: linear-gradient(135deg, var(--green-A-primary), var(--green-A-secondary)); background: linear-gradient(135deg, var(--green-A-primary), var(--green-A-dark));
font-weight: 600; font-weight: 600;
} }
.today{ .today{
border: 2px solid var(--green-primary) ; background: linear-gradient(135deg, var(--green-primary), var(--green-dark));
color: #FFFFFF;
} }
.edt_day_content{ .edt_day_content{

View File

@@ -6,6 +6,16 @@
border-radius: 20px; border-radius: 20px;
} }
.list_object_modal{
display: grid;
gap:10px;
background-color: var(--tint1);
padding: 10px;
border-radius: 20px;
max-height: 200px;
overflow-y: auto;
}
.object { .object {
font-size: clamp(1px, 8cqi, 18px); font-size: clamp(1px, 8cqi, 18px);