barre menu en haut + ajustement style
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
--green-A-primary: #10b98120;
|
--green-A-primary: #10b98120;
|
||||||
--green-A-secondary: #05966920;
|
--green-A-secondary: #05966920;
|
||||||
--green-A-dark: #04785720;
|
--green-A-dark: #04785720;
|
||||||
|
--themeButtonColor : #00AAFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme='light'] {
|
[data-theme='light'] {
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
--green-A-primary: #00ce8920;
|
--green-A-primary: #00ce8920;
|
||||||
--green-A-secondary: #00a57120;
|
--green-A-secondary: #00a57120;
|
||||||
--green-A-dark: #00825d20;
|
--green-A-dark: #00825d20;
|
||||||
|
--themeButtonColor : #FFAA00;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset et base */
|
/* Reset et base */
|
||||||
@@ -69,12 +71,22 @@ code {
|
|||||||
color: var(--green-primary);
|
color: var(--green-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.App{
|
||||||
|
display: grid;
|
||||||
|
padding: 10px;
|
||||||
|
gap:10px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Container principal */
|
/* Container principal */
|
||||||
.app-container {
|
.app-container {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(180deg, var(--tint0) 0%, var(--tint1) 100%);
|
background: linear-gradient(180deg, var(--tint0) 0%, var(--tint1) 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.composant-padding{
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.composant-container{
|
.composant-container{
|
||||||
background-color: var(--tint2);
|
background-color: var(--tint2);
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import EdtCoach from './components/edt_coach'
|
|||||||
import { Coach } from "./classes";
|
import { Coach } from "./classes";
|
||||||
import RessourcePanel from './components/ressourcePanel';
|
import RessourcePanel from './components/ressourcePanel';
|
||||||
import TestAPI from './components/test_api';
|
import TestAPI from './components/test_api';
|
||||||
|
import TopBar from './components/topBar';
|
||||||
|
|
||||||
const keycloakInitOptions = {
|
const keycloakInitOptions = {
|
||||||
onLoad: 'login-required',
|
onLoad: 'login-required',
|
||||||
@@ -22,13 +23,12 @@ function App() {
|
|||||||
<ReactKeycloakProvider authClient={keycloak} /*initOptions={keycloakInitOptions}*/>
|
<ReactKeycloakProvider authClient={keycloak} /*initOptions={keycloakInitOptions}*/>
|
||||||
<LocalDataProvider>
|
<LocalDataProvider>
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<SwitchThemeColor/>
|
<TopBar/>
|
||||||
<h1>Frisbyee</h1>
|
<h1>Frisbyee</h1>
|
||||||
<Login/>
|
<RessourcePanel/>
|
||||||
<RessourcePanel/>
|
<EDT/>
|
||||||
<EDT/>
|
<CreateSession/>
|
||||||
<CreateSession/>
|
<TestAPI/>
|
||||||
<TestAPI/>
|
|
||||||
</div>
|
</div>
|
||||||
</LocalDataProvider>
|
</LocalDataProvider>
|
||||||
</ReactKeycloakProvider>
|
</ReactKeycloakProvider>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useState,useEffect } from 'react';
|
import { useState,useEffect } from 'react';
|
||||||
import './style/SwitchThemeColor.css';
|
|
||||||
|
|
||||||
|
|
||||||
const SwitchThemeColor = () => {
|
const SwitchThemeColor = () => {
|
||||||
|
|||||||
@@ -1,49 +1,27 @@
|
|||||||
import { useKeycloak } from '@react-keycloak/web'
|
import { useKeycloak } from '@react-keycloak/web'
|
||||||
import { useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Admin, Athlete, Coach, User } from '../classes';
|
import { Admin, Athlete, Coach, User } from '../classes';
|
||||||
import { useLocalData } from '../context/useLocalData';
|
import { useLocalData } from '../context/useLocalData';
|
||||||
import { loginOrRegister, postAthlete } from '../requetes';
|
import { loginOrRegister, postAthlete } from '../requetes';
|
||||||
import { clearAuthToken, setAuthToken } from '../api';
|
import { clearAuthToken, setAuthToken } from '../api';
|
||||||
import { AthleteDTO } from '../classesDTO';
|
import { AthleteDTO } from '../classesDTO';
|
||||||
|
import { Modal } from './Modal';
|
||||||
|
import './style/topBar.css';
|
||||||
|
|
||||||
export const Login =() =>{
|
export const Login =() =>{
|
||||||
const {user,setUser} = useLocalData()
|
const {user,setUser} = useLocalData()
|
||||||
const { keycloak } = useKeycloak();
|
const { keycloak } = useKeycloak();
|
||||||
|
const [open,setOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
/*useEffect(() => {
|
|
||||||
const syncAndLoadUser = async () => {
|
|
||||||
if (keycloak.authenticated && keycloak.token && keycloak.tokenParsed) {
|
|
||||||
try {
|
|
||||||
const newAthlete: Athlete = new Athlete();
|
|
||||||
newAthlete.keycloakId = keycloak.tokenParsed.sub || "";
|
|
||||||
newAthlete.email = keycloak.tokenParsed.email || "";
|
|
||||||
newAthlete.nom = keycloak.tokenParsed.family_name || "";
|
|
||||||
newAthlete.prenom = keycloak.tokenParsed.given_name || "";
|
|
||||||
|
|
||||||
setAuthToken(keycloak.token);
|
|
||||||
|
|
||||||
const athlete: Athlete = await postAthlete(newAthlete);
|
|
||||||
setUser(athlete);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error :", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
syncAndLoadUser();
|
|
||||||
}, [keycloak.authenticated, keycloak.token, setUser]);
|
|
||||||
*/
|
|
||||||
|
|
||||||
async function loginUser(){
|
async function loginUser(){
|
||||||
if(keycloak.authenticated){
|
if(keycloak.authenticated){
|
||||||
setAuthToken(keycloak.token);
|
setAuthToken(keycloak.token);
|
||||||
//alert("Connexion en cours : " + keycloak.tokenParsed?.sub + " " + keycloak.tokenParsed?.realm_access?.roles);
|
|
||||||
|
|
||||||
const logedUser = await loginOrRegister(keycloak);
|
const logedUser = await loginOrRegister(keycloak);
|
||||||
console.log(logedUser);
|
console.log(logedUser);
|
||||||
if(logedUser!==null){
|
if(logedUser!==null){
|
||||||
setUser(logedUser);
|
setUser(logedUser);
|
||||||
// alert("Connexion avec succès ! " + keycloak.tokenParsed?.sub);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
alert("Erreur de connexion " + keycloak.tokenParsed?.sub + " " + keycloak.tokenParsed?.realm_access?.roles);
|
alert("Erreur de connexion " + keycloak.tokenParsed?.sub + " " + keycloak.tokenParsed?.realm_access?.roles);
|
||||||
@@ -63,37 +41,51 @@ export const Login =() =>{
|
|||||||
keycloak.logout()
|
keycloak.logout()
|
||||||
setUser(new User());
|
setUser(new User());
|
||||||
clearAuthToken();
|
clearAuthToken();
|
||||||
|
setOpen(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleOpen(): void {
|
||||||
|
setOpen(!open);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keycloak.authenticated){
|
||||||
return(
|
return(
|
||||||
<div>
|
<div className='loginContainer'>
|
||||||
<div>
|
<button className="loginButton" onClick={()=>handleOpen()}>{user.prenom}</button>
|
||||||
Etat : {keycloak.authenticated ? 'connecté' : 'non connecté'}
|
{open &&
|
||||||
|
<div className='login'>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
Prenom : { user.prenom}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Nom : { user.nom}
|
||||||
|
</div>
|
||||||
|
{/* <div>Keycloak ID : { keycloak.tokenParsed?.sub}</div> */}
|
||||||
|
{user instanceof Athlete && <div>Role : Athlete</div>}
|
||||||
|
{user instanceof Coach && <div>Role : Coach</div>}
|
||||||
|
{user instanceof Admin && <div>Role : Admin</div>}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick={() => handleLogout()}>
|
||||||
|
Se déconnecter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
{keycloak.authenticated &&
|
)
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return(
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<button onClick={() => handleLogin()}>
|
||||||
Keycloak ID : { keycloak.tokenParsed?.sub}
|
Se connecter
|
||||||
</div>
|
</button>
|
||||||
<div>
|
|
||||||
Prenom : { user.prenom}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Nom : { user.nom}
|
|
||||||
</div>
|
|
||||||
{user instanceof Athlete && <div>Role : Athlete</div>}
|
|
||||||
{user instanceof Coach && <div>Role : Coach</div>}
|
|
||||||
{user instanceof Admin && <div>Role : Admin</div>}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
}
|
)
|
||||||
<button onClick={() => handleLogin()}>
|
}
|
||||||
Se connecter
|
|
||||||
</button>
|
|
||||||
<button onClick={() => handleLogout()}>
|
|
||||||
Se déconnecter
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Login
|
export default Login
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ function DetailSession({session,open,setOpen}:Props){
|
|||||||
Activités :
|
Activités :
|
||||||
<div className="session_modal_activite_list">
|
<div className="session_modal_activite_list">
|
||||||
{activites.map((activite,index)=>(
|
{activites.map((activite,index)=>(
|
||||||
<div>
|
<div className="activiteList">
|
||||||
{activite.nom}
|
- {activite.nom}
|
||||||
{canEdit && (
|
{canEdit && (
|
||||||
<button className="deleteButton" onClick={() => handleDeleteActivite(activite)}>x</button>
|
<button className="deleteButton" onClick={() => handleDeleteActivite(activite)}>x</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
.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(--green-A-primary);
|
|
||||||
}
|
|
||||||
@@ -32,11 +32,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.edt_colonne {
|
.edt_colonne {
|
||||||
display: grid;
|
|
||||||
background-color: var(--tint3);
|
background-color: var(--tint3);
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
container-type: inline-size;
|
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -49,6 +48,7 @@
|
|||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
background: linear-gradient(135deg, var(--green-A-primary), var(--green-A-dark));
|
background: linear-gradient(135deg, var(--green-A-primary), var(--green-A-dark));
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
font-size: large;
|
||||||
}
|
}
|
||||||
|
|
||||||
.today{
|
.today{
|
||||||
|
|||||||
@@ -52,7 +52,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.session_modal_activite_list{
|
.session_modal_activite_list{
|
||||||
|
display: grid;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: var(--tint3);
|
background-color: var(--tint3);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.activiteList{
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
69
front_end/src/components/style/topBar.css
Normal file
69
front_end/src/components/style/topBar.css
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
.topBar{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding:15px;
|
||||||
|
background: var(--tint2);
|
||||||
|
border-radius: 30px;
|
||||||
|
height: 60px;
|
||||||
|
border: 3px solid var(--tint5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toBarLeft{
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.topBarRight{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loginContainer{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login{
|
||||||
|
position:absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 1;
|
||||||
|
display: grid;
|
||||||
|
gap:15px;
|
||||||
|
width: fit-content;
|
||||||
|
white-space: nowrap;
|
||||||
|
align-items: left;
|
||||||
|
background: var(--tint2) ;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 3px solid var(--tint5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loginButton{
|
||||||
|
width: 120px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ButtonTheme{
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
color: var(--text);
|
||||||
|
background-color: var(--tint3);
|
||||||
|
border-radius: 15px;
|
||||||
|
font-size: 16px;
|
||||||
|
border-color: var(--tint5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ButtonTheme:hover{
|
||||||
|
border-color: var(--themeButtonColor);
|
||||||
|
color: var(--themeButtonColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo{
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
25
front_end/src/components/topBar.tsx
Normal file
25
front_end/src/components/topBar.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import Login from "./login"
|
||||||
|
import SwitchThemeColor from "./SwitchThemeColor"
|
||||||
|
|
||||||
|
function TopBar(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="topBar">
|
||||||
|
<div className="toBarLeft">
|
||||||
|
<img className="logo" src="/Frisbyee_logo.png"/>
|
||||||
|
<h2>Frisbyee</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="topBarRight">
|
||||||
|
<SwitchThemeColor/>
|
||||||
|
<Login/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TopBar
|
||||||
Reference in New Issue
Block a user