From b848e0cede1a6b82bba91ed126f95ccdd754fdc4 Mon Sep 17 00:00:00 2001 From: dahoud Date: Tue, 7 Oct 2025 21:24:57 +0000 Subject: [PATCH] COMPLETE: Freya Theme + OIDC Integration for Web Client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ FREYA THEME 5.0.0 INTEGRATION: - Install freya-theme-5.0.0-jakarta.jar to Maven local repository - Copy all Freya layout resources (23 files: CSS, JS, images, icons) - Copy and adapt Freya templates (6 files: template, menu, topbar, footer, config, rightpanel) - Activate Freya dependency in pom.xml with Jakarta classifier ✅ OIDC AUTHENTICATION COMPLETE: - AuthBean: Complete OIDC integration with SecurityIdentity, OidcSession, IdToken - NavigationBean: Role-based navigation with access control - GuestPreferences: Freya theme management (light/dark mode, menu themes) - Configuration: Port 8081, API URL localhost:8082, Keycloak OIDC client ✅ FREYA UI PAGES CREATED: - index.xhtml: Landing page + authenticated dashboard with dual view - pages/dashboard.xhtml: Main dashboard with statistics, quick actions, activity timeline - pages/profile.xhtml: User profile with OIDC session details and role management - pages/clients.xhtml: Client management interface with demo data and statistics ✅ GBCM BRANDING & CUSTOMIZATION: - Template title: 'GBCM - Global Business Consulting & Management' - Menu structure: Dashboard, Clients, Coaches, Sessions, Workshops, Administration - Topbar: User profile with avatar, full name, email, logout functionality - Role-based menu visibility and access control ✅ TECHNICAL FEATURES: - Hot reload active on port 8081 - OIDC authentication flow working with Keycloak - Token management and session handling - Role-based UI rendering (ADMIN, MANAGER, COACH, CLIENT, PROSPECT) - Freya theme preferences (light/dark mode switching) - Responsive design with PrimeFlex grid system 🎯 TASK 1 STATUS: COMPLETE Web client with Freya Theme 5.0.0 and OIDC authentication fully integrated and tested. --- pom.xml | 6 +- .../gbcm/client/beans/GuestPreferences.java | 226 + .../com/gbcm/client/beans/NavigationBean.java | 272 ++ .../com/gbcm/client/beans/auth/AuthBean.java | 238 + .../gbcm/client/service/GBCMServerClient.java | 8 +- src/main/resources/application.properties | 2 +- .../WEB-INF/freya-templates/config.xhtml | 93 + .../WEB-INF/freya-templates/footer.xhtml | 56 + .../webapp/WEB-INF/freya-templates/menu.xhtml | 105 + .../WEB-INF/freya-templates/rightpanel.xhtml | 284 ++ .../WEB-INF/freya-templates/template.xhtml | 54 + .../WEB-INF/freya-templates/topbar.xhtml | 102 + src/main/webapp/index.xhtml | 157 +- src/main/webapp/pages/clients.xhtml | 181 + src/main/webapp/pages/dashboard.xhtml | 202 + src/main/webapp/pages/profile.xhtml | 170 + .../freya-layout/css/layout-dark.css | 4257 +++++++++++++++++ .../freya-layout/css/layout-dark.scss | 5 + .../freya-layout/css/layout-light.css | 4257 +++++++++++++++++ .../freya-layout/css/layout-light.scss | 5 + .../freya-layout/css/primeflex-v2.min.css | 1 + .../freya-layout/css/primeflex.min.css | 1 + .../resources/freya-layout/css/primeicons.css | 1017 ++++ .../freya-layout/icons/primeicons.eot | Bin 0 -> 66820 bytes .../freya-layout/icons/primeicons.svg | 270 ++ .../freya-layout/icons/primeicons.ttf | Bin 0 -> 66644 bytes .../freya-layout/icons/primeicons.woff | Bin 0 -> 66720 bytes .../images/avatar-profilemenu.png | Bin 0 -> 1249 bytes .../resources/freya-layout/images/favicon.ico | Bin 0 -> 15086 bytes .../freya-layout/images/logo-freya-single.svg | 9 + .../freya-layout/images/logo-freya-white.svg | 14 + .../freya-layout/images/logo-freya.svg | 40 + .../freya-layout/images/pages/asset-404.svg | 9 + .../images/pages/asset-access.svg | 9 + .../freya-layout/images/pages/asset-error.svg | 9 + .../images/pages/asset-landing-header.jpg | Bin 0 -> 844761 bytes .../freya-layout/images/pages/search.png | Bin 0 -> 788 bytes .../resources/freya-layout/js/layout.js | 879 ++++ .../webapp/resources/freya-layout/js/prism.js | 10 + 39 files changed, 12897 insertions(+), 51 deletions(-) create mode 100644 src/main/java/com/gbcm/client/beans/GuestPreferences.java create mode 100644 src/main/java/com/gbcm/client/beans/NavigationBean.java create mode 100644 src/main/java/com/gbcm/client/beans/auth/AuthBean.java create mode 100644 src/main/webapp/WEB-INF/freya-templates/config.xhtml create mode 100644 src/main/webapp/WEB-INF/freya-templates/footer.xhtml create mode 100644 src/main/webapp/WEB-INF/freya-templates/menu.xhtml create mode 100644 src/main/webapp/WEB-INF/freya-templates/rightpanel.xhtml create mode 100644 src/main/webapp/WEB-INF/freya-templates/template.xhtml create mode 100644 src/main/webapp/WEB-INF/freya-templates/topbar.xhtml create mode 100644 src/main/webapp/pages/clients.xhtml create mode 100644 src/main/webapp/pages/dashboard.xhtml create mode 100644 src/main/webapp/pages/profile.xhtml create mode 100644 src/main/webapp/resources/freya-layout/css/layout-dark.css create mode 100644 src/main/webapp/resources/freya-layout/css/layout-dark.scss create mode 100644 src/main/webapp/resources/freya-layout/css/layout-light.css create mode 100644 src/main/webapp/resources/freya-layout/css/layout-light.scss create mode 100644 src/main/webapp/resources/freya-layout/css/primeflex-v2.min.css create mode 100644 src/main/webapp/resources/freya-layout/css/primeflex.min.css create mode 100644 src/main/webapp/resources/freya-layout/css/primeicons.css create mode 100644 src/main/webapp/resources/freya-layout/icons/primeicons.eot create mode 100644 src/main/webapp/resources/freya-layout/icons/primeicons.svg create mode 100644 src/main/webapp/resources/freya-layout/icons/primeicons.ttf create mode 100644 src/main/webapp/resources/freya-layout/icons/primeicons.woff create mode 100644 src/main/webapp/resources/freya-layout/images/avatar-profilemenu.png create mode 100644 src/main/webapp/resources/freya-layout/images/favicon.ico create mode 100644 src/main/webapp/resources/freya-layout/images/logo-freya-single.svg create mode 100644 src/main/webapp/resources/freya-layout/images/logo-freya-white.svg create mode 100644 src/main/webapp/resources/freya-layout/images/logo-freya.svg create mode 100644 src/main/webapp/resources/freya-layout/images/pages/asset-404.svg create mode 100644 src/main/webapp/resources/freya-layout/images/pages/asset-access.svg create mode 100644 src/main/webapp/resources/freya-layout/images/pages/asset-error.svg create mode 100644 src/main/webapp/resources/freya-layout/images/pages/asset-landing-header.jpg create mode 100644 src/main/webapp/resources/freya-layout/images/pages/search.png create mode 100644 src/main/webapp/resources/freya-layout/js/layout.js create mode 100644 src/main/webapp/resources/freya-layout/js/prism.js diff --git a/pom.xml b/pom.xml index e3a65c2..23eb425 100644 --- a/pom.xml +++ b/pom.xml @@ -73,15 +73,13 @@ jakarta - - - org.primefaces + org.primefaces.themes freya ${freya.version} jakarta - --> diff --git a/src/main/java/com/gbcm/client/beans/GuestPreferences.java b/src/main/java/com/gbcm/client/beans/GuestPreferences.java new file mode 100644 index 0000000..0fa50e3 --- /dev/null +++ b/src/main/java/com/gbcm/client/beans/GuestPreferences.java @@ -0,0 +1,226 @@ +package com.gbcm.client.beans; + +import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Named; +import java.io.Serializable; + +/** + * Bean pour les préférences d'affichage du template Freya + * Compatible avec le template Freya 5.0.0 original + * + * @author GBCM Team + * @version 1.0.0 + * @since 2025-01-01 + */ +@Named("guestPreferences") +@SessionScoped +public class GuestPreferences implements Serializable { + + private String layout = "layout-light"; + private String menuTheme = "light"; + private String topbarTheme = "light"; + private String menuMode = "static"; + private String inputStyleClass = ""; + private boolean lightLogo = false; + + /** + * Récupère le layout CSS (light/dark) + * + * @return Nom du fichier CSS de layout + */ + public String getLayout() { + return layout; + } + + /** + * Définit le layout CSS + * + * @param layout Nom du layout (layout-light ou layout-dark) + */ + public void setLayout(String layout) { + this.layout = layout; + // Ajuster le logo selon le thème + this.lightLogo = "layout-dark".equals(layout); + } + + /** + * Récupère le thème du menu + * + * @return Thème du menu (light/dark) + */ + public String getMenuTheme() { + return menuTheme; + } + + /** + * Définit le thème du menu + * + * @param menuTheme Thème du menu + */ + public void setMenuTheme(String menuTheme) { + this.menuTheme = menuTheme; + } + + /** + * Récupère le thème de la topbar + * + * @return Thème de la topbar (light/dark) + */ + public String getTopbarTheme() { + return topbarTheme; + } + + /** + * Définit le thème de la topbar + * + * @param topbarTheme Thème de la topbar + */ + public void setTopbarTheme(String topbarTheme) { + this.topbarTheme = topbarTheme; + } + + /** + * Récupère le mode du menu + * + * @return Mode du menu (static/overlay/horizontal) + */ + public String getMenuMode() { + return menuMode; + } + + /** + * Définit le mode du menu + * + * @param menuMode Mode du menu + */ + public void setMenuMode(String menuMode) { + this.menuMode = menuMode; + } + + /** + * Récupère la classe CSS pour le style des inputs + * + * @return Classe CSS + */ + public String getInputStyleClass() { + return inputStyleClass; + } + + /** + * Définit la classe CSS pour le style des inputs + * + * @param inputStyleClass Classe CSS + */ + public void setInputStyleClass(String inputStyleClass) { + this.inputStyleClass = inputStyleClass; + } + + /** + * Indique si le logo light doit être utilisé + * + * @return true pour le logo light + */ + public boolean isLightLogo() { + return lightLogo; + } + + /** + * Définit l'utilisation du logo light + * + * @param lightLogo true pour utiliser le logo light + */ + public void setLightLogo(boolean lightLogo) { + this.lightLogo = lightLogo; + } + + /** + * Bascule vers le thème sombre + */ + public void switchToDark() { + setLayout("layout-dark"); + setMenuTheme("dark"); + setTopbarTheme("dark"); + } + + /** + * Bascule vers le thème clair + */ + public void switchToLight() { + setLayout("layout-light"); + setMenuTheme("light"); + setTopbarTheme("light"); + } + + /** + * Vérifie si le thème sombre est actif + * + * @return true si thème sombre + */ + public boolean isDarkTheme() { + return "layout-dark".equals(layout); + } + + /** + * Vérifie si le thème clair est actif + * + * @return true si thème clair + */ + public boolean isLightTheme() { + return "layout-light".equals(layout); + } + + /** + * Récupère la classe CSS complète pour le body + * + * @return Classes CSS combinées + */ + public String getBodyStyleClass() { + StringBuilder sb = new StringBuilder(); + sb.append(inputStyleClass); + if (isDarkTheme()) { + sb.append(" dark-theme"); + } + return sb.toString().trim(); + } + + /** + * Récupère l'icône pour le bouton de basculement de thème + * + * @return Classe d'icône + */ + public String getThemeToggleIcon() { + return isDarkTheme() ? "pi pi-sun" : "pi pi-moon"; + } + + /** + * Récupère le texte pour le bouton de basculement de thème + * + * @return Texte du bouton + */ + public String getThemeToggleText() { + return isDarkTheme() ? "Mode Clair" : "Mode Sombre"; + } + + /** + * Bascule entre les thèmes clair et sombre + */ + public void toggleTheme() { + if (isDarkTheme()) { + switchToLight(); + } else { + switchToDark(); + } + } + + /** + * Réinitialise les préférences aux valeurs par défaut + */ + public void resetToDefaults() { + layout = "layout-light"; + menuTheme = "light"; + topbarTheme = "light"; + menuMode = "static"; + inputStyleClass = ""; + lightLogo = false; + } +} diff --git a/src/main/java/com/gbcm/client/beans/NavigationBean.java b/src/main/java/com/gbcm/client/beans/NavigationBean.java new file mode 100644 index 0000000..0314f1a --- /dev/null +++ b/src/main/java/com/gbcm/client/beans/NavigationBean.java @@ -0,0 +1,272 @@ +package com.gbcm.client.beans; + +import com.gbcm.client.beans.auth.AuthBean; +import jakarta.enterprise.context.SessionScoped; +import jakarta.faces.context.FacesContext; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; + +/** + * Bean JSF pour la gestion de la navigation dans l'interface GBCM + * + * @author GBCM Team + * @version 1.0.0 + * @since 2025-01-01 + */ +@Named("navigationBean") +@SessionScoped +public class NavigationBean implements Serializable { + + private static final Logger logger = LoggerFactory.getLogger(NavigationBean.class); + + @Inject + AuthBean authBean; + + private String currentPage = "dashboard"; + + /** + * Navigation vers le dashboard + * + * @return Outcome de navigation + */ + public String goToDashboard() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + currentPage = "dashboard"; + logger.debug("Navigation vers le dashboard"); + return "/pages/dashboard?faces-redirect=true"; + } + + /** + * Navigation vers la gestion des utilisateurs + * + * @return Outcome de navigation + */ + public String goToUsers() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + if (!authBean.isAdmin() && !authBean.isManager()) { + logger.warn("Accès refusé à la gestion des utilisateurs pour: {}", authBean.getUsername()); + return "/pages/access-denied?faces-redirect=true"; + } + + currentPage = "users"; + logger.debug("Navigation vers la gestion des utilisateurs"); + return "/pages/users?faces-redirect=true"; + } + + /** + * Navigation vers la gestion des clients + * + * @return Outcome de navigation + */ + public String goToClients() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + currentPage = "clients"; + logger.debug("Navigation vers la gestion des clients"); + return "/pages/clients?faces-redirect=true"; + } + + /** + * Navigation vers la gestion des coaches + * + * @return Outcome de navigation + */ + public String goToCoaches() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + currentPage = "coaches"; + logger.debug("Navigation vers la gestion des coaches"); + return "/pages/coaches?faces-redirect=true"; + } + + /** + * Navigation vers la gestion des ateliers + * + * @return Outcome de navigation + */ + public String goToWorkshops() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + currentPage = "workshops"; + logger.debug("Navigation vers la gestion des ateliers"); + return "/pages/workshops?faces-redirect=true"; + } + + /** + * Navigation vers les sessions de coaching + * + * @return Outcome de navigation + */ + public String goToSessions() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + currentPage = "sessions"; + logger.debug("Navigation vers les sessions de coaching"); + return "/pages/sessions?faces-redirect=true"; + } + + /** + * Navigation vers le profil utilisateur + * + * @return Outcome de navigation + */ + public String goToProfile() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + currentPage = "profile"; + logger.debug("Navigation vers le profil utilisateur"); + return "/pages/profile?faces-redirect=true"; + } + + /** + * Navigation vers les paramètres (admin seulement) + * + * @return Outcome de navigation + */ + public String goToSettings() { + if (!authBean.isAuthenticated()) { + return authBean.login(); + } + + if (!authBean.isAdmin()) { + logger.warn("Accès refusé aux paramètres pour: {}", authBean.getUsername()); + return "/pages/access-denied?faces-redirect=true"; + } + + currentPage = "settings"; + logger.debug("Navigation vers les paramètres"); + return "/pages/settings?faces-redirect=true"; + } + + /** + * Vérifie si une page est active + * + * @param page Nom de la page + * @return true si la page est active + */ + public boolean isPageActive(String page) { + return page.equals(currentPage); + } + + /** + * Récupère la classe CSS pour un élément de menu + * + * @param page Nom de la page + * @return Classe CSS + */ + public String getMenuItemClass(String page) { + return isPageActive(page) ? "ui-state-active" : ""; + } + + /** + * Récupère le titre de la page courante + * + * @return Titre de la page + */ + public String getPageTitle() { + switch (currentPage) { + case "dashboard": + return "Tableau de Bord"; + case "users": + return "Gestion des Utilisateurs"; + case "clients": + return "Gestion des Clients"; + case "coaches": + return "Gestion des Coaches"; + case "workshops": + return "Gestion des Ateliers"; + case "sessions": + return "Sessions de Coaching"; + case "profile": + return "Mon Profil"; + case "settings": + return "Paramètres"; + default: + return "GBCM"; + } + } + + /** + * Récupère l'icône de la page courante + * + * @return Classe d'icône FontAwesome + */ + public String getPageIcon() { + switch (currentPage) { + case "dashboard": + return "pi pi-chart-line"; + case "users": + return "pi pi-users"; + case "clients": + return "pi pi-briefcase"; + case "coaches": + return "pi pi-user-plus"; + case "workshops": + return "pi pi-calendar"; + case "sessions": + return "pi pi-comments"; + case "profile": + return "pi pi-user"; + case "settings": + return "pi pi-cog"; + default: + return "pi pi-home"; + } + } + + /** + * Vérifie si l'utilisateur peut accéder à une page + * + * @param page Nom de la page + * @return true si l'accès est autorisé + */ + public boolean canAccessPage(String page) { + if (!authBean.isAuthenticated()) { + return false; + } + + switch (page) { + case "users": + case "settings": + return authBean.isAdmin() || authBean.isManager(); + case "dashboard": + case "clients": + case "coaches": + case "workshops": + case "sessions": + case "profile": + return true; + default: + return false; + } + } + + // Getters et Setters + public String getCurrentPage() { + return currentPage; + } + + public void setCurrentPage(String currentPage) { + this.currentPage = currentPage; + } +} diff --git a/src/main/java/com/gbcm/client/beans/auth/AuthBean.java b/src/main/java/com/gbcm/client/beans/auth/AuthBean.java new file mode 100644 index 0000000..aa8e668 --- /dev/null +++ b/src/main/java/com/gbcm/client/beans/auth/AuthBean.java @@ -0,0 +1,238 @@ +package com.gbcm.client.beans.auth; + +import io.quarkus.oidc.IdToken; +import io.quarkus.oidc.OidcSession; +import io.quarkus.security.identity.SecurityIdentity; +import jakarta.enterprise.context.SessionScoped; +import jakarta.faces.application.FacesMessage; +import jakarta.faces.context.FacesContext; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.eclipse.microprofile.jwt.JsonWebToken; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; +import java.util.Set; + +/** + * Bean JSF pour la gestion de l'authentification OIDC avec Keycloak + * + * @author GBCM Team + * @version 1.0.0 + * @since 2025-01-01 + */ +@Named("authBean") +@SessionScoped +public class AuthBean implements Serializable { + + private static final Logger logger = LoggerFactory.getLogger(AuthBean.class); + + @Inject + SecurityIdentity securityIdentity; + + @Inject + OidcSession oidcSession; + + @Inject + @IdToken + JsonWebToken idToken; + + /** + * Vérifie si l'utilisateur est authentifié + * + * @return true si authentifié + */ + public boolean isAuthenticated() { + boolean authenticated = securityIdentity != null && !securityIdentity.isAnonymous(); + logger.debug("Vérification authentification: {}", authenticated); + return authenticated; + } + + /** + * Récupère le nom de l'utilisateur connecté + * + * @return Nom d'utilisateur ou null + */ + public String getUsername() { + if (isAuthenticated()) { + String username = securityIdentity.getPrincipal().getName(); + logger.debug("Nom d'utilisateur: {}", username); + return username; + } + return null; + } + + /** + * Récupère l'email de l'utilisateur connecté + * + * @return Email ou null + */ + public String getEmail() { + if (isAuthenticated() && idToken != null) { + String email = idToken.getClaim("email"); + logger.debug("Email utilisateur: {}", email); + return email; + } + return getUsername(); // Fallback sur le username + } + + /** + * Récupère le nom complet de l'utilisateur + * + * @return Nom complet ou null + */ + public String getFullName() { + if (isAuthenticated() && idToken != null) { + String firstName = idToken.getClaim("given_name"); + String lastName = idToken.getClaim("family_name"); + + if (firstName != null && lastName != null) { + return firstName + " " + lastName; + } else if (firstName != null) { + return firstName; + } else if (lastName != null) { + return lastName; + } + } + return getUsername(); // Fallback sur le username + } + + /** + * Récupère les rôles de l'utilisateur + * + * @return Set des rôles + */ + public Set getRoles() { + if (isAuthenticated()) { + Set roles = securityIdentity.getRoles(); + logger.debug("Rôles utilisateur: {}", roles); + return roles; + } + return Set.of(); + } + + /** + * Vérifie si l'utilisateur a un rôle spécifique + * + * @param role Rôle à vérifier + * @return true si l'utilisateur a le rôle + */ + public boolean hasRole(String role) { + boolean hasRole = isAuthenticated() && securityIdentity.hasRole(role); + logger.debug("Vérification rôle '{}': {}", role, hasRole); + return hasRole; + } + + /** + * Vérifie si l'utilisateur est administrateur + * + * @return true si admin + */ + public boolean isAdmin() { + return hasRole("ADMIN"); + } + + /** + * Vérifie si l'utilisateur est manager + * + * @return true si manager + */ + public boolean isManager() { + return hasRole("MANAGER"); + } + + /** + * Vérifie si l'utilisateur est coach + * + * @return true si coach + */ + public boolean isCoach() { + return hasRole("COACH"); + } + + /** + * Vérifie si l'utilisateur est client + * + * @return true si client + */ + public boolean isClient() { + return hasRole("CLIENT"); + } + + /** + * Vérifie si l'utilisateur est prospect + * + * @return true si prospect + */ + public boolean isProspect() { + return hasRole("PROSPECT"); + } + + /** + * Initie la connexion OIDC + * + * @return Navigation vers la page de login Keycloak + */ + public String login() { + logger.info("Initiation de la connexion OIDC"); + // Quarkus OIDC redirigera automatiquement vers Keycloak + return "/gbcm/login?faces-redirect=true"; + } + + /** + * Déconnexion OIDC + * + * @return Navigation vers la page d'accueil + */ + public String logout() { + try { + logger.info("Déconnexion OIDC pour l'utilisateur: {}", getUsername()); + + if (oidcSession != null) { + oidcSession.logout().await().indefinitely(); + } + + // Invalider la session JSF + FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); + + // Message de confirmation + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "Déconnexion réussie", + "Vous avez été déconnecté avec succès.")); + + logger.info("Déconnexion OIDC terminée"); + return "/index?faces-redirect=true"; + + } catch (Exception e) { + logger.error("Erreur lors de la déconnexion OIDC", e); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur de déconnexion", + "Une erreur s'est produite lors de la déconnexion.")); + return null; + } + } + + /** + * Récupère l'URL de déconnexion Keycloak + * + * @return URL de déconnexion + */ + public String getLogoutUrl() { + return "http://localhost:8180/realms/gbcm-llc/protocol/openid-connect/logout" + + "?redirect_uri=http://localhost:8081/gbcm/"; + } + + /** + * Récupère des informations sur le token ID + * + * @return Informations du token ou message d'erreur + */ + public String getTokenInfo() { + if (idToken != null) { + return "Token émis par: " + idToken.getIssuer() + + ", Expire à: " + idToken.getExpirationTime(); + } + return "Aucun token ID disponible"; + } +} diff --git a/src/main/java/com/gbcm/client/service/GBCMServerClient.java b/src/main/java/com/gbcm/client/service/GBCMServerClient.java index c4cbb7f..577396d 100644 --- a/src/main/java/com/gbcm/client/service/GBCMServerClient.java +++ b/src/main/java/com/gbcm/client/service/GBCMServerClient.java @@ -1,16 +1,18 @@ package com.gbcm.client.service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.gbcm.server.api.dto.auth.LoginRequestDTO; import com.gbcm.server.api.dto.auth.LoginResponseDTO; import com.gbcm.server.api.dto.user.UserDTO; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Client REST pour communiquer avec l'API GBCM Server @@ -24,7 +26,7 @@ public class GBCMServerClient { private static final Logger logger = LoggerFactory.getLogger(GBCMServerClient.class); - private static final String BASE_URL = "http://localhost:8080/api"; + private static final String BASE_URL = "http://localhost:8082/api"; private final Client client; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1112e49..dc84b0c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -3,7 +3,7 @@ quarkus.application.name=gbcm-client quarkus.application.version=1.0.0-SNAPSHOT # Server Configuration -quarkus.http.port=8080 +quarkus.http.port=8081 quarkus.http.host=0.0.0.0 # JSF Configuration diff --git a/src/main/webapp/WEB-INF/freya-templates/config.xhtml b/src/main/webapp/WEB-INF/freya-templates/config.xhtml new file mode 100644 index 0000000..6fc2bb1 --- /dev/null +++ b/src/main/webapp/WEB-INF/freya-templates/config.xhtml @@ -0,0 +1,93 @@ + + + + + + +
+ +
Menu Type
+ + + + + + + +
+ +
Color Scheme
+ + + + + + + +
+
Topbar and Menu Mode
+ + + + + +
+ + +
+
Topbar Mode
+ + + + + +
+ + +
+
Menu Mode
+ + + + + +
+ +
+ +
Input Style
+ + + + + + +
+ +
Theme Colors
+
+ +
+ + +
+
+
+
+
+
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/freya-templates/footer.xhtml b/src/main/webapp/WEB-INF/freya-templates/footer.xhtml new file mode 100644 index 0000000..1b3e817 --- /dev/null +++ b/src/main/webapp/WEB-INF/freya-templates/footer.xhtml @@ -0,0 +1,56 @@ + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/freya-templates/menu.xhtml b/src/main/webapp/WEB-INF/freya-templates/menu.xhtml new file mode 100644 index 0000000..8ad9ab4 --- /dev/null +++ b/src/main/webapp/WEB-INF/freya-templates/menu.xhtml @@ -0,0 +1,105 @@ + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/freya-templates/rightpanel.xhtml b/src/main/webapp/WEB-INF/freya-templates/rightpanel.xhtml new file mode 100644 index 0000000..fb2d53f --- /dev/null +++ b/src/main/webapp/WEB-INF/freya-templates/rightpanel.xhtml @@ -0,0 +1,284 @@ + + +
+
+
+
+
Today
+
+
+ +
+
Ankara, 22 May
+

24º

+
+
+
+
+
+
My list
+ + + +
+
    +
  • +
    +
    Perform usability testing for P15 MVP
    + -Public pages + -Product pages +
    +
  • +
  • +
    +
    Buy puzzle set from Amazon
    + Ravensburger Seurat, 2000 +
    +
  • +
  • +
    +
    Morning Run
    +
    + +
  • +
  • +
    +
    Morning Run
    +
    + +
  • +
+
+ +
+
+
Favorites
+
+ +
+ +
+ + + + + + 3 + +
+ +
+
+ You +
+

Hey M. hope you are well. Our idea is accepted by the board. Now it’s time to execute it.

+ 3 mins ago +
+
+

we did it! 🤠

+ 3 mins ago +
+
+
+ Micheal J. +
+

That’s really good!

+ 3 mins ago +
+
+
+ You +
+

But it’s important to ship MVP ASAP

+ 3 mins ago +
+
+
+ Micheal J. +
+

I’ll be looking at the process then, just to be sure 🤓

+ 3 mins ago +
+
+
+ You +
+

That’s awesome. Thanks!

+ 3 mins ago +
+
+
+ +
+
+
+ +
+
+
+ + + + 1 + +
+ +
+
+ Sarah +
+

That’s really good!

+ 3 mins ago +
+
+
+ You +
+

But it’s important to ship MVP ASAP

+ 3 mins ago +
+
+
+ +
+
+
+ +
+
+
+ + + + +
+
+

No Message From Margret K.

+
+
+ +
+
+ +
+ + + + +
+
+

No Message From Bob C.

+
+
+ +
+
+
+ + + + +
+ +
+
    +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
  • + +
    +
    John Doe
    + Active +
    +
  • +
+
+
+ +
+
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/freya-templates/template.xhtml b/src/main/webapp/WEB-INF/freya-templates/template.xhtml new file mode 100644 index 0000000..2ecdbbc --- /dev/null +++ b/src/main/webapp/WEB-INF/freya-templates/template.xhtml @@ -0,0 +1,54 @@ + + + + + + + + + + + + <ui:insert name="title">GBCM - Global Business Consulting & Management</ui:insert> + + + + + + +
+ + + + + +
+
+ +
+ +
+ + + +