Aller au contenu principal

Composants React

Les composants React Wast-o permettent d'intégrer nativement les fonctionnalités Wast-o dans votre application React.

Installation​

npm install @wasto/react-components

Prérequis​

  • React 16.8 ou supérieur
  • React DOM 16.8 ou supérieur

Composant Calendar​

Le composant Calendar affiche un calendrier mensuel avec les jours de collecte par type de déchet.

Utilisation de base​

import { Calendar } from '@wasto/react-components';

function App() {
return (
<Calendar
cityId="city-uuid"
lang="fr"
theme="light"
/>
);
}

Props​

PropTypeRequisDéfautDescription
cityIdstringOui-Identifiant unique de la ville (UUID)
placeIdstringNon-Identifiant du lieu de collecte spécifique
apiBaseUrlstringNon'https://api.wast-o.com'URL de base de l'API
lang'fr' | 'en'Non'fr'Langue d'affichage
theme'light' | 'dark'Non'light'Thème d'affichage
onDayClick(date: Date, wasteTypes: string[]) => voidNon-Callback appelé lors du clic sur un jour
classNamestringNon''Classe CSS supplémentaire

Exemple avec gestion d'événements​

import { Calendar } from '@wasto/react-components';
import { useState } from 'react';

function App() {
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
const [wasteTypes, setWasteTypes] = useState<string[]>([]);

return (
<div>
<Calendar
cityId="city-uuid"
placeId="place-uuid"
lang="fr"
onDayClick={(date, types) => {
setSelectedDate(date);
setWasteTypes(types);
console.log('Jour sélectionné:', date);
console.log('Types de déchets:', types);
}}
/>

{selectedDate && (
<div>
<h3>Collecte le {selectedDate.toLocaleDateString('fr-FR')}</h3>
<p>Types de déchets: {wasteTypes.join(', ')}</p>
</div>
)}
</div>
);
}

Embeds iframe (PublicWebEmbed)​

Pour embarquer le site public (info-tri, centres de tri, calendrier) sans recoder l’UI :

import {
PublicWebEmbed,
RecyclingInfoEmbed,
RecyclingCentersEmbed,
} from '@wasto/react-components';

<RecyclingInfoEmbed cityId="city-uuid" />
<RecyclingCentersEmbed cityId="city-uuid" />
<PublicWebEmbed page="calendrier" cityId="city-uuid" placeId="place-uuid" />
PropTypeRequisDéfautDescription
page'info' | 'centres-de-tri' | 'calendrier' | 'calendrier-pdf'oui (PublicWebEmbed)-Module affiché
cityIdstringOui-Commune
placeIdstringNon-Secteur (calendrier)
cityGroupIdstringNon-Groupement (calendrier-pdf)
publicWebBaseUrlstringNon'https://public-web.wast-o.com'Base du site public
heightnumber | stringNon520Hauteur de l’iframe
widthnumber | stringNon'100%'Largeur du widget
maxWidthnumber | stringNon-Largeur maximale
align'left' | 'center' | 'right'Non-Alignement
accentColorstringNon'#0f766e'Couleur d’accent
preview'below' | 'side' | 'none'Non'below' (calendrier-pdf)Aperçu PDF
titlestringNonselon pagetitle de l’iframe

RecyclingInfoEmbed et RecyclingCentersEmbed sont des raccourcis (page="info" / page="centres-de-tri").

Widget recherche d’adresse → PDF (CalendarPdfEmbed)​

Barre de recherche embarquée : le citoyen saisit sa rue, choisit son secteur, puis télécharge le calendrier PDF généré par l’API.

import { CalendarPdfEmbed } from '@wasto/react-components';

function WidgetCollectivite() {
return (
<CalendarPdfEmbed
cityId="city-uuid"
accentColor="#0f766e"
placeholder="Votre rue"
preview="below"
maxWidth={960}
align="center"
/>
);
}

Équivalent via PublicWebEmbed : page="calendrier-pdf".

