12 KiB
SocioWire Frontend
Interface utilisateur de SocioWire - plateforme sociale géolocalisée. Application React moderne avec cartes 3D, authentification Keycloak, et fonctionnalités temps réel.
Description
Le frontend SocioWire est une Single Page Application (SPA) construite avec React 19 et Vite. Elle offre une expérience utilisateur riche avec:
- Authentification OAuth2 via Keycloak
- Feed de posts géolocalisés avec cartes interactives
- Recherche intelligente avec autocomplete
- Visualisation 3D des "Islands" utilisateurs
- Engagement temps réel (likes, comments, shares)
- Interface responsive et moderne
Technologies
- Framework: React 19
- Build Tool: Vite (rolldown-vite)
- Routing: React Router DOM v7
- Auth: Keycloak.js (OAuth2/OIDC)
- Maps: MapLibre GL
- HTTP Client: Axios
- Icons: Font Awesome
- Styling: CSS modules + custom themes
Structure du projet
sociowire-frontend/
├── src/
│ ├── main.jsx # Entry point
│ ├── App.jsx # App router
│ ├── api/
│ │ ├── client.js # Axios client avec auth
│ │ └── templates.js # API templates
│ ├── auth/
│ │ ├── AuthContext.jsx # Auth provider
│ │ ├── authStorage.js # Token storage
│ │ └── emailVerified.js # Email verification
│ ├── components/
│ │ ├── Posts/ # Post components
│ │ │ ├── PostCard.jsx
│ │ │ ├── PostList.jsx
│ │ │ └── PostCardTemplate.jsx
│ │ ├── Search/ # Search components
│ │ │ └── SmartSearchBar.jsx
│ │ ├── Filters/ # Filter components
│ │ │ ├── FilterButtons.jsx
│ │ │ └── TimeFilterButtons.jsx
│ │ ├── Profile/ # User profile
│ │ │ └── UserProfile.jsx
│ │ ├── Island/ # Island visualization
│ │ │ ├── IslandViewer.jsx
│ │ │ └── IslandUniverse.jsx
│ │ ├── Map/ # Map components
│ │ │ ├── MapView.jsx
│ │ │ ├── MapControls.jsx
│ │ │ └── TemplateMarkerCard.jsx
│ │ ├── Auth/ # Auth components
│ │ │ ├── AuthToast.jsx
│ │ │ └── AuthPill.jsx
│ │ └── ui/ # UI primitives
│ │ └── ToastHost.jsx
│ ├── services/
│ │ └── recoSearch.js # Reco service client
│ ├── theme/
│ │ └── cardTokens.js # Design tokens
│ └── index.css # Global styles
├── public/ # Static assets
├── package.json
├── vite.config.js
└── eslint.config.js
Prérequis
- Node.js 18+ (recommandé: 20+)
- npm ou yarn
- Backend SocioWire en cours d'exécution (port 8081)
- Keycloak configuré
Installation
cd /home/swire/sociowire-frontend
npm install
Configuration
Les URLs des services sont configurées dans le code:
Backend API: http://localhost:8081
Keycloak: https://auth.sociowire.com
Pour changer ces URLs, modifier:
src/api/client.js- Backend URLsrc/auth/AuthContext.jsx- Keycloak URL
Variables d'environnement (optionnel)
Créer un fichier .env.local:
VITE_API_URL=http://localhost:8081
VITE_KEYCLOAK_URL=https://auth.sociowire.com
VITE_KEYCLOAK_REALM=sociowire
VITE_KEYCLOAK_CLIENT_ID=sociowire-frontend
Démarrage
Mode développement
npm run dev
L'application démarre sur http://localhost:5173 (ou autre port si occupé).
Build production
npm run build
Les fichiers sont générés dans dist/.
Preview production
npm run preview
Teste le build production localement.
Fonctionnalités principales
1. Authentification
- Login: Email/password via Keycloak
- Signup: Création de compte avec vérification email
- OAuth: Login social (Google, GitHub, etc.)
- Refresh tokens: Gestion automatique de l'expiration
- Logout: Déconnexion complète (Keycloak + local)
Composants:
AuthContext- Provider global d'authAuthPill- Widget utilisateurAuthToast- Notifications auth
2. Feed de posts
- Posts géolocalisés: Affichage avec lat/lon
- Catégories: NEWS, EVENT, DISCUSSION, QUESTION
- Filtres: Par catégorie, temps, géolocalisation
- Pagination: Chargement progressif
- Templates: Posts avec templates visuels
Composants:
PostList- Liste de postsPostCard- Carte de post individuellePostCardTemplate- Post avec template
3. Recherche
- Smart Search: Recherche full-text via reco-service
- Autocomplete: Suggestions en temps réel (posts, profils, lieux)
- Filtres avancés: Catégorie, temps, géo
- Unified Search: Posts + profils + places
Composants:
SmartSearchBar- Barre de recherche avec autocompleteFilterButtons- Filtres de catégorieTimeFilterButtons- Filtres temporels
4. Cartes interactives
- MapLibre GL: Cartes vectorielles performantes
- Markers: Posts géolocalisés sur la carte
- Clustering: Regroupement de markers
- 3D: Visualisation 3D optionnelle
- Controls: Zoom, rotation, pitch
Composants:
MapView- Carte principaleMapControls- Contrôles de carteTemplateMarkerCard- Popup de marker
5. Islands (Univers utilisateurs)
- Island Universe: Visualisation 3D des utilisateurs
- Island Viewer: Détails d'une island
- Génération procédurale: Islands uniques par utilisateur
- Navigation: Exploration de l'univers
Composants:
IslandUniverse- Univers 3DIslandViewer- Vue détaillée d'island
6. Profils utilisateurs
- User Profile: Profil complet avec posts
- Avatar: Upload et affichage
- Stats: Posts, followers, etc.
- Bio: Description personnalisée
Composants:
UserProfile- Page de profil
7. Engagement
- Likes: Like/unlike de posts
- Comments: Commentaires hiérarchiques
- Shares: Partage de posts
- Truth Voting: Vote de vérité (fact-checking)
Intégré dans PostCard.
Appels API
Le frontend communique avec:
1. sociowire-backend (http://localhost:8081)
Authentification:
POST /api/signup-emailPOST /api/signupPOST /api/loginPOST /api/refreshGET /api/me
Posts:
GET /api/posts- FeedPOST /api/post- CréerGET /api/post?id=...- GetPOST /api/post/like- LikeGET /api/post/comments- CommentsPOST /api/post/comment- Ajouter comment
Recherche:
GET /api/search?q=...- Recherche full-textGET /api/suggestions?q=...- AutocompleteGET /api/smart-feed- Feed personnaliséGET /api/unified-search- Search combinée
Profils:
GET /api/profile- Mon profilPATCH /api/profile/username- Update usernamePOST /api/profile/avatar- Upload avatar
Assets:
POST /api/assets/upload- Upload imageGET /api/assets/url?id=...- Get asset URL
Islands:
GET /api/islands/nearby- Islands à proximitéGET /api/islands/by-username/{username}- Island par username
Utilitaires:
GET /api/templates- Templates de postsGET /api/ip-location- Géolocalisation IP
2. Keycloak (https://auth.sociowire.com)
Le frontend utilise keycloak-js pour communiquer avec Keycloak:
- Init:
keycloak.init({ onLoad: 'check-sso' }) - Login:
keycloak.login() - Logout:
keycloak.logout() - Token: Rafraîchissement automatique via
keycloak.updateToken()
Realm: sociowire
Client ID: sociowire-frontend
Gestion d'état
AuthContext
Provider global pour l'authentification:
import { useAuth } from './auth/AuthContext';
function Component() {
const { keycloak, isAuthenticated, username, login, logout } = useAuth();
// ...
}
État:
keycloak- Instance KeycloakisAuthenticated- Booleanusername- StringemailVerified- Booleanlogin()- Fonction loginlogout()- Fonction logout
Axios Client
Client HTTP configuré avec intercepteurs pour auth:
// src/api/client.js
import axios from 'axios';
const client = axios.create({
baseURL: 'http://localhost:8081',
headers: { 'Content-Type': 'application/json' }
});
// Request interceptor: ajoute Bearer token
client.interceptors.request.use(config => {
const token = localStorage.getItem('keycloak_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Response interceptor: refresh token si 401
client.interceptors.response.use(
response => response,
async error => {
if (error.response?.status === 401) {
// Refresh token logic
}
return Promise.reject(error);
}
);
Routing
Routes principales:
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/feed" element={<Feed />} />
<Route path="/search" element={<Search />} />
<Route path="/profile/:username" element={<Profile />} />
<Route path="/islands" element={<Islands />} />
<Route path="/post/:id" element={<PostDetail />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Routes>
</BrowserRouter>
Thème et Styling
Le projet utilise CSS modules + variables CSS:
Design Tokens (theme/cardTokens.js):
- Couleurs de catégories
- Spacing
- Border radius
- Shadows
CSS Variables:
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--success-color: #28a745;
--danger-color: #dc3545;
--warning-color: #ffc107;
}
Icônes (Font Awesome)
import '@fortawesome/fontawesome-free/css/all.min.css';
<i className="fas fa-heart"></i>
<i className="fas fa-comment"></i>
<i className="fas fa-share"></i>
MapLibre GL
Configuration de la carte:
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [-73.5, 45.5],
zoom: 10
});
Build et Déploiement
Build optimisé
npm run build
Génère:
dist/index.html- HTML principaldist/assets/*.js- Bundles JavaScriptdist/assets/*.css- Stylesdist/assets/*- Assets (images, fonts)
Déploiement
Le build peut être déployé sur:
- Nginx: Servir
dist/avec fallback versindex.html - Vercel: Détection automatique de Vite
- Netlify: Build command
npm run build, publish dirdist - Docker: Nginx container avec
dist/
Nginx config:
server {
listen 80;
root /var/www/sociowire-frontend/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Développement
Hot Module Replacement (HMR)
Vite supporte HMR out-of-the-box:
- Modifications CSS: Rechargement instantané
- Modifications JSX: Preserve state
- Modifications API: Reload complet
ESLint
npm run lint
Configuration dans eslint.config.js.
Tests
Tests à ajouter avec Vitest + React Testing Library:
npm install -D vitest @testing-library/react @testing-library/jest-dom
Performance
Optimisations:
- Code splitting: Routes lazy-loaded
- Tree shaking: Vite optimise automatiquement
- Asset optimization: Images optimisées
- Caching: Service Worker (à ajouter)
- Bundle size: Analysé avec rollup-plugin-visualizer
Sécurité
- Tokens stockés en localStorage (préférer httpOnly cookies en prod)
- Validation input côté client + serveur
- CORS configuré sur backend
- CSP headers recommandés
- Sanitisation des URLs externes
Debugging
React DevTools
Installer l'extension browser React DevTools.
Vite DevTools
Console affiche:
- HMR updates
- Build errors
- Network requests (via browser)
Logs
console.log('Debug:', data);
En production, utiliser un service de logging (Sentry, LogRocket).
Notes de développement
- Le frontend assume que le backend est sur
localhost:8081 - Keycloak doit être configuré avec le client
sociowire-frontend - Les tokens JWT sont stockés en localStorage
- MapLibre nécessite une clé API pour certains styles (optionnel)
- L'upload d'images passe par le backend, qui proxy vers asset-service