This commit is contained in:
Amaël Kesteman
2026-01-07 12:02:27 +01:00
23 changed files with 327 additions and 279 deletions

View File

@@ -72,7 +72,6 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -722,7 +721,6 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz",
"integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1606,7 +1604,6 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz",
"integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.27.1",
"@babel/helper-module-imports": "^7.27.1",
@@ -3378,7 +3375,6 @@
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
@@ -3758,7 +3754,6 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -3768,7 +3763,6 @@
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"license": "MIT",
"peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -3883,7 +3877,6 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
"integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.62.0",
@@ -3937,7 +3930,6 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
"integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.62.0",
"@typescript-eslint/types": "5.62.0",
@@ -4307,7 +4299,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -4406,7 +4397,6 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -5327,7 +5317,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -7167,7 +7156,6 @@
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -9923,7 +9911,6 @@
"resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz",
"integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@jest/core": "^27.5.1",
"import-local": "^3.0.2",
@@ -10821,7 +10808,6 @@
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"license": "MIT",
"peer": true,
"bin": {
"jiti": "bin/jiti.js"
}
@@ -11025,7 +11011,6 @@
"resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.2.tgz",
"integrity": "sha512-ug7pNZ1xNkd7PPkerOJCEU2VnUhS7CYStDOCFJgqCNQ64h53ppxaKrh4iXH0xM8hFu5b1W6e6lsyYWqBMvaQFg==",
"license": "Apache-2.0",
"peer": true,
"workspaces": [
"test"
]
@@ -12185,7 +12170,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -13320,7 +13304,6 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"license": "MIT",
"peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -13686,7 +13669,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -13818,7 +13800,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -13849,7 +13830,6 @@
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -14296,7 +14276,6 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
"license": "MIT",
"peer": true,
"bin": {
"rollup": "dist/bin/rollup"
},
@@ -14539,7 +14518,6 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -15786,6 +15764,23 @@
}
}
},
"node_modules/tailwindcss/node_modules/yaml": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
"license": "ISC",
"optional": true,
"peer": true,
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/tapable": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
@@ -16003,7 +15998,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -16172,7 +16166,6 @@
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"license": "(MIT OR CC0-1.0)",
"peer": true,
"engines": {
"node": ">=10"
},
@@ -16281,7 +16274,6 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -16596,7 +16588,6 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz",
"integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@@ -16668,7 +16659,6 @@
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz",
"integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/bonjour": "^3.5.9",
"@types/connect-history-api-fallback": "^1.3.5",
@@ -17082,7 +17072,6 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",

View File

@@ -3,4 +3,4 @@
"resource": "Frisbyee_client",
"auth-server-url": "http://localhost:8080",
"public-client": true
}
}

View File

