diff --git a/backend/migrations/20260325091757_sql_test.sql b/backend/migrations/20260325091757_sql_test.sql
index 1f0e851..db6697a 100644
--- a/backend/migrations/20260325091757_sql_test.sql
+++ b/backend/migrations/20260325091757_sql_test.sql
@@ -250,14 +250,23 @@ INSERT INTO `service` (`id`, `nom`, `id_organisation`) VALUES
INSERT INTO `user` (`id`, `organisation_id`, `service_id`, `email`, `password`, `first_name`, `last_name`, `est_admin`, `total_carbon_footprint`) VALUES
(1, 1, 1, 'test@example.com', '$2y$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa', 'Test', 'User', 0, 100.0),
-(2, NULL, NULL, 'test_default@example.com', '$2y$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa', 'Default', 'User', 0, 0.0);
+(2, NULL, NULL, 'test_default@example.com', '$2y$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa', 'Default', 'User', 0, 0.0),
+(3, 1, 1, 'test_org_agg@example.com', '$2y$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa', 'Agg', 'User', 0, 0.0),
+(4, NULL, NULL, 'test_global_avg_seed@example.com', '$2y$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa', 'Global', 'Seed', 0, 0.0);
INSERT INTO `organisation_user` (`user_id`, `organisation_id`, `est_admin`) VALUES
-(1, 1, 0);
+(1, 1, 0),
+(3, 1, 0);
INSERT INTO `user_equivalent` (`user_id`, `equivalent_id`) VALUES
(1, 1),
-(1, 3);
+(1, 3),
+(3, 2);
+
+INSERT INTO `monitored_website` (`user_id`, `url_domain`, `carbon_footprint`, `creation_date`) VALUES
+(3, NULL, 4000.0, DATE_SUB(CURDATE(), INTERVAL 1 DAY)),
+(4, NULL, -3970.0, DATE_SUB(CURDATE(), INTERVAL 1 DAY)),
+(4, NULL, -15.0, CURDATE());
--
-- Contraintes pour les tables déchargées
diff --git a/backend/src/service/organisation_service.rs b/backend/src/service/organisation_service.rs
index ed88712..9dfc87d 100644
--- a/backend/src/service/organisation_service.rs
+++ b/backend/src/service/organisation_service.rs
@@ -25,7 +25,10 @@ impl OrganisationService {
let average_daily_carbon_footprint: f64 = MonitoredWebsiteService::average_daily_carbon_footprint_for_organization(pool, orga_id, service_id).await;
let total_consumption: f64 = MonitoredWebsiteService::total_organization_consumption(pool, orga_id, service_id).await.unwrap_or(None).unwrap_or(0.0);
- let equivalent = EquivalentService::equivalent(pool, Some(user_id), 1, total_consumption).await.ok().and_then(|mut v| v.pop());
+ let equivalent = EquivalentService::equivalent(pool, Some(user_id), 1, average_daily_carbon_footprint)
+ .await
+ .ok()
+ .and_then(|mut v| v.pop());
Ok(MyOrganizationInfos {
name,
diff --git a/backend/tests/organisation_service_tests.rs b/backend/tests/organisation_service_tests.rs
index 51bad86..5245775 100644
--- a/backend/tests/organisation_service_tests.rs
+++ b/backend/tests/organisation_service_tests.rs
@@ -31,6 +31,25 @@ mod tests {
assert!(infos.total_consumption >= 0.0);
}
+ #[sqlx::test]
+ async fn equivalent_mo_infos_doit_etre_base_sur_moyenne_journaliere(pool: MySqlPool) {
+ // GIVEN
+ let org_id = 1;
+ let user_id = 3;
+
+ // WHEN
+ let infos = OrganisationService::organization_informations(&pool, org_id, user_id, None).await.unwrap();
+ let equivalent = infos.equivalent.expect("Un equivalent doit etre present");
+
+ // THEN
+ assert_eq!(infos.average_daily_carbon_footprint, 2000.0);
+ assert_eq!(infos.total_consumption, 4000.0);
+ assert_eq!(equivalent.name, "data.equivalent.paris_londres");
+ assert_eq!(equivalent.icon, "train-paris-londres.png");
+ assert_eq!(equivalent.value, 1.46);
+ assert_ne!(equivalent.value, 2.92);
+ }
+
#[tokio::test]
async fn devrait_generer_code_organisation() {
// WHEN
diff --git a/frontend/src/lib/components/auth/InscriptionOrganisationForm.svelte b/frontend/src/lib/components/auth/InscriptionOrganisationForm.svelte
index 4639b54..004ca98 100644
--- a/frontend/src/lib/components/auth/InscriptionOrganisationForm.svelte
+++ b/frontend/src/lib/components/auth/InscriptionOrganisationForm.svelte
@@ -75,7 +75,7 @@
+ class="px-3 py-1.5 text-sm border rounded-lg w-full focus:outline-none {submitted && errors.organisationName ? 'border-red-700 bg-red-50' : 'border-grey-200'}" placeholder={$t('auth.register.org_name_placeholder')}>
{#if submitted && errors.organisationName} {$t('auth.register.org_name_required')} {/if}
diff --git a/frontend/src/lib/components/myaccount/CreateService.svelte b/frontend/src/lib/components/myaccount/CreateService.svelte
index c171ab2..00c0b4e 100644
--- a/frontend/src/lib/components/myaccount/CreateService.svelte
+++ b/frontend/src/lib/components/myaccount/CreateService.svelte
@@ -37,7 +37,7 @@
{$t('account.service.title')}
-
Ajoutez les services de votre organisation pour suivre leur empreinte carbone.
+
{$t('account.service.description')}
{#if successMessage}
diff --git a/frontend/src/lib/components/myaccount/DeleteOrganisationModal.svelte b/frontend/src/lib/components/myaccount/DeleteOrganisationModal.svelte
index 69bc388..1952bb3 100644
--- a/frontend/src/lib/components/myaccount/DeleteOrganisationModal.svelte
+++ b/frontend/src/lib/components/myaccount/DeleteOrganisationModal.svelte
@@ -33,7 +33,7 @@
onclick={onConfirm}
class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-medium shadow-sm"
>
- {$t('common.delete', { default: 'Supprimer' })}
+ {$t('account.modals.delete')}
diff --git a/frontend/src/lib/components/myaccount/GererMembre.svelte b/frontend/src/lib/components/myaccount/GererMembre.svelte
index 6501e1f..134e380 100644
--- a/frontend/src/lib/components/myaccount/GererMembre.svelte
+++ b/frontend/src/lib/components/myaccount/GererMembre.svelte
@@ -101,14 +101,14 @@
-
Membres
+
{$t('account.members.title')}
{#if members.length > 0}
@@ -128,8 +128,8 @@
{:else}
-
Vous n'avez pas encore ajouté de membres...
+
{$t('account.members.empty_state')}
{/if}
diff --git a/frontend/src/lib/components/myaccount/MyInfoOrganisation.svelte b/frontend/src/lib/components/myaccount/MyInfoOrganisation.svelte
index 4e8abaa..aa3cfd9 100644
--- a/frontend/src/lib/components/myaccount/MyInfoOrganisation.svelte
+++ b/frontend/src/lib/components/myaccount/MyInfoOrganisation.svelte
@@ -89,7 +89,7 @@
type="text"
bind:value={organisation.nom}
class="px-4 py-2 border border-grey-200 rounded-lg w-full focus:outline-none"
- placeholder="Nom de l'organisation"
+ placeholder={$t('account.organization.name_placeholder')}
/>
@@ -104,7 +104,7 @@
name="siret"
type="text"
class="px-4 py-2 border border-grey-200 rounded-lg w-full focus:outline-none {submitted && errors.siret ? 'border-red-700 bg-red-50' : 'border-grey-200'}"
- placeholder="Votre SIRET"
+ placeholder={$t('account.organization.siret_placeholder')}
/>
{#if submitted && errors.siret} {$t('errors.validation_siret_format')} {/if}
diff --git a/frontend/src/lib/i18n/en.json b/frontend/src/lib/i18n/en.json
index 71576a4..4e26524 100644
--- a/frontend/src/lib/i18n/en.json
+++ b/frontend/src/lib/i18n/en.json
@@ -122,6 +122,7 @@
"firstname_required": "First name required.",
"lastname_required": "Last name required.",
"org_name": "Organization Name",
+ "org_name_placeholder": "My organization",
"org_name_required": "Name required.",
"siret": "SIRET Number (optional)",
"confirm_password": "Confirmation",
@@ -151,6 +152,7 @@
},
"service": {
"title": "Service Management",
+ "description": "Add your organization's services to track their carbon footprint.",
"no_service": "You are not attached to any service.",
"name_label": "Service Name",
"leave_button": "Leave Service",
@@ -207,11 +209,14 @@
"organization": {
"title": "Organization",
"name_label": "Organization Name",
+ "name_placeholder": "Organization name",
+ "siret_placeholder": "Your SIRET",
"code_label": "Organization Code",
"code_unknown": "Unknown",
"leave_button": "Leave",
"change_button": "Change Organization",
"join_button": "Join",
+ "join_create_option": "+ Join / Create",
"join_loading": "Loading...",
"code_placeholder": "Enter organization code",
"code_help": "Please enter the 8-character code sent by your organization",
@@ -221,6 +226,20 @@
"or": "or",
"create_button": "Create my organization"
},
+ "members": {
+ "title": "Members",
+ "search_placeholder": "Search for a member",
+ "admin_badge": "Admin",
+ "unassign_title": "Click to remove from service",
+ "unassign_aria": "Remove from service",
+ "delete_aria": "Delete member",
+ "empty_state": "You have not added any members yet..."
+ },
+ "delete_org": {
+ "title": "Delete organization",
+ "confirmation": "Are you sure you want to delete the organization {orgName}?",
+ "warning": "This action is irreversible and will delete all associated data."
+ },
"modals": {
"leave_org_confirm_title": "Confirmation",
"leave_org_confirm_desc": "Are you sure you want to leave the organization \"{orgName}\"?",
@@ -489,7 +508,7 @@
"no_data_period": "No data available for this period"
},
"top_polluting_sites": {
- "title": "Top 5 most polluting sites",
+ "title": "Top 5 most visited high-carbon-footprint websites",
"chart_label": "Carbon footprint (gCO2e)"
},
"equivalent": {
diff --git a/frontend/src/lib/i18n/fr.json b/frontend/src/lib/i18n/fr.json
index d735ff5..1d574d1 100644
--- a/frontend/src/lib/i18n/fr.json
+++ b/frontend/src/lib/i18n/fr.json
@@ -122,6 +122,7 @@
"firstname_required": "Prénom requis.",
"lastname_required": "Nom requis.",
"org_name": "Nom de l'organisation",
+ "org_name_placeholder": "Mon organisation",
"org_name_required": "Nom requis.",
"siret": "Numéro SIRET (optionnel)",
"confirm_password": "Confirmation",
@@ -151,6 +152,7 @@
},
"service": {
"title": "Gestion des services",
+ "description": "Ajoutez les services de votre organisation pour suivre leur empreinte carbone.",
"no_service": "Vous n'êtes rattaché à aucun service.",
"name_label": "Nom du service",
"leave_button": "Quitter le service",
@@ -205,11 +207,14 @@
"organization": {
"title": "Organisation",
"name_label": "Nom de l'organisation",
+ "name_placeholder": "Nom de l'organisation",
+ "siret_placeholder": "Votre SIRET",
"code_label": "Code Organisation",
"code_unknown": "Inconnu",
"leave_button": "Quitter",
"change_button": "Changer d'organisation",
"join_button": "Rejoindre",
+ "join_create_option": "+ Rejoindre / Créer",
"join_loading": "Chargement...",
"code_placeholder": "Entrez le code organisation",
"code_help": "Merci d'entrer le code à 8 caractères envoyé par votre organisation",
@@ -219,6 +224,20 @@
"or": "ou",
"create_button": "Créer mon organisation"
},
+ "members": {
+ "title": "Membres",
+ "search_placeholder": "Rechercher un membre",
+ "admin_badge": "Admin",
+ "unassign_title": "Cliquer pour retirer du service",
+ "unassign_aria": "Retirer du service",
+ "delete_aria": "Supprimer le membre",
+ "empty_state": "Vous n'avez pas encore ajouté de membres..."
+ },
+ "delete_org": {
+ "title": "Supprimer l'organisation",
+ "confirmation": "Êtes-vous sûr de vouloir supprimer l'organisation {orgName} ?",
+ "warning": "Cette action est irréversible et supprimera toutes les données associées."
+ },
"modals": {
"leave_org_confirm_title": "Confirmation",
"leave_org_confirm_desc": "Etes-vous sur de vouloir quitter l'organisation \"{orgName}\" ?",
@@ -500,7 +519,7 @@
"no_data_period": "Aucune donnée disponible pour cette période"
},
"top_polluting_sites": {
- "title": "Top 5 des sites les plus polluants",
+ "title": "Top 5 des sites visités ayant la plus forte empreinte carbone",
"chart_label": "Empreinte carbone (gCO2e)"
},
"equivalent": {
diff --git a/frontend/src/routes/(app)/mon-compte/+page.server.ts b/frontend/src/routes/(app)/mon-compte/+page.server.ts
index 95213a9..3850aa8 100644
--- a/frontend/src/routes/(app)/mon-compte/+page.server.ts
+++ b/frontend/src/routes/(app)/mon-compte/+page.server.ts
@@ -204,11 +204,12 @@ export const actions: Actions = {
'Content-Type': 'application/json',
'Cookie': request.headers.get('cookie') || ''
},
- body: JSON.stringify({ userId: serviceId, organisationId })
+ body: JSON.stringify({ serviceId, organisationId })
});
const result = await response.json();
+
if (result.success) {
return { success: true, message: 'success.service_deleted', actionType: 'delete_service' };
}
diff --git a/frontend/src/routes/(app)/mon-compte/+page.svelte b/frontend/src/routes/(app)/mon-compte/+page.svelte
index ccf429c..8c00810 100644
--- a/frontend/src/routes/(app)/mon-compte/+page.svelte
+++ b/frontend/src/routes/(app)/mon-compte/+page.svelte
@@ -88,7 +88,7 @@
{org.nom} {org.est_admin ? '(Admin)' : ''}
{/each}
-
+
{#if selectedOrganisation && selectedOrganisation.est_admin}