diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 1126539..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml deleted file mode 100644 index eeec968..0000000 --- a/.idea/kotlinc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index cb90649..639900d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,10 +1,6 @@ - - - - - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 6ad2b6b..2db4f39 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,6 +2,7 @@ + diff --git a/FencerJudgeBack/README.md b/FencerJudgeBack/README.md deleted file mode 100644 index e334d69..0000000 --- a/FencerJudgeBack/README.md +++ /dev/null @@ -1,137 +0,0 @@ -# Entités -## MATCHES (MatchBean) -- id -> Long -- country -> String -- city -> String -- weapon -> String -- player1ID -> Long -- player2ID -> Long -- refereeID (arbitre) -> Long -- score1 (score du joueur 1) -> Integer -- score2 (score du joueur 2) -> Integer -- date -> Date -- state (état du match : en cours, terminé, pas commencé) -> Integer (ENUM) - -## ETATS D'UN MATCH (MatchesStates) -- ONGOING -> Integer (1) -- OVER -> Integer (2) -- NOT STARTED -> Integer (3) - -## ARBITRES (RefereeBean) -- id -> Long -- name (nom de famille) -> String -- firstName (prénom) -> String -- qualification -> String - -## JOUEURS (PlayerBean) -- id -> Long -- name (nom de famille) -> String -- firstName (prénom) -> String -- club -> String - -# Actions REST sur les entités -## matches (MatchRestController, "/matches") -- Lister tous les matches -> **GET "/matches/"** -> List -- Lister tous les matches à partir d'une certaine date -> **GET "/matches/date=&date"** -> List -- Lister les matches en cours (état : en cours) -> **GET "/matches/active"** -> List -- Lister les matches terminés (état : terminé) -> **GET "/matches/over"** -> List -- Lister les matches non commencés (état : non commencé) -> **GET "/matches/not-started"** -> List -- Afficher un match par id -> **GET "/matches/id=&id"** -> MatchBean -- Mettre à jour les score d'un match récupéré par id -> **POST "/matches/update-match"** -{ - id=$id, - score1=$score1, - score2=$score2 -} --> MatchBean -- Ajouter un match -> **POST "/matches/add-match"** -{ - date=$date, - country=$country - city=$city, - weapon=$weapon, - refereeID=$refereeID, - player1ID=$player1ID, - player2ID=$player2ID, - -} --> MatchBean -- Supprimer un match (supprimer élément de MatchRepository en récupérant l'id) -> **POST "/matches/delete-match"** -{ - id=$id -} - -## ARBITRES (RefereeRestController, "/referees") : -- Lister tous les arbitres -> **GET "/referees/"** -> List -- Afficher un arbitre par id -> **GET "/referees/id=$id"** -> RefereeBean -- Afficher un arbitre par nom ->**GET "/referees/name=$name"** -> RefereeBean -- Ajouter un arbitre ->**POST "/referees/add-referee"** -{ - name=$name, - firstName=$firstName, - qualification=$qualification -} --> RefereeBean -- Supprimer un arbitre ->**POST "/referees/delete-referee/"** -{ - id=$id -} - -## JOUEURS (PlayerRestController, "/players") : -- Lister tous les joueurs ->**GET "/players/"** -> List -- Afficher un joueur par id ->**GET "/players/id=$id"** -> PlayerBean -- Afficher un joueur par nom ->**GET "/players/name=$name"** -> PlayerBean -- Ajouter un joueur ->**POST "/players/add-player"** -{ - name=$name, - firstName=$firstName, - club=$club -} --> PlayerBean -- Supprimer un joueur ->**POST "/players/delete-player"** -{ - id=$id -} - -# Websocket (http://localhost:8080/ws) -- Vider le channel -- Insérer une donnée dans le channel -- Modifier une donnée dans le channel -- Supprimer une donnée du channel - -## MATCHES -## matches (MatchRestController, "/matches") -- Lister tous les matches -> dans le channel Websocket -- Lister tous les matches à partir d'une certaine date -> dans le channel Websocket -- Lister les matches en cours (état : en cours) -> **GET "/matches/active"** -> List -- Lister les matches terminés (état : terminé) -> **GET "/matches/over"** -> List -- Lister les matches non commencés (état : non commencé) -> **GET "/matches/not-started"** -> List -- Afficher un match par id -> **GET "/matches/id=&id"** -> MatchBean -- Mettre à jour les score d'un match récupéré par id -> **POST "/matches/update-match"** -{ - id=$id, - score1=$score1, - score2=$score2 -} --> MatchBean -- Ajouter un match -> **POST "/matches/add-match"** -{ - date=$date, - country=$country - city=$city, - weapon=$weapon, - refereeID=$refereeID, - player1ID=$player1ID, - player2ID=$player2ID, - -} --> MatchBean -- Supprimer un match (supprimer élément de MatchRepository en récupérant l'id) -> **POST "/matches/delete-match"** -{ - id=$id -} - -## REFEREES - - -## PLAYERS \ No newline at end of file diff --git a/FencerJudgeBack/TODO.txt b/FencerJudgeBack/TODO.txt deleted file mode 100644 index b3e8f97..0000000 --- a/FencerJudgeBack/TODO.txt +++ /dev/null @@ -1,6 +0,0 @@ -corriger les services - V -tester les restcontrollers via des requêtes http - V -créer la bdd avec toutes les tables (repositories) - V -tester le websocket - -prévoir l'utilisation en admin uniquement (spring security) -faire le jackarta de l'api \ No newline at end of file diff --git a/FencerJudgeBack/build.gradle.kts b/FencerJudgeBack/build.gradle.kts index e72e48d..729b120 100644 --- a/FencerJudgeBack/build.gradle.kts +++ b/FencerJudgeBack/build.gradle.kts @@ -22,21 +22,10 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("org.springframework.boot:spring-boot-starter-data-jpa") developmentOnly("org.springframework.boot:spring-boot-devtools") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") testRuntimeOnly("org.junit.platform:junit-platform-launcher") - implementation("org.springframework.boot:spring-boot-starter-validation") - - // WEBSOCKET - implementation("org.springframework.boot:spring-boot-starter-websocket") - - // SECURITY - implementation("org.springframework.boot:spring-boot-starter-security") - - // H2 Database - runtimeOnly("com.h2database:h2") } kotlin { diff --git a/FencerJudgeBack/conception.txt b/FencerJudgeBack/conception.txt deleted file mode 100644 index 02a822b..0000000 --- a/FencerJudgeBack/conception.txt +++ /dev/null @@ -1,269 +0,0 @@ -## Websocket -// Ouvrir channel websocket sur port 8500 --> DONE -function startWebsocket(var integer port) -> Websocket: - var Websocket websocket = start Websocket at port [port] - return websocket - -## Entités -MATCHS -> MatchBean, MatchRepository -MatchBean: - - id:Long - - player1:PlayerBean - - player2:PlayerBean - - referee:RefereeBean - - score1:Int (score du player1) - - score2:Int (score du player2) - - date:String (date du match) - - state:String (état du match : terminé, en cours, pas commencé) - -REFEREES (arbitres) -> RefereeBean, RefereeRepository -RefereeBean: - - id:Long - - name:Long (nom) - - firstName:String (prénom) - -PLAYERS -> PlayerBean, PlayerRepository -PlayerBean: - - id:Long - - name:String (nom) - - firstName:String (prénom) - -## Services -MatchService --> DONE: - // Obtenir tous les matchs (public) --> DONE - function getAll() -> array : - return MatchRepository.getAll() - - // Obtenir un match par id (public) --> DONE - function getById(var long id) -> MatchBean : - return MatchRepository.findById(id) - - // Obtenir un ou plusieurs match(s) par joueurs (id) (public) --> DONE - function getByPlayers(var long player1ID, var long player2ID) -> array { - return MatchRepository.getAll().filterBy(player1ID or player2ID) - } - - // Ajouter un match (admin) --> DONE - function createMatch(var MatchBean newMatch) -> MatchBean : - MatchRepository.add(newMatch) - return newMatch - - // Modifier un match (admin) --> DONE - function updateMatch(var long id, var Date date, var long refereeID, var long player1ID, var long player2ID, var integer scorePlayer1, var integer scorePlayer2, var Date date, var string matchState) -> integr (success or not): - // Vérifier si le match existe à l'id renseigné - if MatchRepository.getById(id) doesn't exist { - return FAILED - } - - // Créer nouveau MatchBean à l'id renseigné - var MatchBean newMatch = new MatchBean(id, player1ID, player2ID, refereeID, score1, score2, date, state) - - // Supprimer le MatchBean à l'id en paramètre - MatchRepository.deleteById(id) - - // Insérer le nouveau MatchBean à l'id en paramètre - MatchRepository.add(newMatch) - - return SUCCESS - - - // Supprimer un match (admin) --> DONE - function deleteMatch(var long id) -> integer (success or failure) : - try: - MatchRepository.deleteById(id) - catch error: - return FAILED - - return SUCCESS - -RefereeService --> DONE: - // Obtenir tous les arbitres (public) --> DONE - function getAll() -> array : - return RefereeRepository.getAll() - - // Obtenir un arbitre par id (public) --> DONE - function getById(var long id) -> RefereeBean : - return RefereeRepository.findById(id) - - // Obtenir un ou plusieurs arbitre(s) par nom (public) --> DONE - function getByName(var string name) -> array : - return RefereeRepository.getAll().filterBy(name) - - // Obtenir un ou plusieurs arbitre(s) par prénom (public) - function getByFirstName(var string firstName) -> array : - return RefereeRepository.getAll().filterBy(firstName) - - // Ajouter un arbitre (admin) --> DONE - function createReferee(var RefereeBean newReferee) -> RefereeBean: - RefereeRepository.add(newReferee) - return newReferee - - // Modifier un arbitre (admin) --> DONE - function updateReferee(var long id, var string name, var string firstName) -> integer (success or not): - - // Vérifier si l'arbitre existe à l'id renseigné - if RefereeRepository.getById(id) doesn't exist { - return FAILED - } - - // Créer nouveau RefereeBean à l'id renseigné - var RefereeBean newReferee = new RefereeBean(id, name, firstName) - - // Supprimer le RefereeBean à l'id en paramètre - RefereeRepository.deleteById(id) - - // Insérer le nouveau RefereeBean à l'id en paramètre - RefereeRepository.add(newReferee) - - return SUCCESS - - - // Supprimer un arbitre (admin) --> DONE - function delete(var long id) -> integer (success or failure) : - try: - RefereeRepository.deleteById(id) - catch error: - return FAILED - - return SUCCESS - -PlayerService --> DONE: - // Obtenir tous les joueurs (public) --> DONE - function getAll() -> array : - return PlayerRepository.getAll() - - // Obtenir un joueur par id (public) --> DONE - function getById(var long id) -> PlayerBean : - return PlayerRepository.findById(id) - - // Obtenir un ou plusieurs joueur(s) par nom (public) --> DONE - function getByName(var string name) -> array : - return PlayerRepository.getAll().filterBy(name) - - // Obtenir un ou plusieurs joueur(s) par prénom (public) --> DONE - function getByFirstName(var string firstName) -> array : - return PlayerRepository.getAll().filterBy(firstName) - - // Ajouter un joueur (admin) --> DONE - function add(var PlayerBean newPlayer) -> PlayerBean: - PlayerRepository.add(newPlayer) - return newPlayer - - // Modifier un joueur (admin) --> DONE - function update(var long id, var string name, var string firstName) -> PlayerBean : - // Créer nouveau PlayerBean - var PlayerBean newPlayer = new PlayerBean(id, name, firstName) - - // Supprimer le PlayerBean à l'id en paramètre - deleteById(id) - - // Insérer le nouveau PlayerBean à l'id en paramètre - PlayerRepository.add(newPlayer) - - return newPlayer - - // Supprimer un joueur (admin) --> DONE - function delete(var long id) -> integer (success or failure) : - try: - PlayerRepository.deleteById(id) - catch error: - return FAILED - - return SUCCESS - -## RestControllers -MatchRestController --> TODO: - // Lister tous les matchs --> DONE - function getAll() -> array : - return MatchService.getAll() - - // Lister tous les matchs à partir d'une certaine date - function getAllFromDate(var Date dateToFilter) -> array : - return MatchService.getAll().filter(date == dateToFilter) - - // Lister les matchs en cours (état : en cours) - function getAllActive() -> array : - return MatchService.getAll().filter(state == "ONGOING") - - // Lister les matchs terminés (état : terminé) - function getAllOver() -> array : - return MatchService.getAll().filter(state == "FINISHED") - - // Lister les matchs non commencés (état : non commencé) - function getAllNotStarted() -> array : - // MatchService : - return MatchService.getAll().filter(state == "NOT STARTED") - - // Afficher un match par id - function get(var long id) -> MatchBean : - return MatchService.get(id) - - // Mettre à jour le score1 d'un match récupéré par id --> TODO - function updateScore1Of(var long id, var integer newScore) -> integer (success or failure) : - return MatchService.update( - - // Mettre à jour le score2 d'un match récupéré par id --> TODO - function updateScore2Of(var long id, var integer newScore) -> integer (success or failure) : - return MatchService.update( - - // Ajouter un match (créer nouveau MatchBean dans MatchRepository) - function add(var MatchBean newMatch) -> integer (success or failure): - return MatchService.add(newMatch) - - // Supprimer un match (supprimer élément de MatchRepository en récupérant l'id) - function deleteById(var long id) -> integer (success or failure) : - return MatchService.deleteById(id) - -RefereeRestController --> DONE: - // Lister tous les arbitres - function getAll() -> array : - return RefereeService.getAll() - - // Afficher un arbitre par id - function get(var long id) -> RefereeBean : - return RefereeService.get(id) - - // Afficher un arbitre par nom - function get(var string name) -> RefereeBean: - return RefereeService.get(name) - - // Ajouter un arbitre (créer nouveau RefereeBean dans RefereeRepository) - function add(var RefereeBean newReferee) -> integer (success or failure) : - return RefereeService.add(newReferee) - - // Supprimer un arbitre (supprimer élément de RefereeRepository en récupérant l'id) - function deleteById(var long id) -> integer (success or failure) : - return RefereeService.deleteById(id) - -PlayerRestController --> DONE: - // Lister tous les joueurs - function getAll() -> array : - return PlayerService.getAll() - - // Afficher un joueur par id - function get(var long id) -> PlayerBean : - return PlayerService.get(id) - - // Afficher un joueur par nom - function get(var string name) -> PlayerBean : - return PlayerService.get(name) - - // Ajouter un joueur (créer nouveau PlayerBean dans PlayerRepository) - function add(var PlayerBean newPlayer) -> integer (success or failure) : - return PlayerService.add(newPlayer) - - // Supprimer un joueur (supprimer élément de PlayerRepository en récupérant l'id) - function deleteById(var long id) -> integer (success or failure) : - return PlayerService.deleteById(id) - -## Pages -Page des matchs (publique) : - à définir (partie front sur Angular ?) - -Page de connexion à l'administration (publique) : - formulaire : - - nom d'utilisateur - - mot de passe - -Page d'administration (privée) : - à définir (partie front sur Angular ?) \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/config/ConfigSecurity.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/config/ConfigSecurity.kt deleted file mode 100644 index 373883d..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/config/ConfigSecurity.kt +++ /dev/null @@ -1,56 +0,0 @@ -package fr.teamflash.fencerjudgeback.config - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder -import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity -import org.springframework.security.core.userdetails.User -import org.springframework.security.core.userdetails.UserDetailsService -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder -import org.springframework.security.provisioning.InMemoryUserDetailsManager -import org.springframework.security.web.SecurityFilterChain - -@Configuration -@EnableWebSecurity -class SecurityConfig { - - @Autowired - open fun configureGlobal(auth: AuthenticationManagerBuilder) { - val encoder = BCryptPasswordEncoder() - - //Créer des utilisateurs fixes - auth.inMemoryAuthentication() - .passwordEncoder(encoder) - .withUser("aaa") - .password(encoder.encode("bbb")) - .roles("USER") - .and() - .withUser("Admin") - .password(encoder.encode("Admin")) - .roles("ADMIN") - } - - @Bean - open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { - http.authorizeHttpRequests { authorize -> - authorize.requestMatchers("/ws/*").authenticated() - .anyRequest().permitAll() - } - .httpBasic { } - .formLogin { } - .csrf { it.disable() } - return http.build() - } - - @Bean - fun userDetailsService(): UserDetailsService { - val user = User.withUsername("user") - .password("{noop}password") // {noop} = pas de hash pour dev - .roles("USER") - .build() - - return InMemoryUserDetailsManager(user) - } -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/config/WebSocketConfig.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/config/WebSocketConfig.kt deleted file mode 100644 index ec13cd2..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/config/WebSocketConfig.kt +++ /dev/null @@ -1,32 +0,0 @@ -package fr.teamflash.fencerjudgeback.config - -import org.springframework.context.annotation.Configuration -import org.springframework.messaging.simp.config.MessageBrokerRegistry -import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker -import org.springframework.web.socket.config.annotation.StompEndpointRegistry -import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer -import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor - -const val CHANNEL_MATCH_NAME: String = "/ws/topic/match" - -@Configuration -@EnableWebSocketMessageBroker -open class MatchWebSocketConfig : WebSocketMessageBrokerConfigurer { - - override fun configureMessageBroker(registry: MessageBrokerRegistry) { - // Enable a simple memory-based message broker to send messages to clients - // Prefix for messages FROM server TO client - registry.enableSimpleBroker(CHANNEL_MATCH_NAME) - - // Prefix for messages FROM client TO server - registry.setApplicationDestinationPrefixes("/ws") - } - - override fun registerStompEndpoints(registry: StompEndpointRegistry) { - // Register the "/ws" endpoint, enabling SockJS fallback options - registry.addEndpoint("/ws/matches-app") - .addInterceptors(HttpSessionHandshakeInterceptor()) - .setAllowedOriginPatterns("*") // Allow connections from any origin (adjust for production) - .withSockJS() - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/MatchBean.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/MatchBean.kt deleted file mode 100644 index f37c7fd..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/MatchBean.kt +++ /dev/null @@ -1,40 +0,0 @@ -package fr.teamflash.fencerjudgeback.entities - -import jakarta.persistence.Entity -import jakarta.persistence.GeneratedValue -import jakarta.persistence.GenerationType -import jakarta.persistence.Id -import jakarta.persistence.SequenceGenerator -import jakarta.persistence.Table -import jakarta.validation.constraints.* -import java.util.Date - -enum class MatchState { - ONGOING, - OVER, - NOT_STARTED -} - -@Entity -@Table(name="matches") -data class MatchBean( - - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "match_sequence") - @SequenceGenerator(name = "match_sequence", sequenceName = "match_seq", allocationSize = 1) - var id:Long?=null, - val weapon:String?=null, - val country:String?=null, - val city:String?=null, - @field:NotNull(message = "Player 1 ID must not be null") - val player1ID:Long?=null, - @field:NotNull(message = "Player 2 ID must not be null") - val player2ID:Long?=null, - val refereeID: Long?=null, - @field:Min(value = 0, message = "Score must be at least 0") - var score1:Int=0, - @field:Min(value = 0, message = "Score must be at least 0") - var score2:Int=0, - val date: Date?=null, - val state: MatchState?=null -) diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/MatchUpdateBean.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/MatchUpdateBean.kt deleted file mode 100644 index 16059ac..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/MatchUpdateBean.kt +++ /dev/null @@ -1,3 +0,0 @@ -package fr.teamflash.fencerjudgeback.entities - -data class MatchUpdateBean(val match: MatchBean?=null, val playerId:Long?=null) \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/PlayerBean.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/PlayerBean.kt deleted file mode 100644 index 4033340..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/PlayerBean.kt +++ /dev/null @@ -1,20 +0,0 @@ -package fr.teamflash.fencerjudgeback.entities - -import jakarta.persistence.Entity -import jakarta.persistence.GeneratedValue -import jakarta.persistence.GenerationType -import jakarta.persistence.Id -import jakarta.persistence.SequenceGenerator -import jakarta.persistence.Table - -@Entity -@Table(name="players") -data class PlayerBean( - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "player_sequence") - @SequenceGenerator(name = "player_sequence", sequenceName = "player_seq", allocationSize = 1) - val id:Long?=null, - val name:String?="", - val firstName:String?="", - val club:String?="" -) \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/RefereeBean.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/RefereeBean.kt deleted file mode 100644 index cb2570a..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/entities/RefereeBean.kt +++ /dev/null @@ -1,27 +0,0 @@ -package fr.teamflash.fencerjudgeback.entities - -import jakarta.persistence.Entity -import jakarta.persistence.GeneratedValue -import jakarta.persistence.GenerationType -import jakarta.persistence.Id -import jakarta.persistence.SequenceGenerator -import jakarta.persistence.Table - -enum class RefereeLevel { - DEPARTMENTAL, - REGIONAL, - NATIONAL, - INTERNATIONAL -} - -@Entity -@Table(name="referees") -data class RefereeBean( - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "referee_sequence") - @SequenceGenerator(name = "referee_sequence", sequenceName = "referee_seq", allocationSize = 1) - val id:Long?=null, - val name:String?=null, - val firstName:String?=null, - val level:RefereeLevel?=null -) \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/MatchRepository.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/MatchRepository.kt deleted file mode 100644 index 728d059..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/MatchRepository.kt +++ /dev/null @@ -1,9 +0,0 @@ -package fr.teamflash.fencerjudgeback.repositories - -import fr.teamflash.fencerjudgeback.entities.MatchBean -import org.springframework.data.jpa.repository.JpaRepository -import org.springframework.stereotype.Repository - -@Repository -interface MatchRepository: JpaRepository { -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/PlayerRepository.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/PlayerRepository.kt deleted file mode 100644 index ee1eefe..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/PlayerRepository.kt +++ /dev/null @@ -1,9 +0,0 @@ -package fr.teamflash.fencerjudgeback.repositories - -import fr.teamflash.fencerjudgeback.entities.PlayerBean -import org.springframework.data.jpa.repository.JpaRepository -import org.springframework.stereotype.Repository - -@Repository -interface PlayerRepository: JpaRepository { -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/RefereeRepository.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/RefereeRepository.kt deleted file mode 100644 index 102c985..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/repositories/RefereeRepository.kt +++ /dev/null @@ -1,10 +0,0 @@ -package fr.teamflash.fencerjudgeback.repositories - -import fr.teamflash.fencerjudgeback.entities.RefereeBean -import org.springframework.data.jpa.repository.JpaRepository -import org.springframework.stereotype.Repository - -@Repository -interface RefereeRepository : JpaRepository { - -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/MainController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/MainController.kt deleted file mode 100644 index 5dbfd7a..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/MainController.kt +++ /dev/null @@ -1,12 +0,0 @@ -package fr.teamflash.fencerjudgeback.restControllers - -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RestController - -@RestController -class MainController { - @GetMapping("/") - fun main() { - return print("Hello") - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/MatchRestController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/MatchRestController.kt deleted file mode 100644 index ab2e7de..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/MatchRestController.kt +++ /dev/null @@ -1,90 +0,0 @@ -package fr.teamflash.fencerjudgeback.restControllers - -import fr.teamflash.fencerjudgeback.entities.MatchBean -import fr.teamflash.fencerjudgeback.entities.MatchState -import fr.teamflash.fencerjudgeback.services.MatchService -import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.* -import java.util.Date - -@RestController -@CrossOrigin(origins = ["*"]) -@RequestMapping("/matches") -class MatchRestController(private val matchService: MatchService) { - - companion object { - const val URL_ORIGIN: String = "http://localhost:*" - } - - // Lister tous les matchs - @GetMapping("/") - fun getAll(): ResponseEntity?> { - return ResponseEntity.ok(matchService.getAll()) - } - - // Lister tous les matchs à partir d'une certaine date - @GetMapping("/date/{date}") - fun getAllFromDate(@PathVariable date: Date): ResponseEntity?> { - return ResponseEntity.ok(matchService.getAll().filter { it.date == date }) - } - - // Lister tous les matchs par pays - @GetMapping("/country/{country}") - fun getAllFromCountry(@PathVariable country:String): ResponseEntity?> { - return ResponseEntity.ok(matchService.getAll().filter { it.country == country }) - } - - // Lister tous les matchs par ville - @GetMapping("/city/{city}") - fun getAllFromCity(@PathVariable city:String): ResponseEntity?> { - return ResponseEntity.ok(matchService.getAll().filter { it.city == city }) - } - - // Lister tous les matchs par joueurs - @GetMapping("/players/{player1ID}/{player2ID}") - fun getAllWithPlayers(@PathVariable player1ID: Long?, @PathVariable player2ID: Long?): ResponseEntity?> { - return ResponseEntity.ok(matchService.getByPlayers(player1ID, player2ID)) - } - - // Lister les matchs en cours - @GetMapping("/active") - fun getAllActive(): ResponseEntity?> { - return ResponseEntity.ok(matchService.getAll().filter { it.state == MatchState.ONGOING }) - } - - // Lister les matchs terminés - @GetMapping("/over") - fun getAllFinished(): ResponseEntity?> { - return ResponseEntity.ok(matchService.getAll().filter { it.state == MatchState.OVER }) - } - - // Lister les matchs non commencés - @GetMapping("/not-started") - fun getAllNotStarted(): ResponseEntity?> { - return ResponseEntity.ok(matchService.getAll().filter { it.state == MatchState.NOT_STARTED }) - } - - // Afficher un match par id - @GetMapping("/{id}") - fun getById(@PathVariable id: Long): ResponseEntity { - return ResponseEntity.ok(matchService.getById(id)) - } - - // Ajouter un match - @PostMapping("/create-match") - fun createMatch(@RequestBody match: MatchBean): ResponseEntity { - return ResponseEntity.ok(matchService.createMatch(match)) - } - - // Mettre à jour un match - @PutMapping("/update-match/{id}") - fun updateMatch(@PathVariable id: Long, @RequestBody match: MatchBean): ResponseEntity { - return ResponseEntity.ok(matchService.updateMatch(id, match)) - } - - // Supprimer un match - @DeleteMapping("/delete-match/{id}") - fun deleteMatch(@PathVariable id: Long): ResponseEntity { - return ResponseEntity.ok(matchService.deleteMatchById(id)) - } -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/PlayerRestController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/PlayerRestController.kt deleted file mode 100644 index 628282a..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/PlayerRestController.kt +++ /dev/null @@ -1,68 +0,0 @@ -package fr.teamflash.fencerjudgeback.restControllers - -import fr.teamflash.fencerjudgeback.entities.PlayerBean -import fr.teamflash.fencerjudgeback.services.PlayerService -import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.CrossOrigin -import org.springframework.web.bind.annotation.DeleteMapping -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.PutMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@RestController -@CrossOrigin(origins = ["*"]) -@RequestMapping("/players") -class PlayerRestController(private val playerService: PlayerService) { - - // Lister tous les joueurs - @GetMapping("/") - fun getAll(): ResponseEntity> { - return ResponseEntity.ok(playerService.getAll()) - } - - // Afficher un joueur par id - @GetMapping("/{id}") - fun getById(@PathVariable id: Long): ResponseEntity { - return ResponseEntity.ok(playerService.getById(id)) - } - - // Afficher un ou plusieurs joueur(s) par nom - @GetMapping("/name/{name}") - fun getByName(@PathVariable name: String): ResponseEntity?> { - return ResponseEntity.ok(playerService.getByName(name)) - } - - // Afficher un ou plusieurs joueur(s) par prénom - @GetMapping("/firstName/{firstName}") - fun getByFirstName(@PathVariable firstName: String): ResponseEntity?> { - return ResponseEntity.ok(playerService.getByFirstName(firstName)) - } - - // Afficher un ou plusieurs joueur(s) par club - @GetMapping("/club/{club}") - fun getByClub(@PathVariable club: String): ResponseEntity?> { - return ResponseEntity.ok(playerService.getByClub(club)) - } - - // Ajouter un joueur - @PostMapping("/create-player") - fun createPlayer(@RequestBody player: PlayerBean): ResponseEntity { - return ResponseEntity.ok(playerService.createPlayer(player)) - } - - // Modifier un joueur - @PutMapping("/update-player/{id}") - fun updatePlayer(@PathVariable id: Long, @RequestBody player: PlayerBean): ResponseEntity { - return ResponseEntity.ok(playerService.updatePlayer(id, player)) - } - - // Supprimer un joueur - @DeleteMapping("/delete-player/{id}") - fun deletePlayer(@PathVariable id: Long): ResponseEntity { - return ResponseEntity.ok(playerService.deletePlayerById(id)) - } -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/RefereeRestController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/RefereeRestController.kt deleted file mode 100644 index 42ca424..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/restControllers/RefereeRestController.kt +++ /dev/null @@ -1,71 +0,0 @@ -package fr.teamflash.fencerjudgeback.restControllers - -import fr.teamflash.fencerjudgeback.entities.MatchState -import fr.teamflash.fencerjudgeback.entities.RefereeBean -import fr.teamflash.fencerjudgeback.entities.RefereeLevel -import fr.teamflash.fencerjudgeback.services.RefereeService -import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.CrossOrigin -import org.springframework.web.bind.annotation.DeleteMapping -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.PutMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@RestController -@CrossOrigin(origins = ["*"]) -@RequestMapping("/referees") -class RefereeRestController(private val refereeService: RefereeService) { - - // Lister tous les arbitres - @GetMapping("/") - fun getAll() : ResponseEntity> { - return ResponseEntity.ok(refereeService.getAll()) - } - - // Afficher un arbitre par id - @GetMapping("/{id}") - fun getById(@PathVariable id: Long): ResponseEntity { - return ResponseEntity.ok(refereeService.getById(id)) - } - - // Afficher un ou plusieurs arbitre(s) par nom - @GetMapping("/name/{name}") - fun getByName(@PathVariable name:String): ResponseEntity?> { - return ResponseEntity.ok(refereeService.getByName(name)) - } - - // Afficher un ou plusieurs arbitre(s) par prénom - @GetMapping("/firstname/{firstName}") - fun getByFirstName(@PathVariable firstName:String): ResponseEntity?> { - return ResponseEntity.ok(refereeService.getByFirstName(firstName)) - } - - // Afficher un ou plusieurs arbitre(s) par niveau - @GetMapping("/level/{level}") - fun getByQualification(@PathVariable level: RefereeLevel): ResponseEntity?> { - return ResponseEntity.ok(refereeService.getByLevel(level)) - } - - // Ajouter un arbitre - @PostMapping("/create-referee") - fun createReferee(@RequestBody referee: RefereeBean): ResponseEntity { - return ResponseEntity.ok(refereeService.createReferee(referee)) - } - - // Modifier un arbitre - @PutMapping("/update-referee/{id}") - fun updateReferee(@PathVariable id: Long, @RequestBody referee: RefereeBean) : ResponseEntity { - return ResponseEntity.ok(refereeService.updateReferee(id, referee)) - } - - // Supprimer un arbitre - @DeleteMapping("/delete-referee/{id}") - fun deleteReferee(@PathVariable id:Long): ResponseEntity { - return ResponseEntity.ok(refereeService.deleteRefereeById(id)) - } - -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/MatchService.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/MatchService.kt deleted file mode 100644 index 1e5f24b..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/MatchService.kt +++ /dev/null @@ -1,98 +0,0 @@ -package fr.teamflash.fencerjudgeback.services - -import fr.teamflash.fencerjudgeback.entities.MatchBean -import fr.teamflash.fencerjudgeback.repositories.MatchRepository -import fr.teamflash.fencerjudgeback.websocket.controllers.MatchWebSocketController -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.annotation.Lazy -import org.springframework.stereotype.Service - -@Service -class MatchService( - @Autowired private val matchRepository: MatchRepository, - @Lazy private val matchWebSocketController: MatchWebSocketController? = null -) { - // Obtenir tous les matchs (public) - fun getAll() : List { - println("MatchService.getMatchs") - return matchRepository.findAll() - } - - // Obtenir un match par id (public) - fun getById(id: Long?): MatchBean? { - println("MatchService.getMatchById : $id") - - if (id == null) { - println("MatchService.getMatchById : Match not found") - return null - } - - return matchRepository.findById(id).get() - } - - // Obtenir un ou plusieurs match(s) par joueurs (id) (public) - fun getByPlayers(player1ID: Long?, player2ID: Long?): List { - println("MatchService.getMatchByPlayers : $player1ID - $player2ID") - return matchRepository.findAll().filter { it.player1ID == player1ID && it.player2ID == player2ID } - } - - // Ajouter un match (admin) - fun createMatch(newMatch: MatchBean): MatchBean { - println("MatchService.createMatch : $newMatch") - val savedMatch = matchRepository.save(newMatch) - // Broadcast the new match via WebSocket - matchWebSocketController?.broadcastMatchUpdate(savedMatch, fr.teamflash.fencerjudgeback.websocket.models.MatchUpdateMessage.UpdateType.MATCH_START) - - return savedMatch - } - - // Modifier un match (admin) - fun updateMatch(id: Long?, newMatch: MatchBean): Int { - println("MatchService.updateMatch : $newMatch") - - if (getById(id) == null) { - return -1 - } - - val updatedMatch = newMatch.copy(id = id) - val savedMatch = matchRepository.save(updatedMatch) - // Broadcast the updated match via WebSocket - matchWebSocketController?.broadcastMatchUpdate(savedMatch, fr.teamflash.fencerjudgeback.websocket.models.MatchUpdateMessage.UpdateType.SCORE_UPDATE) - return 1 - } - - // Supprimer un match (admin) - fun deleteMatchById(id: Long?) : Int? { - println("MatchService.deleteMatchById : $id") - - val match = getById(id) - if (match == null) { - println("MatchService.deleteMatchById : Match not found") - return -1 - } - - // Broadcast the match deletion via WebSocket before deleting - matchWebSocketController?.broadcastMatchUpdate(match, fr.teamflash.fencerjudgeback.websocket.models.MatchUpdateMessage.UpdateType.MATCH_CANCEL) - - matchRepository.deleteById(id!!) - return 1 - } - - fun getMatchesByCity(city: String): List? { - println("MatchService.getMatchesByCity : $city") - - return matchRepository.findAll() - .filter { it.city == city } - } - - fun getMatchesByCountry(country: String): List? { - println("MatchService.getMatchesByCountry : $country") - - return matchRepository.findAll() - .filter { it.country == country } - } - - fun addMatch(match:MatchBean) { - matchRepository.save(match) - } -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/PlayerService.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/PlayerService.kt deleted file mode 100644 index 0443f0e..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/PlayerService.kt +++ /dev/null @@ -1,96 +0,0 @@ -package fr.teamflash.fencerjudgeback.services - -import fr.teamflash.fencerjudgeback.entities.PlayerBean -import fr.teamflash.fencerjudgeback.repositories.PlayerRepository -import fr.teamflash.fencerjudgeback.websocket.controllers.PlayerWebSocketController -import fr.teamflash.fencerjudgeback.websocket.models.PlayerUpdateMessage -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.annotation.Lazy -import org.springframework.stereotype.Service - -@Service -class PlayerService( - @Autowired private val playerRepository: PlayerRepository, - @Lazy private val playerWebSocketController: PlayerWebSocketController? = null -) { - // Obtenir tous les joueurs (public) - fun getAll(): List { - println("PlayerService.getAll") - return playerRepository.findAll() - } - - // Obtenir un joueur par id (public) - fun getById(id:Long?) : PlayerBean? { - println("PlayerService.getById : $id") - - if (id == null) { - return null - } - - return playerRepository.findById(id).get() - } - - // Obtenir un ou plusieurs joueur(s) par nom (public) - fun getByName(name:String): List? { - println("PlayerService.getByName : $name") - return playerRepository.findAll().filter{ it.name == name } - } - - // Obtenir un ou plusieurs joueur(s) par prénom - fun getByFirstName(firstName:String): List? { - println("PlayerService.getByFirstName : $firstName") - return playerRepository.findAll().filter{ it.firstName == firstName } - } - - // Obtenir un ou plusieurs joueur(s) par club - fun getByClub(club:String): List? { - println("PlayerService.getByClub : $club") - return playerRepository.findAll().filter{ it.club == club } - } - - // Ajouter un joueur (admin) - fun createPlayer(player: PlayerBean) : PlayerBean { - println("PlayerService.createPlayer : $player") - val savedPlayer = playerRepository.save(player) - // Broadcast the new player via WebSocket - playerWebSocketController?.broadcastPlayerUpdate(savedPlayer, PlayerUpdateMessage.UpdateType.PLAYER_CREATE) - return savedPlayer - } - - // Modifier un joueur (admin) - fun updatePlayer(id:Long, newPlayer: PlayerBean) : Int { - // Vérifier si le joueur existe à l'id renseigné - if (getById(id) == null) { - println("PlayerService.updatePlayer : Player not found") - return -1 - } - - val updatedPlayer = newPlayer.copy(id = id) - val savedPlayer = playerRepository.save(updatedPlayer) - // Broadcast the updated player via WebSocket - playerWebSocketController?.broadcastPlayerUpdate(savedPlayer, PlayerUpdateMessage.UpdateType.PLAYER_UPDATE) - - return 1 - } - - // Supprimer un joueur (admin) - fun deletePlayerById(id:Long?): Int { - println("PlayerService.deletePlayer : $id") - - val player = getById(id) - if (player == null) { - println("PlayerService.deletePlayer : Player not found") - return -1 - } - - // Broadcast the player deletion via WebSocket before deleting - playerWebSocketController?.broadcastPlayerUpdate(player, PlayerUpdateMessage.UpdateType.PLAYER_DELETE) - - playerRepository.deleteById(id!!) - return 1 - } - - fun addPlayer(player:PlayerBean) { - playerRepository.save(player) - } -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/RefereeService.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/RefereeService.kt deleted file mode 100644 index c3491ed..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/services/RefereeService.kt +++ /dev/null @@ -1,92 +0,0 @@ -package fr.teamflash.fencerjudgeback.services - -import fr.teamflash.fencerjudgeback.entities.MatchState -import fr.teamflash.fencerjudgeback.entities.RefereeBean -import fr.teamflash.fencerjudgeback.entities.RefereeLevel -import fr.teamflash.fencerjudgeback.repositories.RefereeRepository -import fr.teamflash.fencerjudgeback.websocket.controllers.RefereeWebSocketController -import fr.teamflash.fencerjudgeback.websocket.models.RefereeUpdateMessage -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.annotation.Lazy -import org.springframework.stereotype.Service - -@Service -class RefereeService( - @Autowired private val refereeRepository: RefereeRepository, - @Lazy private val refereeWebSocketController: RefereeWebSocketController? = null -) { - // Obtenir tous les arbitres (public) - fun getAll(): List { - println("RefereeService.getReferees") - return refereeRepository.findAll() - } - - // Obtenir un arbitre par id (public) - fun getById(id:Long?) : RefereeBean? { - println("RefereeService.getRefereeById : $id") - - if (id == null) { - return null - } - - return refereeRepository.findById(id).get() - } - - // Obtenir un ou plusieurs arbitre(s) par nom (public) - fun getByName(name:String): List? { - println("RefereeService.getRefereeByName : $name") - return refereeRepository.findAll().filter{ it.name == name } - } - - // Obtenir un ou plusieurs arbitre(s) par prénom - fun getByFirstName(firstName:String): List? { - println("RefereeService.getRefereeByFirstName : $firstName") - return refereeRepository.findAll().filter{ it.firstName == firstName } - } - - // Obtenir un ou plusieurs arbitre(s) par niveau - fun getByLevel(level: RefereeLevel): List? { - println("RefereeService.getByLevel : $level") - return refereeRepository.findAll().filter{ it.level == level } - } - - // Ajouter un arbitre (admin) - fun createReferee(referee: RefereeBean) : RefereeBean { - println("RefereeService.createReferee : $referee") - val savedReferee = refereeRepository.save(referee) - // Broadcast the new referee via WebSocket - refereeWebSocketController?.broadcastRefereeUpdate(savedReferee, RefereeUpdateMessage.UpdateType.REFEREE_CREATE) - return savedReferee - } - - // Modifier un arbitre (admin) - fun updateReferee(id:Long, newReferee: RefereeBean) : Int? { - // Vérifier si l'arbitre existe à l'id renseigné - if (getById(id) == null) { - return -1 - } - - val updatedReferee = newReferee.copy(id = id) - val savedReferee = refereeRepository.save(updatedReferee) - // Broadcast the updated referee via WebSocket - refereeWebSocketController?.broadcastRefereeUpdate(savedReferee, RefereeUpdateMessage.UpdateType.REFEREE_UPDATE) - return 1 - } - - // Supprimer un arbitre (admin) - fun deleteRefereeById(id:Long): Int { - println("RefereeService.deleteReferee : $id") - - val referee = getById(id) - if (referee == null) { - println("RefereeService.deleteReferee : Referee not found") - return -1 - } - - // Broadcast the referee deletion via WebSocket before deleting - refereeWebSocketController?.broadcastRefereeUpdate(referee, RefereeUpdateMessage.UpdateType.REFEREE_DELETE) - - refereeRepository.deleteById(id) - return 1 - } -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/README.md b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/README.md deleted file mode 100644 index ebd2037..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# WebSocket Implementation for FencerJudge - -This document explains how to use the WebSocket functionality in the FencerJudge application for real-time match updates. - -## Overview - -The WebSocket implementation allows for real-time updates of match information, including: -- Match creation -- Score updates -- Match completion -- Match cancellation - -## WebSocket Endpoints - -### Connection Endpoint -``` -ws://localhost:8080/ws -``` - -The WebSocket endpoint supports SockJS for fallback in browsers that don't support WebSockets natively. - -## Message Topics - -### Subscribe to Match Updates -To receive real-time match updates, subscribe to: -``` -/topic/match.updates -``` - -### Send Match Updates -To send match updates from the client to the server: -``` -/app/match.update -``` - -## Message Format - -Match update messages use the following JSON format: - -```json -{ - "matchId": 1, - "player1Id": 101, - "player2Id": 102, - "refereeId": 201, - "score1": 5, - "score2": 3, - "date": "2023-06-01", - "type": "SCORE_UPDATE" -} -``` - -The `type` field can have the following values: -- `SCORE_UPDATE`: When a match score is updated -- `MATCH_START`: When a new match is created -- `MATCH_END`: When a match is completed -- `MATCH_CANCEL`: When a match is cancelled - -## Integration with REST API - -The WebSocket functionality is integrated with the REST API. Any changes made through the REST endpoints will automatically trigger WebSocket messages to all connected clients. - -REST endpoints: -- `GET /api/matches`: Get all matches -- `GET /api/matches/{id}`: Get a match by ID -- `POST /api/matches`: Create a new match (triggers MATCH_START WebSocket message) -- `PUT /api/matches/{id}`: Update a match (triggers SCORE_UPDATE WebSocket message) -- `PATCH /api/matches/{id}/score`: Update just the score (triggers SCORE_UPDATE WebSocket message) -- `DELETE /api/matches/{id}`: Delete a match (triggers MATCH_CANCEL WebSocket message) - -## Client-Side Example (JavaScript) - -```javascript -// Using SockJS and STOMP client -import SockJS from 'sockjs-client'; -import { Client } from '@stomp/stompjs'; - -// Create a new STOMP client -const socket = new SockJS('http://localhost:8080/ws'); -const stompClient = new Client({ - webSocketFactory: () => socket, - debug: (str) => console.log(str) -}); - -// Connect to the WebSocket server -stompClient.activate(); - -// Subscribe to match updates -stompClient.onConnect = (frame) => { - console.log('Connected to WebSocket'); - - // Subscribe to match updates - stompClient.subscribe('/topic/match.updates', (message) => { - const matchUpdate = JSON.parse(message.body); - console.log('Received match update:', matchUpdate); - - // Handle the update in your application - // e.g., update UI, play sound, etc. - }); -}; - -// Send a match update (e.g., when a referee updates a score) -function sendMatchUpdate(matchId, score1, score2) { - if (stompClient.connected) { - stompClient.publish({ - destination: '/app/match.update', - body: JSON.stringify({ - matchId: matchId, - score1: score1, - score2: score2, - type: 'SCORE_UPDATE' - }) - }); - } -} -``` - -## Security Considerations - -The WebSocket endpoint is currently configured to allow connections from any origin (`*`). For production environments, this should be restricted to specific allowed origins. \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/WebsocketController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/WebsocketController.kt deleted file mode 100644 index af33708..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/WebsocketController.kt +++ /dev/null @@ -1,41 +0,0 @@ -package fr.teamflash.fencerjudgeback.websocket - -import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.simp.SimpMessagingTemplate -import org.springframework.stereotype.Controller -import org.springframework.web.bind.annotation.RequestMapping - -data class Data(val id: String, val value: Any) - -@Controller -@RequestMapping("/ws") -class WebSocketController(private val messagingTemplate: SimpMessagingTemplate) { - - // Insérer une donnée dans le channel - @MessageMapping("/insert") - fun insertData(data: Data) { - // Logique d'insertion - messagingTemplate.convertAndSend("/topic/data", data) - } - - // Modifier une donnée existente dans le channel - @MessageMapping("/modify") - fun modifyData(data: Data) { - // Logique de modification - messagingTemplate.convertAndSend("/topic/data", data) - } - - // Supprimer une donnée existante dans le channel - @MessageMapping("/delete") - fun deleteData(id: String) { - // Logique de suppression - messagingTemplate.convertAndSend("/topic/data/delete", id) - } - - // Vider le channel - @MessageMapping("/clear") - fun clearChannel() { - // Logique pour vider le channel - messagingTemplate.convertAndSend("/topic/data/clear", null) - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/MatchWebSocketController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/MatchWebSocketController.kt deleted file mode 100644 index bee6a2f..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/MatchWebSocketController.kt +++ /dev/null @@ -1,118 +0,0 @@ -package fr.teamflash.fencerjudgeback.websocket.controllers - -import fr.teamflash.fencerjudgeback.config.CHANNEL_MATCH_NAME -import fr.teamflash.fencerjudgeback.entities.MatchBean -import fr.teamflash.fencerjudgeback.entities.MatchUpdateBean -import fr.teamflash.fencerjudgeback.services.MatchService -import fr.teamflash.fencerjudgeback.websocket.models.MatchUpdateMessage -import org.springframework.context.event.EventListener -import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.simp.SimpMessagingTemplate -import org.springframework.messaging.simp.stomp.StompHeaderAccessor -import org.springframework.stereotype.Controller -import org.springframework.web.socket.messaging.SessionSubscribeEvent - -@Controller -class MatchWebSocketController( - private val matchService: MatchService, - private val messagingTemplate: SimpMessagingTemplate -) { - - private var mainId:Long? = 1 - private val messageHistory = ArrayList() - - @MessageMapping("/all") - fun receiveMessage(message: MatchBean) { - println("/ws/matches $message") - messageHistory.add(message) - - // Envoyer la liste des messages sur le channel - //Si la variable est dans le même package il faut enlever WebSocketConfig. - messagingTemplate.convertAndSend(CHANNEL_MATCH_NAME, messageHistory) - } - - /** - * Handle match update requests from clients - * Client sends to: /app/match.update - * Server broadcasts to: /topic/match.updates - */ - @MessageMapping("/update") - fun handleMatchUpdate(matchUpdateMessage: MatchUpdateMessage): MatchUpdateMessage { - // Create a MatchBean from the update message - val matchBean = MatchBean( - id = matchUpdateMessage.matchId, - player1ID = matchUpdateMessage.player1Id, - player2ID = matchUpdateMessage.player2Id, - refereeID = matchUpdateMessage.refereeId, - score1 = matchUpdateMessage.score1, - score2 = matchUpdateMessage.score2, - date = matchUpdateMessage.date - ) - - // Update the match in the database - matchService.updateMatch(matchBean.id, matchBean) - - // Return the update message to be broadcast to all subscribers - return matchUpdateMessage - } - - /** - * Broadcast a match update to all connected clients - * This method can be called from other services - */ - fun broadcastMatchUpdate(matchBean: MatchBean, type: MatchUpdateMessage.UpdateType = MatchUpdateMessage.UpdateType.SCORE_UPDATE) { - val updateMessage = MatchUpdateMessage.fromMatchBean(matchBean, type) - messagingTemplate.convertAndSend("/topic/match.updates", updateMessage) - } - - //A mettre dans le controller - @EventListener - fun handleWebSocketSubscribeListener(event: SessionSubscribeEvent) { - val headerAccessor = StompHeaderAccessor.wrap(event.message) - if (CHANNEL_MATCH_NAME == headerAccessor.destination) { - messagingTemplate.convertAndSend(CHANNEL_MATCH_NAME, messageHistory) - println("Lancement du WebSocket") - } - } - - @MessageMapping("/plusPoint") - fun addPoint(matchUpdateBean: MatchUpdateBean) { - val playerId = matchUpdateBean.playerId - val match = matchUpdateBean.match - print("plus") - if (match != null) { - print("minus") - when (playerId) { - match.player1ID -> if (match.score1 > 0) match.score1 -= 1 - match.player2ID -> if (match.score2 > 0) match.score2 -= 1 - } - matchService.updateMatch(match.id, match) - broadcastMatchUpdate(match) - } - } - - @MessageMapping("/minusPoint") - fun minusPoint(matchUpdateBean: MatchUpdateBean) { - val playerId = matchUpdateBean.playerId - val match = matchUpdateBean.match - print("minus") - if (match != null) { - when (playerId) { - match.player1ID -> if (match.score1 > 0) match.score1 -= 1 - match.player2ID -> if (match.score2 > 0) match.score2 -= 1 - } - matchService.updateMatch(match.id, match) - broadcastMatchUpdate(match) - } - } - - @MessageMapping("/add") - fun addMatchtoMainList(match:MatchBean) { - match.id = mainId; - matchService.addMatch(match) - messageHistory.add(match) - broadcastMatchUpdate(match, MatchUpdateMessage.UpdateType.NEW_MATCH) - mainId = mainId?.plus(1) - println("Ajout du match $match.id en bdd") - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/PlayerWebSocketController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/PlayerWebSocketController.kt deleted file mode 100644 index 4e31270..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/PlayerWebSocketController.kt +++ /dev/null @@ -1,71 +0,0 @@ -package fr.teamflash.fencerjudgeback.websocket.controllers - -import fr.teamflash.fencerjudgeback.entities.PlayerBean -import fr.teamflash.fencerjudgeback.services.PlayerService -import fr.teamflash.fencerjudgeback.websocket.models.PlayerUpdateMessage -import org.springframework.context.event.EventListener -import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.handler.annotation.SendTo -import org.springframework.messaging.simp.SimpMessagingTemplate -import org.springframework.messaging.simp.stomp.StompHeaderAccessor -import org.springframework.stereotype.Controller -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.socket.messaging.SessionSubscribeEvent - -@Controller -@RequestMapping("/ws") -class PlayerWebSocketController( - private val playerService: PlayerService, - private val messagingTemplate: SimpMessagingTemplate -) { - - private val messageHistory = ArrayList() - - @MessageMapping("/player.update") - @SendTo("/topic/player.updates") - fun handlePlayerUpdate(playerUpdateMessage: PlayerUpdateMessage): PlayerUpdateMessage { - // Create a PlayerBean from the update message - val playerBean = PlayerBean( - id = playerUpdateMessage.playerId, - name = playerUpdateMessage.name, - firstName = playerUpdateMessage.firstName, - club = playerUpdateMessage.club - ) - - // Update the player in the database - playerService.updatePlayer(playerBean.id ?: 0, playerBean) - - // Return the update message to be broadcast to all subscribers - return playerUpdateMessage - } - - /** - * Broadcast a player update to all connected clients - * This method can be called from other services - */ - fun broadcastPlayerUpdate(playerBean: PlayerBean, type: PlayerUpdateMessage.UpdateType = PlayerUpdateMessage.UpdateType.PLAYER_UPDATE) { - val updateMessage = PlayerUpdateMessage.fromPlayerBean(playerBean, type) - messagingTemplate.convertAndSend("/topic/player.updates", updateMessage) - } - - @EventListener - fun handleWebSocketSubscribeListener(event: SessionSubscribeEvent) { - val headerAccessor = StompHeaderAccessor.wrap(event.message) - if ("/topic/player.updates" == headerAccessor.destination) { - // When a client subscribes, send them the current players - val players = playerService.getAll() - players.forEach { player -> - messagingTemplate.convertAndSend( - "/topic/player.updates", - PlayerUpdateMessage.fromPlayerBean(player, PlayerUpdateMessage.UpdateType.PLAYER_UPDATE) - ) - } - } - } - - @MessageMapping - fun addPlayerToMainList(playerBean: PlayerBean) { - playerService.addPlayer(playerBean) - broadcastPlayerUpdate(playerBean, PlayerUpdateMessage.UpdateType.PLAYER_CREATE) - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/RefereeWebSocketController.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/RefereeWebSocketController.kt deleted file mode 100644 index 792fdc1..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/controllers/RefereeWebSocketController.kt +++ /dev/null @@ -1,66 +0,0 @@ -package fr.teamflash.fencerjudgeback.websocket.controllers - -import fr.teamflash.fencerjudgeback.config.CHANNEL_MATCH_NAME -import fr.teamflash.fencerjudgeback.entities.RefereeBean -import fr.teamflash.fencerjudgeback.services.RefereeService -import fr.teamflash.fencerjudgeback.websocket.models.RefereeUpdateMessage -import org.springframework.context.event.EventListener -import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.handler.annotation.SendTo -import org.springframework.messaging.simp.SimpMessagingTemplate -import org.springframework.messaging.simp.stomp.StompHeaderAccessor -import org.springframework.stereotype.Controller -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.socket.messaging.SessionSubscribeEvent - -@Controller -@RequestMapping("/ws") -class RefereeWebSocketController( - private val refereeService: RefereeService, - private val messagingTemplate: SimpMessagingTemplate -) { - - private val messageHistory = ArrayList() - - @MessageMapping("/referee.update") - @SendTo("/topic/referee.updates") - fun handleRefereeUpdate(refereeUpdateMessage: RefereeUpdateMessage): RefereeUpdateMessage { - // Create a RefereeBean from the update message - val refereeBean = RefereeBean( - id = refereeUpdateMessage.refereeId, - name = refereeUpdateMessage.name, - firstName = refereeUpdateMessage.firstName, - level = refereeUpdateMessage.level - ) - - // Update the referee in the database - refereeService.updateReferee(refereeBean.id ?: 0, refereeBean) - - // Return the update message to be broadcast to all subscribers - return refereeUpdateMessage - } - - /** - * Broadcast a referee update to all connected clients - * This method can be called from other services - */ - fun broadcastRefereeUpdate(refereeBean: RefereeBean, type: RefereeUpdateMessage.UpdateType = RefereeUpdateMessage.UpdateType.REFEREE_UPDATE) { - val updateMessage = RefereeUpdateMessage.fromRefereeBean(refereeBean, type) - messagingTemplate.convertAndSend("/topic/referee.updates", updateMessage) - } - - @EventListener - fun handleWebSocketSubscribeListener(event: SessionSubscribeEvent) { - val headerAccessor = StompHeaderAccessor.wrap(event.message) - if ("/topic/referee.updates" == headerAccessor.destination) { - // When a client subscribes, send them the current referees - val referees = refereeService.getAll() - referees.forEach { referee -> - messagingTemplate.convertAndSend( - "/topic/referee.updates", - RefereeUpdateMessage.fromRefereeBean(referee, RefereeUpdateMessage.UpdateType.REFEREE_UPDATE) - ) - } - } - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/MatchUpdateMessage.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/MatchUpdateMessage.kt deleted file mode 100644 index f30aef3..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/MatchUpdateMessage.kt +++ /dev/null @@ -1,44 +0,0 @@ -package fr.teamflash.fencerjudgeback.websocket.models - -import fr.teamflash.fencerjudgeback.entities.MatchBean -import java.util.* - -/** - * Message model for match updates sent through WebSocket - */ -data class MatchUpdateMessage( - val matchId: Long, - val player1Id: Long?, - val player2Id: Long?, - val refereeId: Long?, - val score1: Int, - val score2: Int, - val date: Date?, - val type: UpdateType = UpdateType.SCORE_UPDATE -) { - enum class UpdateType { - SCORE_UPDATE, - MATCH_START, - MATCH_END, - MATCH_CANCEL, - NEW_MATCH, - } - - companion object { - /** - * Create a MatchUpdateMessage from a MatchBean - */ - fun fromMatchBean(matchBean: MatchBean, type: UpdateType = UpdateType.SCORE_UPDATE): MatchUpdateMessage { - return MatchUpdateMessage( - matchId = matchBean.id ?: 0, - player1Id = matchBean.player1ID, - player2Id = matchBean.player2ID, - refereeId = matchBean.refereeID, - score1 = matchBean.score1, - score2 = matchBean.score2, - date = matchBean.date, - type = type - ) - } - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/PlayerUpdateMessage.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/PlayerUpdateMessage.kt deleted file mode 100644 index c45b1e5..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/PlayerUpdateMessage.kt +++ /dev/null @@ -1,35 +0,0 @@ -package fr.teamflash.fencerjudgeback.websocket.models - -import fr.teamflash.fencerjudgeback.entities.PlayerBean - -/** - * Message model for player updates sent through WebSocket - */ -data class PlayerUpdateMessage( - val playerId: Long, - val name: String?, - val firstName: String?, - val club: String?, - val type: UpdateType = UpdateType.PLAYER_UPDATE -) { - enum class UpdateType { - PLAYER_UPDATE, - PLAYER_CREATE, - PLAYER_DELETE - } - - companion object { - /** - * Create a PlayerUpdateMessage from a PlayerBean - */ - fun fromPlayerBean(playerBean: PlayerBean, type: UpdateType = UpdateType.PLAYER_UPDATE): PlayerUpdateMessage { - return PlayerUpdateMessage( - playerId = playerBean.id ?: 0, - name = playerBean.name, - firstName = playerBean.firstName, - club = playerBean.club, - type = type - ) - } - } -} diff --git a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/RefereeUpdateMessage.kt b/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/RefereeUpdateMessage.kt deleted file mode 100644 index 12f0fdd..0000000 --- a/FencerJudgeBack/src/main/kotlin/fr/teamflash/fencerjudgeback/websocket/models/RefereeUpdateMessage.kt +++ /dev/null @@ -1,36 +0,0 @@ -package fr.teamflash.fencerjudgeback.websocket.models - -import fr.teamflash.fencerjudgeback.entities.RefereeBean -import fr.teamflash.fencerjudgeback.entities.RefereeLevel - -/** - * Message model for referee updates sent through WebSocket - */ -data class RefereeUpdateMessage( - val refereeId: Long, - val name: String?, - val firstName: String?, - val level: RefereeLevel?, - val type: UpdateType = UpdateType.REFEREE_UPDATE -) { - enum class UpdateType { - REFEREE_UPDATE, - REFEREE_CREATE, - REFEREE_DELETE - } - - companion object { - /** - * Create a RefereeUpdateMessage from a RefereeBean - */ - fun fromRefereeBean(refereeBean: RefereeBean, type: UpdateType = UpdateType.REFEREE_UPDATE): RefereeUpdateMessage { - return RefereeUpdateMessage( - refereeId = refereeBean.id ?: 0, - name = refereeBean.name, - firstName = refereeBean.firstName, - level = refereeBean.level, - type = type - ) - } - } -} \ No newline at end of file diff --git a/FencerJudgeBack/src/main/resources/application.properties b/FencerJudgeBack/src/main/resources/application.properties index 0084aa4..6ada312 100644 --- a/FencerJudgeBack/src/main/resources/application.properties +++ b/FencerJudgeBack/src/main/resources/application.properties @@ -1,16 +1 @@ spring.application.name=FencerJudgeBack - -# H2 Database Configuration -spring.datasource.url=jdbc:h2:file:./db;AUTO_SERVER=true -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password=password -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect - -# Enable H2 Console -spring.h2.console.enabled=true -spring.h2.console.path=/h2-console - -# Hibernate Configuration -spring.jpa.hibernate.ddl-auto=update -spring.jpa.show-sql=true \ No newline at end of file diff --git a/FencerJudgeBack/src/main/resources/static/testMatchWebSocketHTML.html b/FencerJudgeBack/src/main/resources/static/testMatchWebSocketHTML.html deleted file mode 100644 index 950f7b6..0000000 --- a/FencerJudgeBack/src/main/resources/static/testMatchWebSocketHTML.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - Test WebSocket Match - - - - -