@@ -3,4 +3,5 @@
background-color: var(--tint4);
color: var(--text);
min-height: 100vh;
padding: 16px;
}

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import './App.css';
import { ReactKeycloakProvider } from '@react-keycloak/web'
import keycloak from './keycloak'
@@ -15,7 +15,10 @@ const keycloakInitOptions = {
checkLoginIframe: false
}
function App() {
return (
<ReactKeycloakProvider authClient={keycloak} /*initOptions={keycloakInitOptions}*/>
<LocalDataProvider>

View File

@@ -3,13 +3,76 @@ import keycloak from "./keycloak";
const api = axios.create({
baseURL: "http://localhost:8081/api",
headers: {
"Content-Type": "application/json",
},
});
api.interceptors.request.use((config) => {
if (keycloak?.token) {
// eslint-disable-next-line no-param-reassign
config.headers.Authorization = `Bearer ${keycloak.token}`;
}
return config;
});
export const athleteService = {
create: (data: any) => api.post("/athletes/create", data),
getAll: () => api.get("/athletes/all"),
getById: (id: number | string) => api.get(`/athletes/${id}`),
update: (id: number | string, data: any) => api.put(`/athletes/${id}`, data),
delete: (id: number | string) => api.delete(`/athletes/${id}`),
// session-related endpoints exposed by AthleteResource
getSessionsForAthlete: (athleteId: number | string) => api.get(`/athletes/athlete/${athleteId}/session`),
getAllSessions: () => api.get(`/athletes/session`),
getActivitiesForSession: (sessionId: number | string) => api.get(`/athletes/session/${sessionId}/activities`),
getSessionsAfterDate: (athleteId: number | string, date: string) => api.get(`/athletes/${athleteId}/session/after/${encodeURIComponent(date)}`),
getSessionsBetweenDates: (athleteId: number | string, startDate: string, endDate: string) => api.get(`/athletes/${athleteId}/session/between/${encodeURIComponent(startDate)}/${encodeURIComponent(endDate)}`),
};
export const activiteService = {
create: (data: any) => api.post("/activite/create", data),
delete: (id: number | string) => api.delete(`/activite/delete/${id}`),
update: (id: number | string, data: any) => api.post(`/activite/update/${id}`, data),
getById: (id: number | string) => api.get(`/activite/${id}`),
getAll: () => api.get(`/activite/all`),
getByTheme: (theme: string) => api.get(`/activite/theme/${encodeURIComponent(theme)}`),
};
export const sessionService = {
// controller uses singular /session/* endpoints
create: (data: any) => api.post(`/session/create`, data),
getAll: () => api.get(`/session/all`),
getById: (id: number | string) => api.get(`/session/${id}`),
delete: (id: number | string) => api.delete(`/session/delete/${id}`),
update: (id: number | string, data: any) => api.put(`/session/update/${id}`, data),
// plural variants used around the frontend (keep for compatibility)
createPlural: (data: any) => api.post(`/sessions`, data),
getAllPlural: () => api.get(`/sessions`),
getActivities: (sessionId: number | string) => api.get(`/sessions/${sessionId}/activities`),
addActivity: (sessionId: number | string, activity: any) => api.post(`/sessions/${sessionId}/activities`, activity),
subscribe: (sessionId: number | string, userId: number | string) => api.post(`/sessions/${sessionId}/subscribe`, { userId }),
unsubscribe: (sessionId: number | string, userId: number | string) => api.post(`/sessions/${sessionId}/unsubscribe`, { userId }),
};
export const coachService = {
// controller doesn't declare a class-level path consistently; support both common patterns
create: (data: any) => api.post(`/coach/create`, data),
getAll: () => api.get(`/coach/all`),
getById: (id: number | string) => api.get(`/coach/${id}`),
update: (id: number | string, data: any) => api.put(`/coach/update/${id}`, data),
delete: (id: number | string) => api.delete(`/coach/delete/${id}`),
// plural convenience
createPlural: (data: any) => api.post(`/coaches`, data),
getAllPlural: () => api.get(`/coaches`),
};
export const userService = {
getById: (id: number | string) => api.get(`/users/${id}`),
getAll: () => api.get(`/users`),
};
export default api;

View File

@@ -24,7 +24,7 @@ export class Session{
id!: number;
name!: String;
activites: Activite[] = [];
isRecurent! : Boolean;
isRecurrent! : Boolean;
creneau!: Date;
coach!: Coach;
athletes!: Athlete[]

View File

@@ -37,7 +37,7 @@ export const CreateSession = () => {
newSession.groupe = groupe;
newSession.creneau = new Date(creneau);
newSession.duree= duree;
newSession.isRecurent= isRecurent;
newSession.isRecurrent= isRecurent;
newSession.coach= user as Coach;
newSession.athletes= [];
newSession.activites= activities;

View File

@@ -4,7 +4,8 @@ import { useLocalData } from "../context/useLocalData"
import './style/edt.css';
import {updateSessionsOfUserAPI } from "../requetes";
import EdtSession from "./edt_session";
import {delay} from "../requetes";
import Loading from "./loading";
export function dateToString(date:Date){
const dd_prefix = date.getDate()<10 ? "0" : "";
@@ -28,11 +29,14 @@ export const EDT =() =>{
const {user,setUser} = useLocalData()
const [sessions, setSessions] = useState<Session[]>([])
const [week,setWeek] = useState<Date>(getFirstDay(new Date()));
const [loadedWeek,setLoadedWeek] = useState<Date|null>(null);
const [loading,setLoading] = useState<boolean>(false);
const week_days:String[] = ["Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"];
const week_days_nums:number[] = [1,2,3,4,5,6,0];
function loadSessions(date:Date){
var maxDate = getNextDay(date,6)
@@ -47,18 +51,39 @@ export const EDT =() =>{
function changeWeek(date:Date){
setWeek(date);
loadSessions(date)
}
function isSameDay(date1:Date,date2:Date){
return (
date1.getDay()===date2.getDay() &&
date1.getMonth()===date2.getMonth() &&
date1.getFullYear()===date2.getFullYear());
}
useEffect(() => {
updateWeek();
},[week])
setLoadedWeek(null);
updateWeek(week);
loadSessions(week)
setLoading(true);
},[week,user])
useEffect(() => {
if(loadedWeek!==null){
if(isSameDay(week,loadedWeek)){
loadSessions(week)
setLoading(false);
}
else{
setLoadedWeek(null);
}
}
},[loadedWeek])
async function updateWeek(){
async function updateWeek(week:Date){
//TODO updateSession
await delay(2000);
//await updateSessionsOfUser(user,null,null);
loadSessions(week);
setUser(getUserTest())
setLoadedWeek(week);
}
@@ -90,20 +115,20 @@ export const EDT =() =>{
return(
<div className="edt">
<div className="edt">
<div className="edt_header">
<button className="edt_button_week_select" onClick={() =>handlePrev()}>Prev</button>
<button className="edt_button_week_select" onClick={() => handleNext()}>Next</button>
</div>
<div className="edt_colonnes">
<div className="edt_loading">{loading && <Loading/>}</div>
{week_days_nums.map((num,index)=>(
<div className="edt_colonne">
<div className="edt_day_header">
<div> {week_days[index]} </div>
<div className="edt_date"> {dateToString(getNextDay(week,index))} </div>
</div>
<div className="edt_day_contedt">
<div className="edt_day_content">
{sessions.map((session,index2)=>(
session.creneau.getDay()===num &&
<EdtSession session={session}/>

View File

@@ -4,6 +4,7 @@ import { dateToString, hoursToString } from './edt';
import './style/edt.css';
import { Modal } from './Modal';
import Loading from './loading';
import {delay} from "../requetes";
type Props = {
@@ -21,6 +22,7 @@ function EdtSession({session}:Props){
async function updateActivites(){
//TODO
await delay(2000);
//await updateActivitiesOfSessionAPI(session);
setLoading(false);
}
@@ -37,19 +39,24 @@ function EdtSession({session}:Props){
return(
<div>
<div className="edt_session" onClick={() => handleOpen()}>
<div className="edt_date">{hoursToString(sDate)}</div>
<div className="edt_session_header">
<div className="edt_date">{hoursToString(sDate)}</div>
{!session.isRecurrent && <div className="edt_date"> recurrent</div>}
</div>
<div>{session.name}</div>
</div>
{open &&
<Modal isOpen={open} onClose={() => setOpen(false)}>
<div>{session.name}</div>
<div>{hoursToString(sDate)}</div>
<div>{dateToString(sDate)}</div>
{session.activites.map((activite,index)=>(
<div>activite</div>
))}
{loading && <Loading/>}
<div className="edt_session_modal">
<div>{session.name}</div>
<div>{hoursToString(sDate)}</div>
<div>{dateToString(sDate)}</div>
{session.activites.map((activite,index)=>(
<div>activite</div>
))}
{loading && <div className='edt_loading'><Loading/></div>}
</div>
</Modal>
}
</div>

View File

@@ -1,19 +1,40 @@
import { useKeycloak } from '@react-keycloak/web'
import { useEffect } from 'react';
import { getUserTest, User } from '../classes';
import { useLocalData } from '../context/useLocalData';
export const Login =() =>{
const {user,setUser} = useLocalData()
useEffect(() => { //TODO à supprimer
setUser(getUserTest())
},[]);
function handleLogin(): void {
keycloak.login()
//TODO setUser
}
function handleLogout(): void {
keycloak.logout()
setUser(new User());
}
const { keycloak } = useKeycloak()
return(
<div>
<div>
Authenticated : {keycloak.authenticated ? '' : ''}
Authenticated : {keycloak.authenticated ? 'oui' : 'non'}
</div>
<button onClick={() => keycloak.login()}>
<button onClick={() => handleLogin()}>
Se connecter
</button>
<button onClick={() => keycloak.logout()}>
<button onClick={() => handleLogout()}>
Se déconnecter
</button>
</div>

View File

@@ -1,56 +1,74 @@
.edt{
justify-contedt: cedter;
justify-content: center;
background-color: var(--tint1);
border-radius: 30px;
padding: 10px;
}
.edt_header{
justify-contedt: cedter;
justify-content: center;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, 0.5fr);
/* background-color: #0000FF; */
padding-bottom: 10px;
gap: 30%;
}
.edt_colonnes {
position: relative;
display: grid;
align-items: flex-start;
grid-template-columns: repeat(7, 1fr);
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: 16px;
color: var(--text);
/* background-color: #00FF00; */
width: 100%;
}
.edt_loading{
position: absolute;
inset: 0;
display: grid;
/* place-items: center; */
pointer-events: none;
}
.edt_colonne {
display: grid;
background-color: var(--tint3);
border-radius: 20px;
container-type: inline-size;
}
.edt_day_header{
font-size: clamp(5px, 1vw, 18px);
padding: 8px;
/* background-color: var(--tint2); */
border-radius: 20px;
height: 30px;
text-align: cedter;
text-align: center;
font-size: 1em;
}
.edt_day_contedt{
display: grid;
.edt_day_content{
display: flex;
flex-direction: column;
gap: 8px;
padding: 8px;
border-radius: 20px;
min-width: 0;
/* background-color: #FF0000; */
}
.edt_session {
font-size: clamp(1px, 8cqi, 18px);
gap: 8px;
background-color: var(--tint4);
border-radius: 12px;
padding: 8px;
padding: 5%;
min-width: 0;
}
.edt_session:hover {
@@ -61,6 +79,11 @@
background-color: var(--tint5);
}
.edt_session_header{
display: flex;
gap: 5px;
}
.edt_date{
font-size: 0.75em;
}
@@ -72,3 +95,11 @@
border-radius: 20px;
}
.edt_session_modal{
background-color: var(--tint2);
padding: 20px;
border-radius: 20px;
position: relative;
}

View File

@@ -49,16 +49,14 @@ code {
}
.modal{
background-color: var(--tint2);
padding: 10px;
border-radius: 20px;
min-width: 200px;
min-height: 100px;
}
.loading{
width: 24px;
height: 24px;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}

View File

@@ -2,14 +2,21 @@ import api from "./api";
import { Activite, Athlete, Coach, Session, User } from "./classes";
import { useKeycloak } from '@react-keycloak/web'
const { keycloak } = useKeycloak()
/*const { keycloak } = useKeycloak()
const useAuthHeader = () => {
return keycloak?.token
? { Authorization: `Bearer ${keycloak.token}` }
: {}
}*/
//debug:
export function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
//UPDATE /////////////////////////////////////////////////////////
//COACH / ATHLETE