PropTypeRequisDéfautDescription
cityIdstringOui-Commune
cityGroupIdstringNon-Élargit la recherche aux communes du groupement
accentColorstringNon'#0f766e'Couleur d’accent
placeholderstringNon-Placeholder du champ adresse
yearnumberNonannée en coursAnnée du calendrier PDF
preview'below' | 'side' | 'none'Non'below'Aperçu sous / à côté / masqué
previewHeightnumberNonautoHauteur de l’aperçu (px)
previewWidthnumberNon100%Largeur de l’aperçu (px)
widthnumber | stringNon'100%'Largeur du widget
maxWidthnumber | stringNon-Largeur max (ex. 960)
align'left' | 'center' | 'right'Non-Alignement dans la page
publicWebBaseUrlstringNon'https://public-web.wast-o.com'Base du site public
heightnumber | stringNon420Hauteur initiale (auto-ajustée)
autoResizebooleanNontrueAjuste la hauteur au contenu

Snippet iframe copiable : voir Intégration par iframe.

Widget Wast'O Agent (AssistantChatEmbed)​

FAB de chat citoyen flottant (bas-droite), même contrat que data-wasto="assistant" + widget.js.

import { AssistantChatEmbed } from '@wasto/react-components';

function SiteCollectivite() {
return (
<AssistantChatEmbed
cityId="city-uuid"
accentColor="#2E7D32"
/>
);
}
PropTypeRequisDéfautDescription
cityIdstringOui-Commune
placeIdstringNon-Secteur de collecte
accentColorstringNon'#2E7D32'Couleur FAB / en-tête
publicWebBaseUrlstringNon'https://public-web.wast-o.com'Base du site public

Console : Assistant IA → Installation site web.

Composant Challenges​

Le composant Challenges affiche la liste des challenges disponibles pour une ville.

Utilisation de base​

import { Challenges } from '@wasto/react-components';

function App() {
return (
<Challenges
cityId="city-uuid"
lang="fr"
theme="light"
/>
);
}

Props​

PropTypeRequisDéfautDescription
cityIdstringOui-Identifiant unique de la ville (UUID)
apiBaseUrlstringNon'https://api.wast-o.com'URL de base de l'API
lang'fr' | 'en'Non'fr'Langue d'affichage
theme'light' | 'dark'Non'light'Thème d'affichage
onChallengeClick(challengeId: string) => voidNon-Callback appelé lors du clic sur un challenge
onChallengeComplete(challengeId: string, score: number) => voidNon-Callback appelé lors de la complétion d'un challenge
classNamestringNon''Classe CSS supplémentaire

Exemple avec navigation​

import { Challenges } from '@wasto/react-components';
import { useState } from 'react';

function App() {
const [selectedChallenge, setSelectedChallenge] = useState<string | null>(null);

return (
<div>
<Challenges
cityId="city-uuid"
lang="fr"
onChallengeClick={(challengeId) => {
setSelectedChallenge(challengeId);
// Naviguer vers le quiz
}}
onChallengeComplete={(challengeId, score) => {
console.log(`Challenge ${challengeId} complété avec un score de ${score}%`);
}}
/>
</div>
);
}

Composant Quiz​

Le composant Quiz affiche un quiz interactif pour un challenge spécifique.

Utilisation de base​

import { Quiz } from '@wasto/react-components';

function App() {
const deviceId = 'device-uuid'; // Généré ou récupéré depuis le localStorage

return (
<Quiz
cityId="city-uuid"
challengeId="challenge-uuid"
deviceId={deviceId}
lang="fr"
theme="light"
/>
);
}

Props​

PropTypeRequisDéfautDescription
cityIdstringOui-Identifiant unique de la ville (UUID)
challengeIdstringOui-Identifiant du challenge
serieIdstringNon-Identifiant de la série de questions
apiBaseUrlstringNon'https://api.wast-o.com'URL de base de l'API
lang'fr' | 'en'Non'fr'Langue d'affichage
theme'light' | 'dark'Non'light'Thème d'affichage
deviceIdstringNon-Identifiant de l'appareil pour sauvegarder la progression
onComplete(score: number) => voidNon-Callback appelé à la fin du quiz
classNamestringNon''Classe CSS supplémentaire