Test WebSocket Match

- -
Connexion...
- -
- - - -
- -
- - - -
- - - - - - - - - - diff --git a/FencerJudgeBack/src/main/resources/static/testPlayerMatchWebSocketHTML.html b/FencerJudgeBack/src/main/resources/static/testPlayerMatchWebSocketHTML.html deleted file mode 100644 index 15b617a..0000000 --- a/FencerJudgeBack/src/main/resources/static/testPlayerMatchWebSocketHTML.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - - Test WebSocket Match - - - - -

Test WebSocket Match

- -
Connexion...
- -
- - - - -
- -
- - - -
- - - - - - - - - - diff --git a/FencerJudgeBack/src/main/resources/static/testPlusOrMinusWebSocketHTML.html b/FencerJudgeBack/src/main/resources/static/testPlusOrMinusWebSocketHTML.html deleted file mode 100644 index 8fd04a8..0000000 --- a/FencerJudgeBack/src/main/resources/static/testPlusOrMinusWebSocketHTML.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - Test WebSocket Match - - - - -

Test WebSocket Match

- -
Connexion...
- -
- - - -
- -
- - - -
- - - - - - - - - - diff --git a/FencerJudgeBack/test.http b/FencerJudgeBack/test.http deleted file mode 100644 index 6a6444e..0000000 --- a/FencerJudgeBack/test.http +++ /dev/null @@ -1,138 +0,0 @@ -### Get all matches -GET http://localhost:8080/matches/ - -### Get matches by players --> TODO -GET http://localhost:8080/matches/players/1/2 - -### Get matches by date -GET http://localhost:8080/matches/date/2025-06-02 - -### Get matches by country -GET http://localhost:8080/matches/country/France - -### Get matches by city -GET http://localhost:8080/matches/city/Paris - -### Get active matches -GET http://localhost:8080/matches/active - -### Get finished matches -GET http://localhost:8080/matches/over - -### Get not started matches -GET http://localhost:8080/matches/not-started - -### Get match by ID -GET http://localhost:8080/matches/2 - -### Create new match -POST http://localhost:8080/matches/create-match -Content-Type: application/json - -{ - "weapon": "Épée", - "country": "France", - "city": "Paris", - "player1ID": 1, - "player2ID": 2, - "refereeID": 1, - "score1": 0, - "score2": 0, - "date": "2025-06-02", - "state": "NOT STARTED" -} - -### Update match -PUT http://localhost:8080/matches/update-match/4 -Content-Type: application/json - -{ - - "weapon": "Épée", - "country": "France", - "city": "Paris", - "player1ID": 1, - "player2ID": 2, - "refereeID": 1, - "score1": 5, - "score2": 3, - "date": "2025-06-02", - "state": "OVER" -} - -### Delete match -DELETE http://localhost:8080/matches/delete-match/3 - -### Get all referees -GET http://localhost:8080/referees/ - -### Get referee by ID -GET http://localhost:8080/referees/1 - -### Get referees by name -GET http://localhost:8080/referees/name/Smith - -### Get referees by firstname -GET http://localhost:8080/referees/firstname/John - -### Get referees by qualification -GET http://localhost:8080/referees/qualification/NATIONAL - -### Create new referee -POST http://localhost:8080/referees/create-referee -Content-Type: application/json - -{ - "name": "Smith", - "firstName": "John", - "qualification": "NATIONAL" -} - -### Update referee -PUT http://localhost:8080/referees/update-referee/6 -Content-Type: application/json - -{ - "name": "Smith", - "firstName": "John", - "qualification": "INTERNATIONAL" -} - -### Delete referee -DELETE http://localhost:8080/referees/delete-referee/5 - -### Get all players -GET http://localhost:8080/players/ - -### Get player by ID -GET http://localhost:8080/players/10 - -### Get players by name -GET http://localhost:8080/players/name/Doe - -### Get players by firstname -GET http://localhost:8080/players/firstname/Jane - -### Create new player -POST http://localhost:8080/players/create-player -Content-Type: application/json - -{ - "name": "Doe", - "firstName": "Jane", - "club": "Paris Escrime Club" -} - -### Update player -PUT http://localhost:8080/players/update-player/10 -Content-Type: application/json - -{ - "name": "Doe", - "firstName": "Jane", - "club": "Un autre club" -} - -### Delete player -DELETE http://localhost:8080/players/delete-player/10 - diff --git a/FencerJudgeFront/src/app/app.module.ts b/FencerJudgeFront/src/app/app.module.ts index de9e710..4490d31 100644 --- a/FencerJudgeFront/src/app/app.module.ts +++ b/FencerJudgeFront/src/app/app.module.ts @@ -1,7 +1,6 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; -import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -30,7 +29,7 @@ import { MatchesDelComponent } from './components/match/matches-del/matches-del. SponsortComponent, MatchesDelComponent, ], - imports: [BrowserModule, AppRoutingModule, FormsModule, HttpClientModule], + imports: [BrowserModule, AppRoutingModule, FormsModule], providers: [], bootstrap: [AppComponent], }) diff --git a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.css b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.css index 93884ad..a76370e 100644 --- a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.css +++ b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.css @@ -1,52 +1,21 @@ -footer { - color: white; - background-color: var(--h-f-bg); - padding: 2rem; -} -.socialmedias { - display: flex; - justify-content: end; - align-items: center; -} - -.socialmedias a { - background-color: white; - text-decoration: none; - margin-left: 1rem; - height: 40px; - width: 40px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - padding: .6rem; - transition: background-color .4s ease-in-out; -} - -.socialmedias a:hover { - background-color: var(--primary-color); +.footer-gris { + background-color: #2c2c2c; /* Gris foncé personnalisé */ } .flag-bar { - height: 6px; - /* épaisseur du trait */ - width: 100%; - /* toute la largeur */ - background: linear-gradient(to right, - #0055a4 0%, - /* bleu */ - #0055a4 33.33%, - /* 1/3 */ - #fff 33.33%, - /* blanc */ - #fff 66.66%, - /* 2/3 */ - #ef4135 66.66%, - /* rouge */ - #ef4135 100%); + height: 6px; /* épaisseur du trait */ + width: 100%; /* toute la largeur */ + background: linear-gradient( + to right, + #0055a4 0%, /* bleu */ + #0055a4 33.33%, /* 1/3 */ + #fff 33.33%, /* blanc */ + #fff 66.66%, /* 2/3 */ + #ef4135 66.66%, /* rouge */ + #ef4135 100% + ); margin-bottom: 8px; - border-radius: 3px; - /* optionnel, pour arrondir les bords */ - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + border-radius: 3px; /* optionnel, pour arrondir les bords */ + box-shadow: 0 1px 3px rgba(0,0,0,0.1); } \ No newline at end of file diff --git a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.html b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.html index 68e8789..a110ff8 100644 --- a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.html +++ b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.html @@ -1,21 +1,48 @@ -
+
- FencerJudge + Angular Covid FencerJudge
-
+
Suivez-nous - - - - + + + +
- © FencerJudge - Tous droits réservés + © FencerJudge - Tous droits réservés
-
\ No newline at end of file +
diff --git a/FencerJudgeFront/src/app/components/essentials/header/header.component.css b/FencerJudgeFront/src/app/components/essentials/header/header.component.css index d7282b5..9df8f3d 100644 --- a/FencerJudgeFront/src/app/components/essentials/header/header.component.css +++ b/FencerJudgeFront/src/app/components/essentials/header/header.component.css @@ -1,7 +1,3 @@ -nav { - background-color: var(--h-f-bg); -} - .navbar { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } @@ -11,7 +7,6 @@ nav { font-size: 1.4rem; display: flex; align-items: center; - color: white; } .navbar-brand img { @@ -20,13 +15,11 @@ nav { } .nav-link { - text-transform: uppercase; - font-weight: 600; - color: white; transition: color 0.3s ease; } .nav-link:hover, .active-link { color: #ffcc00 !important; + font-weight: 600; } diff --git a/FencerJudgeFront/src/app/components/essentials/header/header.component.html b/FencerJudgeFront/src/app/components/essentials/header/header.component.html index d427b35..c8ae8e8 100644 --- a/FencerJudgeFront/src/app/components/essentials/header/header.component.html +++ b/FencerJudgeFront/src/app/components/essentials/header/header.component.html @@ -1,28 +1,52 @@ - diff --git a/FencerJudgeFront/src/app/components/home/home.component.css b/FencerJudgeFront/src/app/components/home/home.component.css index a09e6de..ddf7d9e 100644 --- a/FencerJudgeFront/src/app/components/home/home.component.css +++ b/FencerJudgeFront/src/app/components/home/home.component.css @@ -1,740 +1,568 @@ .match-card { - background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); - border: 2px solid var(--primary-color); - padding: 24px; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), - inset 0 1px 0 rgba(255, 255, 255, 0.1); - position: relative; - overflow: hidden; - transition: all 0.3s ease; - height: 90vh; - width: 100%; - display: flex; - flex-direction: column; - justify-content: space-between; + background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); + border: 2px solid #daa520; + padding: 24px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + position: relative; + overflow: hidden; + transition: all 0.3s ease; + height: 80vh; + width: 100%; } .match-card::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 2px; - background: linear-gradient(90deg, #daa520, var(--primary-color), #daa520); - background-size: 200% 100%; - animation: gradientShift 15s ease infinite; + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, #daa520, #ffd700, #daa520); + background-size: 200% 100%; + animation: gradientShift 15s ease infinite; } @keyframes gradientShift { - 0% { - background-position: 0% 50%; - } + 0% { + background-position: 0% 50%; + } - 50% { - background-position: 100% 50%; - } + 50% { + background-position: 100% 50%; + } - 100% { - background-position: 0% 50%; - } + 100% { + background-position: 0% 50%; + } } .match-card { - transform: translateY(-4px); - box-shadow: 0 12px 48px rgba(218, 165, 32, 0.2), 0 8px 32px rgba(0, 0, 0, 0.4); + transform: translateY(-4px); + box-shadow: 0 12px 48px rgba(218, 165, 32, 0.2), 0 8px 32px rgba(0, 0, 0, 0.4); } .match-background { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; } .background-image { - width: 100%; - height: 100%; - object-fit: cover; - filter: grayscale(30%) brightness(0.4) contrast(1.2); - transition: all 0.5s ease; + width: 100%; + height: 100%; + object-fit: cover; + filter: grayscale(30%) brightness(0.4) contrast(1.2); + transition: all 0.5s ease; } .match-card:hover .background-image { - filter: grayscale(10%) brightness(0.3) contrast(1.4); - transform: scale(1.05); + filter: grayscale(10%) brightness(0.3) contrast(1.4); + transform: scale(1.05); } .image-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(135deg, - rgba(26, 26, 46, 0.85) 0%, - rgba(0, 0, 0, 0.7) 50%, - rgba(22, 33, 62, 0.85) 100%); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient( + 135deg, + rgba(26, 26, 46, 0.85) 0%, + rgba(0, 0, 0, 0.7) 50%, + rgba(22, 33, 62, 0.85) 100% + ); } /* Header */ .match-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; } .match-weapon { - display: flex; - align-items: center; - gap: 8px; - color: #daa520; - font-weight: 600; + display: flex; + align-items: center; + gap: 8px; + color: #daa520; + font-weight: 600; } .weapon-type { - font-size: 14px; - text-transform: uppercase; - letter-spacing: 1px; + font-size: 14px; + text-transform: uppercase; + letter-spacing: 1px; } /* Status */ .match-status { - display: flex; - align-items: center; - gap: 8px; - padding: 6px 12px; - border-radius: 20px; - font-size: 12px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.5px; + display: flex; + align-items: center; + gap: 8px; + padding: 6px 12px; + border-radius: 20px; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; } .status-warning { - background: rgba(34, 197, 94, 0.2); - color: #22c55e; - border: 1px solid #22c55e; + background: rgba(34, 197, 94, 0.2); + color: #22c55e; + border: 1px solid #22c55e; } .status-success { - background: rgba(239, 68, 68, 0.2); - color: #ef4444; - border: 1px solid #ef4444; + background: rgba(239, 68, 68, 0.2); + color: #ef4444; + border: 1px solid #ef4444; } .status-secondary { - background: rgba(59, 130, 246, 0.2); - color: #3b82f6; - border: 1px solid #3b82f6; + background: rgba(59, 130, 246, 0.2); + color: #3b82f6; + border: 1px solid #3b82f6; } .status-dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: currentColor; - animation: pulse 2s infinite; + width: 8px; + height: 8px; + border-radius: 50%; + background: currentColor; + animation: pulse 2s infinite; } @keyframes pulse { - - 0%, - 100% { - opacity: 1; - } - - 50% { - opacity: 0.5; - } + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } } /* Versus Section */ .match-versus { - display: flex; - align-items: center; - justify-content: space-between; - margin: 24px 0; - position: relative; + display: flex; + align-items: center; + justify-content: space-between; + margin: 24px 0; + position: relative; } .fencer { - flex: 1; - text-align: center; - color: white; + flex: 1; + text-align: center; + color: white; } .fencer-name { - font-size: 18px; - font-weight: 700; - margin-bottom: 4px; - color: #daa520; + font-size: 18px; + font-weight: 700; + margin-bottom: 4px; + color: #daa520; } .fencer-club { - font-size: 12px; - color: #9ca3af; - margin-bottom: 8px; + font-size: 12px; + color: #9ca3af; + margin-bottom: 8px; } .score { - font-size: 32px; - font-weight: 900; - color: white; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); + font-size: 32px; + font-weight: 900; + color: white; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5); } .vs-divider { - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; - margin: 0 20px; + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + margin: 0 20px; } .vs-text { - font-size: 14px; - font-weight: 700; - color: #6b7280; - letter-spacing: 2px; + font-size: 14px; + font-weight: 700; + color: #6b7280; + letter-spacing: 2px; } .crossed-swords { - font-size: 20px; - opacity: 0.7; + font-size: 20px; + opacity: 0.7; } /* Details */ .match-details { - display: flex; - flex-direction: column; - gap: 12px; - margin-top: 20px; - padding-top: 20px; - border-top: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + flex-direction: column; + gap: 12px; + margin-top: 20px; + padding-top: 20px; + border-top: 1px solid rgba(255, 255, 255, 0.1); } .detail-item { - display: flex; - align-items: center; - gap: 12px; - font-size: 14px; + display: flex; + align-items: center; + gap: 12px; + font-size: 14px; } .detail-item .icon { - font-size: 16px; - width: 20px; - text-align: center; + font-size: 16px; + width: 20px; + text-align: center; } .detail-item .label { - color: #9ca3af; - font-weight: 500; - min-width: 60px; + color: #9ca3af; + font-weight: 500; + min-width: 60px; } .detail-item .value { - color: white; - font-weight: 600; + color: white; + font-weight: 600; } /* Responsive */ @media (max-width: 768px) { - .match-card { - padding: 16px; - } + .match-card { + padding: 16px; + } - .match-versus { - flex-direction: column; - gap: 16px; - } + .match-versus { + flex-direction: column; + gap: 16px; + } - .vs-divider { - transform: rotate(90deg); - margin: 0; - } + .vs-divider { + transform: rotate(90deg); + margin: 0; + } - .fencer { - width: 100%; - } + .fencer { + width: 100%; + } } .combat-arena { - margin-top: 24px; - background: linear-gradient(135deg, - rgba(220, 38, 38, 0.1) 0%, - rgba(0, 0, 0, 0.8) 50%, - rgba(255, 215, 0, 0.1) 100%); - border: 2px solid; - border-image: linear-gradient(45deg, #dc2626, var(--primary-color), #dc2626) 1; - border-radius: var(--border-radius); - padding: 20px; - position: relative; - overflow: hidden; + margin-top: 24px; + background: linear-gradient( + 135deg, + rgba(220, 38, 38, 0.1) 0%, + rgba(0, 0, 0, 0.8) 50%, + rgba(255, 215, 0, 0.1) 100% + ); + border: 2px solid; + border-image: linear-gradient(45deg, #dc2626, #ffd700, #dc2626) 1; + border-radius: 12px; + padding: 20px; + position: relative; + overflow: hidden; } .combat-arena::before { - content: ""; - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: repeating-conic-gradient(from 0deg at 50% 50%, - transparent 0deg 2deg, - rgba(220, 38, 38, 0.05) 2deg 4deg); - animation: rotate 20s linear infinite; - pointer-events: none; + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: repeating-conic-gradient( + from 0deg at 50% 50%, + transparent 0deg 2deg, + rgba(220, 38, 38, 0.05) 2deg 4deg + ); + animation: rotate 20s linear infinite; + pointer-events: none; } @keyframes rotate { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } /* Header Arena */ .arena-header { - display: flex; - align-items: center; - justify-content: center; - gap: 12px; - margin-bottom: 20px; - position: relative; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + margin-bottom: 20px; + position: relative; } .arena-title { - font-family: "Orbitron", monospace; - font-size: 16px; - font-weight: 900; - color: var(--primary-color); - letter-spacing: 3px; - text-shadow: 0 0 10px var(--primary-color), 0 0 20px var(--primary-color), 0 0 30px var(--primary-color); - animation: titleGlow 2s ease-in-out infinite alternate; + font-family: "Orbitron", monospace; + font-size: 16px; + font-weight: 900; + color: #ffd700; + letter-spacing: 3px; + text-shadow: 0 0 10px #ffd700, 0 0 20px #ffd700, 0 0 30px #ffd700; + animation: titleGlow 2s ease-in-out infinite alternate; } @keyframes titleGlow { - from { - text-shadow: 0 0 10px var(--primary-color), 0 0 20px var(--primary-color), 0 0 30px var(--primary-color); - } - - to { - text-shadow: 0 0 20px var(--primary-color), 0 0 30px var(--primary-color), 0 0 40px var(--primary-color); - } + from { + text-shadow: 0 0 10px #ffd700, 0 0 20px #ffd700, 0 0 30px #ffd700; + } + to { + text-shadow: 0 0 20px #ffd700, 0 0 30px #ffd700, 0 0 40px #ffd700; + } } .arena-pulse { - width: 10px; - height: 10px; - background: #dc2626; - border-radius: 50%; - position: relative; - animation: pulse-danger 1s infinite; + width: 10px; + height: 10px; + background: #dc2626; + border-radius: 50%; + position: relative; + animation: pulse-danger 1s infinite; } .arena-pulse::before { - content: ""; - position: absolute; - top: -5px; - left: -5px; - right: -5px; - bottom: -5px; - background: #dc2626; - border-radius: 50%; - opacity: 0.3; - animation: pulse-ring 1s infinite; + content: ""; + position: absolute; + top: -5px; + left: -5px; + right: -5px; + bottom: -5px; + background: #dc2626; + border-radius: 50%; + opacity: 0.3; + animation: pulse-ring 1s infinite; } @keyframes pulse-danger { - - 0%, - 100% { - transform: scale(1); - } - - 50% { - transform: scale(1.2); - } + 0%, + 100% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } } @keyframes pulse-ring { - 0% { - transform: scale(0.8); - opacity: 0.8; - } - - 100% { - transform: scale(2); - opacity: 0; - } + 0% { + transform: scale(0.8); + opacity: 0.8; + } + 100% { + transform: scale(2); + opacity: 0; + } } /* Combat Grid */ .combat-grid { - display: grid; - grid-template-columns: 1fr; - gap: 16px; + display: grid; + grid-template-columns: 1fr; + gap: 16px; } .combat-stat { - display: flex; - align-items: center; - gap: 16px; - padding: 16px; - background: linear-gradient(90deg, - rgba(0, 0, 0, 0.8) 0%, - rgba(26, 26, 46, 0.9) 50%, - rgba(0, 0, 0, 0.8) 100%); - border: 1px solid var(--primary-color); - border-radius: var(--border-radius); - position: relative; - transition: all 0.3s ease; - cursor: pointer; + display: flex; + align-items: center; + gap: 16px; + padding: 16px; + background: linear-gradient( + 90deg, + rgba(0, 0, 0, 0.8) 0%, + rgba(26, 26, 46, 0.9) 50%, + rgba(0, 0, 0, 0.8) 100% + ); + border: 1px solid rgba(255, 215, 0, 0.3); + border-radius: 8px; + position: relative; + transition: all 0.3s ease; + cursor: pointer; } .combat-stat:hover { - transform: translateX(8px); - border-color: var(--primary-color); - box-shadow: 0 4px 20px var(--primary-color), - inset 0 1px 0 rgba(255, 215, 0, 0.1); + transform: translateX(8px); + border-color: #ffd700; + box-shadow: 0 4px 20px rgba(255, 215, 0, 0.3), + inset 0 1px 0 rgba(255, 215, 0, 0.1); } /* Icons animés */ .stat-icon { - position: relative; - display: flex; - align-items: center; - justify-content: center; - width: 48px; - height: 48px; - font-size: 24px; + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 48px; + height: 48px; + font-size: 24px; } .location-radar { - position: absolute; - width: 40px; - height: 40px; - border: 2px solid #10b981; - border-radius: 50%; - border-top-color: transparent; - animation: radar-spin 2s linear infinite; + position: absolute; + width: 40px; + height: 40px; + border: 2px solid #10b981; + border-radius: 50%; + border-top-color: transparent; + animation: radar-spin 2s linear infinite; } .referee-badge { - position: absolute; - width: 35px; - height: 35px; - background: linear-gradient(45deg, var(--primary-color), #ffed4a); - clip-path: polygon(50% 0%, - 61% 35%, - 98% 35%, - 68% 57%, - 79% 91%, - 50% 70%, - 21% 91%, - 32% 57%, - 2% 35%, - 39% 35%); - animation: badge-pulse 3s ease-in-out infinite; + position: absolute; + width: 35px; + height: 35px; + background: linear-gradient(45deg, #ffd700, #ffed4a); + clip-path: polygon( + 50% 0%, + 61% 35%, + 98% 35%, + 68% 57%, + 79% 91%, + 50% 70%, + 21% 91%, + 32% 57%, + 2% 35%, + 39% 35% + ); + animation: badge-pulse 3s ease-in-out infinite; } .time-ring { - position: absolute; - width: 36px; - height: 36px; - border: 3px solid #dc2626; - border-radius: 50%; - border-left-color: transparent; - animation: time-tick 1s linear infinite; + position: absolute; + width: 36px; + height: 36px; + border: 3px solid #dc2626; + border-radius: 50%; + border-left-color: transparent; + animation: time-tick 1s linear infinite; } @keyframes radar-spin { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } @keyframes badge-pulse { - - 0%, - 100% { - transform: scale(1) rotate(0deg); - } - - 50% { - transform: scale(1.1) rotate(5deg); - } + 0%, + 100% { + transform: scale(1) rotate(0deg); + } + 50% { + transform: scale(1.1) rotate(5deg); + } } @keyframes time-tick { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } /* Content */ .stat-content { - flex: 1; - display: flex; - flex-direction: column; - gap: 2px; + flex: 1; + display: flex; + flex-direction: column; + gap: 2px; } .stat-label { - font-family: "Orbitron", monospace; - font-size: 10px; - font-weight: 700; - color: #6b7280; - letter-spacing: 1px; - text-transform: uppercase; + font-family: "Orbitron", monospace; + font-size: 10px; + font-weight: 700; + color: #6b7280; + letter-spacing: 1px; + text-transform: uppercase; } .stat-value { - font-size: 16px; - font-weight: 700; - color: white; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); + font-size: 16px; + font-weight: 700; + color: #ffffff; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); } .stat-sub { - font-size: 11px; - color: #9ca3af; - font-weight: 500; + font-size: 11px; + color: #9ca3af; + font-weight: 500; } /* Glows spécifiques */ .venue .stat-value { - color: #10b981; + color: #10b981; } - .referee .stat-value { - color: var(--primary-color); + color: #ffd700; } - .timing .stat-value { - color: #dc2626; + color: #dc2626; } .stat-glow { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - border-radius: 8px; - opacity: 0; - transition: opacity 0.3s ease; - pointer-events: none; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 8px; + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; } .combat-stat:hover .stat-glow { - opacity: 1; + opacity: 1; } .venue-glow { - box-shadow: inset 0 0 20px rgba(16, 185, 129, 0.2); + box-shadow: inset 0 0 20px rgba(16, 185, 129, 0.2); } - .referee-glow { - box-shadow: inset 0 0 20px rgba(255, 215, 0, 0.2); + box-shadow: inset 0 0 20px rgba(255, 215, 0, 0.2); } - .timing-glow { - box-shadow: inset 0 0 20px rgba(220, 38, 38, 0.2); + box-shadow: inset 0 0 20px rgba(220, 38, 38, 0.2); } /* Responsive */ @media (min-width: 768px) { - .combat-grid { - grid-template-columns: repeat(3, 1fr); - } + .combat-grid { + grid-template-columns: repeat(3, 1fr); + } - .combat-stat { - flex-direction: column; - text-align: center; - gap: 12px; - } - - .combat-stat:hover { - transform: translateY(-4px); - } -} - -/* Section Weapons */ -.section-header { - text-align: center; - margin-bottom: 3rem; - position: relative; -} - -.section-title { - font-size: 2.5rem; - font-weight: 300; - letter-spacing: 2px; - color: #333; - margin: 0; - position: relative; - display: inline-block; -} - -.section-title::after { - content: ''; - position: absolute; - bottom: -10px; - left: 50%; - transform: translateX(-50%); - width: 60px; - height: 2px; - background: var(--gradient-color); -} - -.weapons-container, -.diplomes-container { - display: flex; - flex-wrap: wrap; - gap: 20px; - justify-content: center; - padding: 20px; -} - -/* Card Weapon */ -.weapon-card, -.diplomes-card { - position: relative; - background-size: cover; - background-position: center; - border-radius: var(--border-radius); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); - width: 400px; - height: 500px; - color: white; - text-align: center; - overflow-y: auto; - overflow-x: hidden; - display: flex; + .combat-stat { flex-direction: column; - padding: 20px; - aspect-ratio: 16/9; - transition: box-shadow 0.3s ease; - /* Transition douce pour l'effet de lift */ + text-align: center; + gap: 12px; + } + + .combat-stat:hover { + transform: translateY(-4px); + } } - -.weapon-card:hover, -.diplomes-card:hover { - background-image: none !important; - box-shadow: - 0 8px 25px rgba(0, 0, 0, 0.3), - 0 0 20px rgba(212, 175, 55, 0.3), - inset 0 1px 0 rgba(255, 255, 255, 0.1); - transform: translateY(-2px); - /* Léger lift au hover */ - border: 2px solid var(--primary-color); - background: var(--card-gradient) !important; -} - -.weapon-card:before, -.diplomes-card:before { - content: ''; - position: absolute; - inset: 0; - background-image: inherit; - background-size: cover; - background-position: center; - filter: var(--blur-effect); - opacity: .6; - z-index: 1; - transition: var(--transition-smooth); - /* Courbe plus fluide */ -} - -.weapon-card:hover:before, -.diplomes-card:hover:before { - transform: scale(1.2); - /* Zoom uniquement sur l'image */ - filter: var(--blur-hover); - /* Moins de blur + plus lumineux au hover */ - opacity: .8; - /* Plus visible au hover */ - background-image: none; -} - -.weapon-card:hover:before, -.diplomes-card:hover:before { - animation: metalShine 2s ease-in-out infinite alternate; -} - -@keyframes metalShine { - 0% { - filter: brightness(1.1) contrast(1.2); - } - - 100% { - filter: brightness(1.3) contrast(1.4) saturate(1.1); - } -} - -.weapon-card *, -.diplomes-card * { - position: relative; - z-index: 2; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8); -} - -.weapon-card p { - color: white; - font-size: 0.95em; -} - -.diplomes-card h2, -.weapon-card h2 { - position: absolute; - opacity: 1; - transition: opacity 0.3s ease, transform 0.3s ease; - bottom: 50%; - left: 50%; - transform: translate(-50%, 50%); - /* Centrage parfait */ - margin: auto 0; - text-transform: uppercase; - font-size: 1.4em; -} - -.diplomes-card:hover h2, -.weapon-card:hover h2 { - opacity: 0; - transform: translate(-50%, 30%); - /* Glisse vers le haut en disparaissant */ -} - -.diplomes-card p, -.weapon-card p, -.weapon-card ul li, -.diplomes-card ul li { - text-align: start; - opacity: 0; - transform: translateY(-100%); - transition: opacity transform .6s ease-in-out; -} - -.diplomes-card:hover p, -.weapon-card:hover p, -.weapon-card:hover ul li, -.diplomes-card:hover ul li { - opacity: 1; - transform: translateY(0); -} \ No newline at end of file diff --git a/FencerJudgeFront/src/app/components/home/home.component.html b/FencerJudgeFront/src/app/components/home/home.component.html index aaf0494..37d0ba6 100644 --- a/FencerJudgeFront/src/app/components/home/home.component.html +++ b/FencerJudgeFront/src/app/components/home/home.component.html @@ -1,277 +1,114 @@
-
- Escrime -
+
+ Escrime +
+
+ +
+
+ ⚔️ + {{ latestMatch.weapon }} +
+
+ + {{ getMatchStateLabel(latestMatch.state) }} +
+
+ +
+
+
+ {{ player1?.name }} {{ player1?.firstName }} +
+
{{ player1?.club }}
+
{{ latestMatch.score1 }}
-
-
- ⚔️ - {{ latestMatch.weapon }} -
-
- - {{ getMatchStateLabel(latestMatch.state) }} -
+
+ VS +
⚔️
-
-
-
- {{ player1?.name }} {{ player1?.firstName }} -
-
{{ player1?.club }}
-
{{ latestMatch.score1 }}
-
+
+
+ {{ player2?.name }} {{ player2?.firstName }} +
+
{{ player2?.club }}
+
{{ latestMatch.score2 }}
+
+
-
- VS -
⚔️
-
- -
-
- {{ player2?.name }} {{ player2?.firstName }} -
-
{{ player2?.club }}
-
{{ latestMatch.score2 }}
-
+
+
+ ARENA COMBAT +
-
-
- ARENA COMBAT -
+
+
+
+
+ 🏛️
- -
-
-
-
- 🏛️ -
-
- BATTLEFIELD - {{ latestMatch.city }} - {{ latestMatch.country }} -
-
-
- -
-
-
- ⚖️ -
-
- COMBAT JUDGE - {{ referee?.name }} {{ referee?.firstName }} - OFFICIAL REFEREE -
-
-
- -
-
-
- -
-
- COMBAT START - {{ getTimeUntilMatch() }} - LIVE BATTLE -
-
-
-
-
- 🎯 -
-
- FUN FACT - - Saviez-vous que l'escrime est l'un des sports les plus anciens aux - Jeux Olympiques ? - - Inspiration et tradition au rendez-vous -
-
+
+ BATTLEFIELD + {{ latestMatch.city }} + {{ latestMatch.country }}
+
+
+ +
+
+
+ ⚖️ +
+
+ COMBAT JUDGE + {{ referee?.name }} {{ referee?.firstName }} + OFFICIAL REFEREE +
+
+
+ +
+
+
+ +
+
+ COMBAT START + {{ getTimeUntilMatch() }} + LIVE BATTLE +
+
+
+
+
+ 🎯 +
+
+ FUN FACT + + Saviez-vous que l'escrime est l'un des sports les plus anciens aux + Jeux Olympiques ? + + Inspiration et tradition au rendez-vous +
+
+
-
-
-

Les Armes

-
- -
-
-

Épée

-
    -
  • - Le but de l’épée est de toucher le premier son adversaire avec la pointe de la lame. - La priorité ne s’applique pas comme au fleuret, - c’est-à-dire que les deux épéistes peuvent toucher simultanément : le point leur sera accordé. -
  • -
  • - Toutes les parties du corps comptent, des pieds jusqu’au masque. - C’est le premier qui touche l’autre qui marque le point. -
  • -
  • - Les touches ne sont accordées que si elles sont portées avec la pointe de la lame. - Les touches doivent être portées à l’adversaire avec une pression suffisante. -
  • -
-
- -
-

Fleuret

-
    -
  • - Les touches sont comptabilisées par un système électrique qui détecte les touches sur la veste des escrimeurs. -
  • -
  • - Pour marquer un point, la touche doit être portée sur la partie valable du corps de l’adversaire, qui est délimitée par les règles de l’escrime. - La zone valable est le tronc, ce qui exclut les membres et la tête. -
  • -
  • - Les touches simultanées ne sont pas prises en compte, c’est-à-dire que si les deux escrimeurs touchent leur adversaire en même temps, - l’arbitre dira lequel des deux avait la « priorité » pour pouvoir attribuer le point. -
  • -
-
- -
-

Sabre

-
    -
  • - Le sabre est une arme qui permet des touches rapides et dynamiques. - Les touches sont marquées avec le tranchant et le bout de la lame. -
  • -
  • - Les touches sont valides sur tout le haut du corps, au-dessus de la ceinture jusqu’à la tête. - Les touches sont déterminées par des capteurs électriques sur la cuirasse et le masque de l’escrimeur. -
  • -
  • - Si les deux tireurs touchent en même temps, c’est l’attaquant qui a la priorité du point, sauf si l’adversaire parade et riposte. - Cette règle est quasiment identique à celle du fleuret. -
  • -
-
- -
-

Sabre Laser

-

Les combats au sabre laser suivent généralement des règles similaires à celles de l’escrime artistique. - La pratique du sabre laser se décline en trois disciplines complémentaires : -

-
    -
  • - Combat sportif : Les escrimeurs s’affrontent en duel réglementé dans une arène. - Ils doivent toucher l’adversaire avec leur sabre laser pour accumuler des points en un temps donné. - Le combat sportif exige de la stratégie, de la rapidité et une maîtrise technique. -
  • -
  • - Combat chorégraphié : Cette discipline se pratique à deux ou en groupe. - Les participants exécutent ensemble un combat sous forme de mise en scène préalablement répétée, souvent accompagnée d’une musique appropriée. - Le sens du spectacle prime, et les mouvements doivent être précis et spectaculaires. -
  • -
  • - Kata : Inspiré des arts martiaux, le kata consiste à reproduire un enchaînement de mouvements codifiés seul ou face à un adversaire imaginaire. - Il vise à progresser techniquement et exige rigueur, précision et patience. -
  • -
-
- -
-
- -
-
-

Les diplômes d'arbitrage

-
- -
-
-

départemental

-

Ce diplôme est décemé par la CAI ou la CRA dont - dépend l'arbitre :

-
    -
  • - Âge minimum : 14 ans. -
  • -
  • - Ouvre droit à arbitrer toutes les compétitions - organisées dans le cadre du comité interdépartemental - et/ou du comité régional dont dépend l'arbitre (sous - réserve de l'avis de la CRA dont dépend l'arbitre). -
  • -
  • - Titulaire d'un carton BLANC qui permet d'arrêter un - match à n'importe quel moment pour demander une - assistance du DT et/ou de l'organisateur de la - compétition. Le rôle pédagogique du DT et/ou de - l'organisateur est primordial dans l'accompagnement - des jeunes arbitres. -
  • -
-
- -
-

régional

-

Ce diplôme est décerné par la CRA dont dépend - l'arbitre :

-
    -
  • - Âge minimum : 16 ans -
  • -
  • - Il ouvre droit à arbitrer toutes les compétitions - organisées dans le cadre du Comité régional, -
  • -
  • - Les circuits nationaux, -
  • -
  • - La Fête des Jeunes, -
  • -
  • - Des dérogations ponctuelles peuvent faire l'objet d'une - circulaire. -
  • -
-
- -
-

national

-

Ce diplôme est décerné par la CNA (Commission - Nationale Arbitrage) :

-
    -
  • • Âge minimum : 18 ans
  • -
  • Il ouvre droit à arbitrer toutes les compétitions - organisées dans le cadre du Comité régional,
  • -
  • Les circuits nationaux,
  • -
  • La Fête des Jeunes, les championnats de France M17, - M20, Séniors et Vétérans sur convocation de la CNN
  • -
  • Les circuits européens M17 et U23 organisés sur le - territoire français et à l'étranger.
  • -
-
- -
-

international

-

Ce diplôme est décerné par la Fédération - Internationale d'Escrime (FIE).

-
    -
  • Âge minimum : 20 ans
  • -
  • Il ouvre droit à arbitrer toutes les compétitions. Les - arbitres qui figurent sur la liste restreinte de la FIE - doivent arbitrer des compétitions nationales séniors et - être la référence de notre corps arbitral.
  • -
-
- -
-
- - \ No newline at end of file + diff --git a/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.html b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.html index 6ce2a75..2f926a0 100644 --- a/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.html +++ b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.html @@ -29,7 +29,7 @@
diff --git a/FencerJudgeFront/src/app/interfaces/matches.ts b/FencerJudgeFront/src/app/interfaces/matches.ts index 1437a58..26c6767 100644 --- a/FencerJudgeFront/src/app/interfaces/matches.ts +++ b/FencerJudgeFront/src/app/interfaces/matches.ts @@ -1,7 +1,7 @@ export enum MatchState { - ONGOING = 0, - OVER = 1, - NOT_STARTED = 2, + ONGOING = 1, + OVER = 2, + NOT_STARTED = 3, } export interface Matches { diff --git a/FencerJudgeFront/src/app/templates/sponsort/sponsort.component.html b/FencerJudgeFront/src/app/templates/sponsort/sponsort.component.html index dd13b28..89ce529 100644 --- a/FencerJudgeFront/src/app/templates/sponsort/sponsort.component.html +++ b/FencerJudgeFront/src/app/templates/sponsort/sponsort.component.html @@ -20,25 +20,4 @@ src="https://www.prieur-sports.us/assets/images/prieur-sport-fencing-equipment.png" />
-
- - - - - - - -
diff --git a/FencerJudgeFront/src/assets/departements.jpg b/FencerJudgeFront/src/assets/departements.jpg deleted file mode 100644 index 787fc6b..0000000 Binary files a/FencerJudgeFront/src/assets/departements.jpg and /dev/null differ diff --git a/FencerJudgeFront/src/assets/epee_escrime.jpg b/FencerJudgeFront/src/assets/epee_escrime.jpg deleted file mode 100644 index 96b8b68..0000000 Binary files a/FencerJudgeFront/src/assets/epee_escrime.jpg and /dev/null differ diff --git a/FencerJudgeFront/src/assets/fleuret_escrime.jpg b/FencerJudgeFront/src/assets/fleuret_escrime.jpg deleted file mode 100644 index 95b6957..0000000 Binary files a/FencerJudgeFront/src/assets/fleuret_escrime.jpg and /dev/null differ diff --git a/FencerJudgeFront/src/assets/international.jpg b/FencerJudgeFront/src/assets/international.jpg deleted file mode 100644 index 3447190..0000000 Binary files a/FencerJudgeFront/src/assets/international.jpg and /dev/null differ diff --git a/FencerJudgeFront/src/assets/nationnal.jpg b/FencerJudgeFront/src/assets/nationnal.jpg deleted file mode 100644 index a9ed1a7..0000000 Binary files a/FencerJudgeFront/src/assets/nationnal.jpg and /dev/null differ diff --git a/FencerJudgeFront/src/assets/region.png b/FencerJudgeFront/src/assets/region.png deleted file mode 100644 index 3c6daa9..0000000 Binary files a/FencerJudgeFront/src/assets/region.png and /dev/null differ diff --git a/FencerJudgeFront/src/assets/sabre_escrime.jpg b/FencerJudgeFront/src/assets/sabre_escrime.jpg deleted file mode 100644 index 3aa26df..0000000 Binary files a/FencerJudgeFront/src/assets/sabre_escrime.jpg and /dev/null differ diff --git a/FencerJudgeFront/src/assets/sabre_laser_escrime.jpg b/FencerJudgeFront/src/assets/sabre_laser_escrime.jpg deleted file mode 100644 index fc13894..0000000 Binary files a/FencerJudgeFront/src/assets/sabre_laser_escrime.jpg and /dev/null differ diff --git a/FencerJudgeFront/src/styles.css b/FencerJudgeFront/src/styles.css index 5374057..c44aac6 100644 --- a/FencerJudgeFront/src/styles.css +++ b/FencerJudgeFront/src/styles.css @@ -2,32 +2,3 @@ .bg-primary-custom { background-color: #414141; } - -/* Colors */ -:root { - --primary-color: rgba(212, 175, 55, 0.6); - --gradient-color: linear-gradient(90deg, #d4af37, var(--primary-color)); - --card-gradient: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%), - linear-gradient(135deg, - rgba(64, 64, 64, 0.95) 0%, - rgba(32, 32, 32, 0.98) 50%, - rgba(16, 16, 16, 0.95) 100%); - --h-f-bg: #2c2c2c; -} - -/* Filters */ -:root { - --blur-effect: blur(10px) brightness(1.1) contrast(1.1); - --blur-hover: blur(8px) brightness(1.3); -} - -/* Transitions */ -:root { - --transition-smooth: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); - --transition-quick: all 0.3s ease; -} - -/* Borders */ -:root { - --border-radius: 12px; -} \ No newline at end of file diff --git a/db.lock.db b/db.lock.db new file mode 100644 index 0000000..072e750 --- /dev/null +++ b/db.lock.db @@ -0,0 +1,6 @@ +#FileLock +#Mon Jun 02 17:40:34 CEST 2025 +hostName=ExostFlash +id=197313393c88a931fa21bf5ce1281b7253870b00683 +method=file +server=192.167.2.100\:54366 diff --git a/db.mv.db b/db.mv.db deleted file mode 100644 index 13d536b..0000000 Binary files a/db.mv.db and /dev/null differ diff --git a/db.trace.db b/db.trace.db deleted file mode 100644 index 016cc9c..0000000 --- a/db.trace.db +++ /dev/null @@ -1,48 +0,0 @@ -2025-06-03 09:54:12.514185+02:00 database: close -org.h2.message.DbException: IO Exception: "Closing" -IO Exception: "Closing" [90028-232] - at org.h2.message.DbException.get(DbException.java:212) - at org.h2.mvstore.db.Store.close(Store.java:374) - at org.h2.engine.Database.closeOpenFilesAndUnlock(Database.java:1292) - at org.h2.engine.Database.closeImpl(Database.java:1254) - at org.h2.engine.Database.close(Database.java:1173) - at org.h2.engine.Database.onShutdown(Database.java:1158) - at org.h2.engine.OnExitDatabaseCloser.onShutdown(OnExitDatabaseCloser.java:85) - at org.h2.engine.OnExitDatabaseCloser.run(OnExitDatabaseCloser.java:114) -Caused by: org.h2.jdbc.JdbcSQLNonTransientException: IO Exception: "Closing" -IO Exception: "Closing" [90028-232] - at org.h2.message.DbException.getJdbcSQLException(DbException.java:566) - at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) - ... 8 more -Caused by: org.h2.mvstore.MVStoreException: Reading from file sun.nio.ch.FileChannelImpl@1baeb921 failed at 15775 (length -1), read 0, remaining 24 [2.3.232/1] - at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996) - at org.h2.mvstore.DataUtils.readFully(DataUtils.java:455) - at org.h2.mvstore.FileStore.readFully(FileStore.java:721) - at org.h2.mvstore.SingleFileStore.readFully(SingleFileStore.java:60) - at org.h2.mvstore.SingleFileStore.readFully(SingleFileStore.java:28) - at org.h2.mvstore.SFChunk.readFully(SFChunk.java:35) - at org.h2.mvstore.Chunk.readToC(Chunk.java:496) - at org.h2.mvstore.FileStore.getToC(FileStore.java:2070) - at org.h2.mvstore.FileStore.rewriteChunks(FileStore.java:1913) - at org.h2.mvstore.FileStore.compactRewrite(FileStore.java:1901) - at org.h2.mvstore.FileStore.rewriteChunks(FileStore.java:1862) - at org.h2.mvstore.FileStore.lambda$compact$0(FileStore.java:879) - at org.h2.mvstore.MVStore.tryExecuteUnderStoreLock(MVStore.java:937) - at org.h2.mvstore.FileStore.compact(FileStore.java:879) - at org.h2.mvstore.RandomAccessStore.compactStore(RandomAccessStore.java:441) - at org.h2.mvstore.FileStore.compactStore(FileStore.java:890) - at org.h2.mvstore.FileStore.stop(FileStore.java:275) - at org.h2.mvstore.MVStore.closeStore(MVStore.java:693) - at org.h2.mvstore.MVStore.close(MVStore.java:643) - at org.h2.mvstore.db.Store.close(Store.java:364) - ... 6 more -Caused by: java.io.IOException: Le périphérique n’est pas prêt - at java.base/sun.nio.ch.FileDispatcherImpl.pread0(Native Method) - at java.base/sun.nio.ch.FileDispatcherImpl.pread(FileDispatcherImpl.java:67) - at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:338) - at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:306) - at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:283) - at java.base/sun.nio.ch.FileChannelImpl.readInternal(FileChannelImpl.java:984) - at java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:964) - at org.h2.mvstore.DataUtils.readFully(DataUtils.java:441) - ... 24 more diff --git a/jpe-controle.iml b/jpe-controle.iml index b081e58..9a5cfce 100644 --- a/jpe-controle.iml +++ b/jpe-controle.iml @@ -4,6 +4,5 @@ - \ No newline at end of file