correction bug admin + lecture de toute les session dans l'edt pour l'admin
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
package hackathon.FrisbYEE.jpa.dto;
|
||||
import hackathon.FrisbYEE.jpa.metier.Role;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AdminDTO {
|
||||
private String id_keycloak;
|
||||
private Integer id;
|
||||
private String id_keycloak;
|
||||
private String name;
|
||||
private String prenom;
|
||||
private Role role;
|
||||
}
|
||||
|
||||
@@ -3,17 +3,12 @@ package hackathon.FrisbYEE.rest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import hackathon.FrisbYEE.jpa.dto.AdminDTO;
|
||||
import hackathon.FrisbYEE.jpa.metier.Admin;
|
||||
import hackathon.FrisbYEE.jpa.service.AdminDAO;
|
||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||
import hackathon.FrisbYEE.jpa.service.UserDAO;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
@@ -22,12 +17,24 @@ public class AdminResource {
|
||||
|
||||
@Autowired
|
||||
private AdminDAO adminDAO;
|
||||
@Autowired
|
||||
private UserDAO userDAO;
|
||||
|
||||
|
||||
@PostMapping("/create")
|
||||
@PreAuthorize("hasRole('Admin')") // Only admin can create
|
||||
@PreAuthorize("hasRole('admin')") // Only admin can create
|
||||
public ResponseEntity<AdminDTO> create(@RequestBody AdminDTO dto) {
|
||||
|
||||
userDAO.findByKeycloakId(dto.getId_keycloak())
|
||||
.ifPresent(existing -> {
|
||||
if (!(existing instanceof Admin)) {
|
||||
userDAO.delete(existing);
|
||||
userDAO.flush();
|
||||
}
|
||||
});
|
||||
|
||||
Admin admin = mapToEntity(dto);
|
||||
|
||||
if(adminDAO.findByKeycloakId(admin.getKeycloakId()).isPresent()) {
|
||||
return ResponseEntity.status(200).body(mapToDTO(adminDAO.findByKeycloakId(admin.getKeycloakId()).get()));
|
||||
}
|
||||
@@ -55,7 +62,6 @@ public class AdminResource {
|
||||
dto.setId_keycloak(admin.getKeycloakId());
|
||||
dto.setName(admin.getName());
|
||||
dto.setPrenom(admin.getPrenom());
|
||||
dto.setRole(admin.getRole());
|
||||
|
||||
return dto;
|
||||
}
|
||||
@@ -65,7 +71,7 @@ public class AdminResource {
|
||||
admin.setKeycloakId(dto.getId_keycloak());
|
||||
admin.setName(dto.getName());
|
||||
admin.setPrenom(dto.getPrenom());
|
||||
admin.setRole(dto.getRole());
|
||||
admin.setRole(hackathon.FrisbYEE.jpa.metier.Role.admin);
|
||||
|
||||
return admin;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package hackathon.FrisbYEE.rest;
|
||||
|
||||
import hackathon.FrisbYEE.jpa.dto.CoachDTO;
|
||||
import hackathon.FrisbYEE.jpa.metier.Admin;
|
||||
import hackathon.FrisbYEE.jpa.metier.Coach;
|
||||
import hackathon.FrisbYEE.jpa.service.CoachDAO;
|
||||
import hackathon.FrisbYEE.jpa.service.UserDAO;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -17,13 +20,26 @@ import java.util.List;
|
||||
@RestController
|
||||
@RequestMapping("/coach")
|
||||
public class CoachResource {
|
||||
|
||||
@Autowired
|
||||
private CoachDAO coachDAO;
|
||||
@Autowired
|
||||
private UserDAO userDAO;
|
||||
|
||||
@PostMapping("/create")
|
||||
@PreAuthorize("hasRole('Admin')") // Only admin can create
|
||||
@PreAuthorize("hasRole('admin') or hasRole('coach')") // Only admin can create
|
||||
public ResponseEntity<CoachDTO> create(@RequestBody CoachDTO dto) {
|
||||
|
||||
userDAO.findByKeycloakId(dto.getId_keycloak())
|
||||
.ifPresent(existing -> {
|
||||
if (!(existing instanceof Coach)) {
|
||||
userDAO.delete(existing);
|
||||
userDAO.flush();
|
||||
}
|
||||
});
|
||||
|
||||
Coach coach = mapToEntity(dto);
|
||||
|
||||
if(coachDAO.existsByKeycloakId(coach.getKeycloakId())) {
|
||||
return ResponseEntity.status(200).body(mapToDTO(coachDAO.findByKeycloakId(coach.getKeycloakId()).get()));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -69,6 +70,30 @@ public class SessionResource {
|
||||
return ResponseEntity.ok(dtos);
|
||||
}
|
||||
|
||||
@GetMapping("/all-between-dates")
|
||||
@PreAuthorize("hasRole('admin') or hasRole('coach') or hasRole('athlete')")
|
||||
public ResponseEntity<List<SessionDTO>> getAllBetweenDates(
|
||||
@RequestParam LocalDate startDate,
|
||||
@RequestParam LocalDate endDate
|
||||
) {
|
||||
List<Session> sessions = sessionDAO.findAll();
|
||||
List<SessionDTO> dtos = new ArrayList<>();
|
||||
System.out.println("date : " + startDate + " " + endDate);
|
||||
for (Session session : sessions) {
|
||||
LocalDate sessionDate = session.getCreneau().toLocalDate();
|
||||
|
||||
boolean isBetween =
|
||||
(!sessionDate.isBefore(startDate) || session.getIsRecurrent()) &&
|
||||
!sessionDate.isAfter(endDate);
|
||||
|
||||
if (isBetween) {
|
||||
dtos.add(maptoDTO(session));
|
||||
}
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(dtos);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasRole('coach') or hasRole('athlete')")
|
||||
public ResponseEntity<?> getById(@PathVariable Integer id) {
|
||||
|
||||
@@ -62,11 +62,16 @@ export const activiteService = {
|
||||
getByTheme: (theme: string) => api.get(`/activite/theme/${encodeURIComponent(theme)}`),
|
||||
getDataActivite: (id: number | string) => api.get(`/activite/${id}`),
|
||||
};
|
||||
type DateBetween = {
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
}
|
||||
|
||||
export const sessionService = {
|
||||
// controller uses singular /session/* endpoints
|
||||
create: (data: any) => api.post(`/session/create`, data),
|
||||
create: (data: SessionDTO) => api.post(`/session/create`, data),
|
||||
getAll: () => api.get<SessionDTO[]>(`/session/all`),
|
||||
getAllBetweenDate: (data: any) => api.get<SessionDTO[]>(`/session/all-between-dates`,{params: data,}),
|
||||
getById: (id: number | null) => api.get(`/session/${id}`),
|
||||
delete: (id: number | null) => api.delete(`/session/delete/${id}`),
|
||||
update: (id: number | null, data: any) => api.put(`/session/update/${id}`, data),
|
||||
@@ -79,7 +84,7 @@ export const sessionService = {
|
||||
|
||||
export const coachService = {
|
||||
// controller doesn't declare a class-level path consistently; support both common patterns
|
||||
create: (data: any) => api.post<CoachDTO>(`/coach/create`, data),
|
||||
create: (data: CoachDTO) => api.post<CoachDTO>(`/coach/create`, data),
|
||||
getAll: () => api.get<CoachDTO[]>(`/coach/all`),
|
||||
getById: (id: number) => api.get(`/coach/${id}`),
|
||||
getByKeycloakId: (keycloakId: string) => api.get(`/coach/keycloak/${keycloakId}`),
|
||||
@@ -97,7 +102,8 @@ export const userService = {
|
||||
|
||||
export const adminService = {
|
||||
getByKeycloakId: (keycloak_id: string) => api.get(`/admin/keycloak/${keycloak_id}`),
|
||||
getById: (id: number | string) => api.get(`/admin/${id}`),
|
||||
getById: (id: number | string) => api.get<AdminDTO>(`/admin/${id}`),
|
||||
create: (data: AdminDTO) => api.post<AdminDTO>("/admin/create", data),
|
||||
};
|
||||
|
||||
export default api;
|
||||
@@ -55,7 +55,7 @@ export class Athlete extends User{
|
||||
|
||||
constructor(dto?:AthleteDTO){
|
||||
super();
|
||||
this.id = dto?.id ?? 0;
|
||||
this.id = dto?.id ?? null;
|
||||
this.keycloakId = dto?.id_keycloak ?? "";
|
||||
this.nom = dto?.name ?? "";
|
||||
this.prenom = dto?.prenom ?? "" ;
|
||||
@@ -90,7 +90,7 @@ export class Coach extends User{
|
||||
|
||||
constructor(dto?:CoachDTO){
|
||||
super();
|
||||
this.id = dto?.id ?? 0;
|
||||
this.id = dto?.id ?? null;
|
||||
this.keycloakId = dto?.id_keycloak ?? "";
|
||||
this.nom = dto?.name ?? "";
|
||||
this.prenom = dto?.prenom ?? "";
|
||||
|
||||
@@ -6,7 +6,7 @@ import { createSessionAPI, postSession } from "../requetes";
|
||||
import './style/createSession.css';
|
||||
|
||||
export const CreateSession = () => {
|
||||
const {user} = useLocalData();
|
||||
const {userLocal: user} = useLocalData();
|
||||
const [session,setSession] = useState<Session>(new Session());
|
||||
const [activities, setActivities] = useState<Activite[]>([]);
|
||||
const [name,setName] = useState("");
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { Athlete, Coach, Session} from "../classes"
|
||||
import { Admin, Athlete, Coach, Session} from "../classes"
|
||||
import { useLocalData } from "../context/useLocalData"
|
||||
import './style/edt.css';
|
||||
import {getSessionsOfUserAPI } from "../requetes";
|
||||
import {getAllSessionsAPI, getAllSessionsBetweenAPI, getSessionsOfUserAPI } from "../requetes";
|
||||
import EdtSession from "./edt_session";
|
||||
import {delay} from "../requetes";
|
||||
import Loading from "./loading";
|
||||
@@ -26,7 +26,8 @@ export function hoursToString(date:Date){
|
||||
|
||||
|
||||
export const EDT =() =>{
|
||||
const {user,setUser} = useLocalData()
|
||||
const {userLocal} = useLocalData()
|
||||
const {sessionsLocal,setSessionsLocal} = useLocalData()
|
||||
const [sessions, setSessions] = useState<Session[]>([])
|
||||
const [week,setWeek] = useState<Date>(getFirstDay(new Date()));
|
||||
const [loadedWeek,setLoadedWeek] = useState<Date|null>(null);
|
||||
@@ -35,12 +36,21 @@ export const EDT =() =>{
|
||||
const week_days_nums:number[] = [1,2,3,4,5,6,0];
|
||||
|
||||
function loadSessions(date:Date){
|
||||
var maxDate = getNextDay(date,6)
|
||||
var maxDate = toDateOnly(getNextDay(date,6));
|
||||
|
||||
var newWeek: Session[] = []
|
||||
if(user instanceof Athlete || user instanceof Coach){
|
||||
user.sessions.forEach(session => {
|
||||
if((session.creneau >= date && session.creneau <= maxDate && !session.isRecurrent) || (session.isRecurrent && session.creneau<maxDate)){
|
||||
if(userLocal instanceof Athlete || userLocal instanceof Coach){
|
||||
userLocal.sessions.forEach(session => {
|
||||
const creneau = toDateOnly(session.creneau);
|
||||
if((creneau >= date || session.isRecurrent) && (creneau <= maxDate)){
|
||||
newWeek.push(session);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(userLocal instanceof Admin){
|
||||
sessionsLocal.forEach(session => {
|
||||
const creneau = toDateOnly(session.creneau);
|
||||
if((creneau >= date || session.isRecurrent) && (creneau <= maxDate)){
|
||||
newWeek.push(session);
|
||||
}
|
||||
});
|
||||
@@ -50,7 +60,7 @@ export const EDT =() =>{
|
||||
}
|
||||
|
||||
function changeWeek(date:Date){
|
||||
setWeek(date);
|
||||
setWeek(toDateOnly(date));
|
||||
}
|
||||
|
||||
function isSameDay(date1:Date,date2:Date){
|
||||
@@ -65,7 +75,7 @@ export const EDT =() =>{
|
||||
updateWeek(week);
|
||||
loadSessions(week)
|
||||
setLoading(true);
|
||||
},[week,user])
|
||||
},[week,userLocal])
|
||||
|
||||
useEffect(() => {
|
||||
if(loadedWeek!==null){
|
||||
@@ -83,9 +93,22 @@ export const EDT =() =>{
|
||||
//TODO updateSession
|
||||
//await delay(2000);
|
||||
//await updateSessionsOfUser(user,null,null);
|
||||
if(user instanceof Athlete || user instanceof Coach){
|
||||
const newSessions:Session[] = await getSessionsOfUserAPI(user);
|
||||
user.sessions = newSessions;
|
||||
if(userLocal instanceof Athlete || userLocal instanceof Coach){
|
||||
const newSessions:Session[] = await getSessionsOfUserAPI(userLocal);
|
||||
userLocal.sessions = newSessions;
|
||||
}
|
||||
else if(userLocal instanceof Admin){
|
||||
const newSessions:Session[] = await getAllSessionsBetweenAPI(week,getNextDay(week,6));
|
||||
const date = toDateOnly(week);
|
||||
var maxDate = toDateOnly(getNextDay(date,6));
|
||||
sessionsLocal.forEach(sessionLocal => { //update seulement la semaine
|
||||
const creneau = toDateOnly(sessionLocal.creneau);
|
||||
if(!((creneau >= date || sessionLocal.isRecurrent) && (creneau <= maxDate))){
|
||||
newSessions.push(sessionLocal);
|
||||
}
|
||||
});
|
||||
|
||||
setSessionsLocal(newSessions);
|
||||
}
|
||||
setLoadedWeek(week);
|
||||
}
|
||||
@@ -108,7 +131,15 @@ export const EDT =() =>{
|
||||
else{
|
||||
firstDate = getNextDay(date,-numWeek+1);
|
||||
}
|
||||
return firstDate;
|
||||
return toDateOnly(firstDate);
|
||||
}
|
||||
|
||||
function toDateOnly(date: Date): Date {
|
||||
return new Date(
|
||||
date.getFullYear(),
|
||||
date.getMonth(),
|
||||
date.getDate()
|
||||
);
|
||||
}
|
||||
|
||||
function getNextDay(date:Date,nb:number):Date{
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Modal } from './Modal';
|
||||
import './style/topBar.css';
|
||||
|
||||
export const Login =() =>{
|
||||
const {user,setUser} = useLocalData()
|
||||
const {userLocal: user,setUserLocal: setUser} = useLocalData()
|
||||
const { keycloak } = useKeycloak();
|
||||
const [open,setOpen] = useState<boolean>(false);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ type Props = {
|
||||
|
||||
function DetailSession({session,open,setOpen}:Props){
|
||||
|
||||
const {user,setUser} = useLocalData()
|
||||
const {userLocal: user,setUserLocal: setUser} = useLocalData()
|
||||
|
||||
const [activites,setActivites] = useState<Activite[]>([]);
|
||||
const [open2, setOpen2] = useState<boolean>(false);
|
||||
|
||||
@@ -104,6 +104,9 @@ function ObjectUser({user}:Props){
|
||||
<div className="object_modal">
|
||||
<div>{user.prenom}</div>
|
||||
<div>{user.nom}</div>
|
||||
{user instanceof Athlete && <div>Role : Athlete</div>}
|
||||
{user instanceof Coach && <div>Role : Coach</div>}
|
||||
{user instanceof Admin && <div>Role : Admin</div>}
|
||||
{(user instanceof Athlete || user instanceof Coach) &&
|
||||
<div className='padding'>
|
||||
<div className='list_object_modal'>
|
||||
|
||||
@@ -15,7 +15,7 @@ import ObjectLigne from "./object/lignes";
|
||||
|
||||
export default function RessourcePanel() {
|
||||
const { keycloak } = useKeycloak();
|
||||
const { user } = useLocalData();
|
||||
const { userLocal: user } = useLocalData();
|
||||
//const user = getUserTest(); //TODO
|
||||
const [value,setValue] = useState<keyWord>("sessions");
|
||||
|
||||
|
||||
@@ -2,12 +2,10 @@ import { createContext } from 'react'
|
||||
import { Session, User } from '../classes';
|
||||
|
||||
interface LocalDataContextType {
|
||||
user:User;
|
||||
setUser: React.Dispatch<React.SetStateAction<User>>
|
||||
sessions: Session[];
|
||||
setSessions: React.Dispatch<React.SetStateAction<Session[]>>
|
||||
users: User[];
|
||||
setUsers: React.Dispatch<React.SetStateAction<User[]>>
|
||||
userLocal:User;
|
||||
setUserLocal: React.Dispatch<React.SetStateAction<User>>
|
||||
sessionsLocal: Session[];
|
||||
setSessionsLocal: React.Dispatch<React.SetStateAction<Session[]>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,15 +3,14 @@ import { Session, User } from '../classes'
|
||||
import { LocalDataContext } from '../context/LocalDataContext'
|
||||
|
||||
export const LocalDataProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [user, setUser] = useState<User>(new User())
|
||||
const [sessions, setSessions] = useState<Session[]>([])
|
||||
const [users, setUsers] = useState<User[]>([])
|
||||
const [userLocal, setUserLocal] = useState<User>(new User())
|
||||
const [sessionsLocal, setSessionsLocal] = useState<Session[]>([])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<LocalDataContext.Provider
|
||||
value={{ user, setUser, sessions, setSessions, users, setUsers }}>
|
||||
value={{ userLocal, setUserLocal, sessionsLocal,setSessionsLocal}}>
|
||||
{children}
|
||||
</LocalDataContext.Provider>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import api, { activiteService, athleteService, coachService, sessionService } from "./api";
|
||||
import api, { activiteService, adminService, athleteService, coachService, sessionService } from "./api";
|
||||
import { Activite, Admin, Athlete, Coach, Session, User } from "./classes";
|
||||
import Keycloak from 'keycloak-js'
|
||||
import { AdminDTO, AthleteDTO, CoachDTO, SessionDTO } from "./classesDTO";
|
||||
@@ -27,7 +27,9 @@ export async function loginOrRegister(keycloak:Keycloak): Promise<User|null>{
|
||||
newAdmin.email = keycloak.tokenParsed.email || "";
|
||||
newAdmin.nom = keycloak.tokenParsed.family_name || "";
|
||||
newAdmin.prenom = keycloak.tokenParsed.given_name || "";
|
||||
const response = await athleteService.create(newAdmin.toDTO());
|
||||
console.log(newAdmin.keycloakId);
|
||||
console.log(newAdmin.toDTO().id_keycloak);
|
||||
const response = await adminService.create(newAdmin.toDTO());
|
||||
const admin = new Admin(response.data);
|
||||
return admin;
|
||||
}
|
||||
@@ -217,7 +219,7 @@ export async function postAthlete(athlete: Athlete):Promise<Athlete>{
|
||||
|
||||
export async function postSession(session: Session){
|
||||
try {
|
||||
const data = {
|
||||
/* const data = {
|
||||
name: session.name,
|
||||
creneau: session.creneau, // string ISO OK
|
||||
duree: session.duree,
|
||||
@@ -225,9 +227,9 @@ export async function postSession(session: Session){
|
||||
|
||||
coachId: session.coach?.id,
|
||||
groupe: session.groupe ? session.groupe : undefined,
|
||||
}
|
||||
}*/
|
||||
|
||||
const response = await sessionService.create(data);
|
||||
const response = await sessionService.create(session.toDTO());
|
||||
session.id = response.data.id; //TODO ?
|
||||
|
||||
session.activites.forEach(activite => {
|
||||
@@ -331,6 +333,44 @@ export async function getAllSessionsAPI():Promise<Session[]>{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function formatDateLocal(date: Date): string {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
|
||||
export async function getAllSessionsBetweenAPI(d1:Date,d2:Date):Promise<Session[]>{
|
||||
try {
|
||||
const data = {
|
||||
startDate: formatDateLocal(d1),
|
||||
endDate: formatDateLocal(d2)
|
||||
}
|
||||
console.log(d1 + " " + d2);
|
||||
console.log(data);
|
||||
const response = await sessionService.getAllBetweenDate(data);
|
||||
const sessions = await Promise.all(
|
||||
response.data.map(async sessionDTO => {
|
||||
const session = new Session(sessionDTO);
|
||||
const coach = await getCoachByIdAPI(sessionDTO.coachId);
|
||||
|
||||
if (coach != null) {
|
||||
session.coach = coach;
|
||||
}
|
||||
return session;
|
||||
})
|
||||
);
|
||||
|
||||
return sessions;
|
||||
} catch (error) {
|
||||
console.error("Error fetching sessions:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//COACH
|
||||
export async function getAllCoach(): Promise<Coach[]> {
|
||||
try {
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
background-color: rgba(255, 255, 255, 0.98);
|
||||
overflow: hidden;
|
||||
transition: transform 0.3s ease;
|
||||
width: fit-content;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.card-pf:hover {
|
||||
@@ -38,6 +40,7 @@
|
||||
0 8px 20px rgba(16, 185, 129, 0.15);
|
||||
}
|
||||
|
||||
|
||||
/* Header de la card */
|
||||
#kc-form-login .card-pf h1,
|
||||
.login-pf-page h1 {
|
||||
|
||||
Reference in New Issue
Block a user