Exemple complet​

import { Quiz } from '@wasto/react-components';
import { useState, useEffect } from 'react';

function App() {
const [deviceId, setDeviceId] = useState<string>('');
const [score, setScore] = useState<number | null>(null);

useEffect(() => {
// Générer ou récupérer le deviceId
const storedId = localStorage.getItem('wasto_device_id');
if (storedId) {
setDeviceId(storedId);
} else {
const newId = 'web_' + crypto.randomUUID();
localStorage.setItem('wasto_device_id', newId);
setDeviceId(newId);
}
}, []);

return (
<div>
{score === null ? (
<Quiz
cityId="city-uuid"
challengeId="challenge-uuid"
deviceId={deviceId}
lang="fr"
onComplete={(finalScore) => {
setScore(finalScore);
console.log(`Quiz terminé avec un score de ${finalScore}%`);
}}
/>
) : (
<div>
<h2>Quiz terminé !</h2>
<p>Votre score: {score}%</p>
</div>
)}
</div>
);
}

Personnalisation du style​

Les composants utilisent des classes CSS avec le préfixe wasto-. Vous pouvez personnaliser le style en surchargeant ces classes :

/* Personnaliser le calendrier */
.wasto-calendar {
font-family: 'Your Font', sans-serif;
}

.wasto-calendar-day.today {
background-color: #e3f2fd;
}

/* Personnaliser les challenges */
.wasto-challenge-card {
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* Personnaliser le quiz */
.wasto-quiz-question {
font-size: 1.2rem;
}

Gestion des erreurs​

Tous les composants gèrent les erreurs de manière interne et affichent un message d'erreur si nécessaire. Vous pouvez également intercepter les erreurs :

import { Calendar } from '@wasto/react-components';

function App() {
return (
<Calendar
cityId="city-uuid"
apiBaseUrl="https://api.wast-o.com"
onError={(error) => {
console.error('Erreur du calendrier:', error);
// Afficher une notification à l'utilisateur
}}
/>
);
}

Types TypeScript​

Tous les types sont exportés pour une utilisation TypeScript :

import type { CalendarProps, ChallengesProps, QuizProps } from '@wasto/react-components';

const calendarProps: CalendarProps = {
cityId: 'city-uuid',
lang: 'fr',
};

Exemple d'application complète​

import React, { useState } from 'react';
import { Calendar, Challenges, Quiz } from '@wasto/react-components';

function WastoApp() {
const [view, setView] = useState<'calendar' | 'challenges' | 'quiz'>('calendar');
const [selectedChallenge, setSelectedChallenge] = useState<string | null>(null);
const cityId = 'city-uuid';
const deviceId = localStorage.getItem('wasto_device_id') || 'web_' + crypto.randomUUID();

return (
<div>
<nav>
<button onClick={() => setView('calendar')}>Calendrier</button>
<button onClick={() => setView('challenges')}>Challenges</button>
</nav>

{view === 'calendar' && (
<Calendar
cityId={cityId}
lang="fr"
onDayClick={(date, wasteTypes) => {
console.log('Jour sélectionné:', date, wasteTypes);
}}
/>
)}

{view === 'challenges' && (
<Challenges
cityId={cityId}
lang="fr"
onChallengeClick={(challengeId) => {
setSelectedChallenge(challengeId);
setView('quiz');
}}
/>
)}

{view === 'quiz' && selectedChallenge && (
<Quiz
cityId={cityId}
challengeId={selectedChallenge}
deviceId={deviceId}
lang="fr"
onComplete={(score) => {
console.log('Score:', score);
setView('challenges');
setSelectedChallenge(null);
}}
/>
)}
</div>
);
}

export default WastoApp;

Support​

Pour toute question ou problème, consultez la documentation API ou contactez le support technique.