SocioWire frontend (working JS source, swchrist/sw-fe) — self-hosted mirror w/ v2 globe+clusters
Go to file
canastack-platform e74bb448b0 v2: 3D globe on zoom-out (#223) + colored news-cluster zones (#224)
- useMapCore: MapLibre v5 globe projection in style spec (auto flat on zoom-in)
- EventClustersLayer: per-cluster color by dominant impact (green/red) or stable
  per-event hue; opacity/width scale with post_count; enabled by default
- MapView: clusterZonesEnabled state + search-bar toggle
(#222's 24h default + filter-follows-map-move already present in source)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 15:45:49 +00:00
.claude Fix AppStore: English text, robust subscription loading 2026-01-28 20:19:31 +00:00
.letta/claude Fix AppStore: English text, robust subscription loading 2026-01-28 20:19:31 +00:00
public Fix LiveKit live streaming and remove old WebRTC code 2026-01-19 08:13:59 +00:00
src v2: 3D globe on zoom-out (#223) + colored news-cluster zones (#224) 2026-07-05 15:45:49 +00:00
utils update frontend 2025-12-21 00:28:26 -05:00
.gitignore yeah 2025-12-08 23:22:58 +00:00
Dockerfile Update live features 2026-01-07 02:03:36 +00:00
README.md Commit remaining frontend tweaks 2025-12-31 02:41:50 -05:00
deploy-frontend.sh fix: chat window mobile height overflow and keyboard handling 2026-01-28 05:55:22 +00:00
deploy.sh blehh 2025-12-18 22:39:29 -05:00
eslint.config.js yeah 2025-12-08 23:22:58 +00:00
index.html Fix: Prevent browser zoom on map - only map zoom should work 2026-01-26 02:09:24 +00:00
logo-master.png update frontend 2025-12-21 20:16:34 -05:00
package-lock.json fix: chat window mobile height overflow and keyboard handling 2026-01-28 05:55:22 +00:00
package.json Fix engagement for news posts (guid-based) 2026-01-31 20:17:49 +00:00
postcss.config.js feat: Modernize UI with Tailwind CSS v4 + Framer Motion 2026-01-19 09:05:51 +00:00
vite.config.js j essais de fix 2025-12-16 22:47:17 -05:00

README.md

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 URL
  • src/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'auth
  • AuthPill - Widget utilisateur
  • AuthToast - 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 posts
  • PostCard - Carte de post individuelle
  • PostCardTemplate - 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 autocomplete
  • FilterButtons - Filtres de catégorie
  • TimeFilterButtons - 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 principale
  • MapControls - Contrôles de carte
  • TemplateMarkerCard - 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 3D
  • IslandViewer - 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-email
  • POST /api/signup
  • POST /api/login
  • POST /api/refresh
  • GET /api/me

Posts:

  • GET /api/posts - Feed
  • POST /api/post - Créer
  • GET /api/post?id=... - Get
  • POST /api/post/like - Like
  • GET /api/post/comments - Comments
  • POST /api/post/comment - Ajouter comment

Recherche:

  • GET /api/search?q=... - Recherche full-text
  • GET /api/suggestions?q=... - Autocomplete
  • GET /api/smart-feed - Feed personnalisé
  • GET /api/unified-search - Search combinée

Profils:

  • GET /api/profile - Mon profil
  • PATCH /api/profile/username - Update username
  • POST /api/profile/avatar - Upload avatar

Assets:

  • POST /api/assets/upload - Upload image
  • GET /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 posts
  • GET /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 Keycloak
  • isAuthenticated - Boolean
  • username - String
  • emailVerified - Boolean
  • login() - Fonction login
  • logout() - 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 principal
  • dist/assets/*.js - Bundles JavaScript
  • dist/assets/*.css - Styles
  • dist/assets/* - Assets (images, fonts)

Déploiement

Le build peut être déployé sur:

  • Nginx: Servir dist/ avec fallback vers index.html
  • Vercel: Détection automatique de Vite
  • Netlify: Build command npm run build, publish dir dist
  • 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