Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions backend/migrations/20260325091757_sql_test.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion backend/src/service/organisation_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions backend/tests/organisation_service_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<div class="w-full text-grey-700 font-outfit font-semibold text-xs">
<label for="organisationName" class="block mb-1">{$t('auth.register.org_name')}</label>
<input bind:value={organisationName} id="organisation_name" type="text" name="organisationName"
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="Mon Organisation">
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} <span class="text-red-500 text-xs mt-0.5 block">{$t('auth.register.org_name_required')}</span> {/if}
</div>

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/myaccount/CreateService.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

<div class="flex flex-col gap-1">
<h2 class="text-2xl font-bold font-outfit text-gray-900">{$t('account.service.title')}</h2>
<p class="text-sm text-gray-500">Ajoutez les services de votre organisation pour suivre leur empreinte carbone.</p>
<p class="text-sm text-gray-500">{$t('account.service.description')}</p>
</div>

{#if successMessage}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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')}
</button>
</div>
</div>
Expand Down
20 changes: 10 additions & 10 deletions frontend/src/lib/components/myaccount/GererMembre.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@
</script>

<div class="flex flex-col gap-4">
<h1 class="font-outfit text-2xl font-semibold">Membres</h1>
<h1 class="font-outfit text-2xl font-semibold">{$t('account.members.title')}</h1>

{#if members.length > 0}
<div class="w-full font-outfit">
<div class="mb-4">
<input
type="search"
placeholder="Rechercher un membre"
placeholder={$t('account.members.search_placeholder')}
bind:value={query}
class="w-full px-3 py-2 border border-grey-200 rounded-lg focus:outline-none focus:ring-1 focus:ring-gs-green-950"
>
Expand All @@ -128,8 +128,8 @@
<button
type="button"
class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 transition-colors duration-200 cursor-pointer hover:bg-red-100 hover:text-red-800"
title="Cliquer pour retirer du service"
aria-label="Retirer du service"
title={$t('account.members.unassign_title')}
aria-label={$t('account.members.unassign_aria')}
onclick={() => {
showUnassignModal = true;
unassignMemberId = member.id;
Expand All @@ -144,17 +144,17 @@
{:else}
<span
class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 transition-colors duration-200"
title="admin"
title={$t('account.members.admin_badge')}
>
Admin
{$t('account.members.admin_badge')}
</span>
{/if}
{:else if user.id === member.id}
<span
class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 transition-colors duration-200"
title="admin"
title={$t('account.members.admin_badge')}
>
Admin
{$t('account.members.admin_badge')}
</span>
{/if}
</p>
Expand All @@ -163,7 +163,7 @@
{#if user.id !== member.id}
<button
class="hover:scale-110 transition-transform duration-200 text-red-600 p-1 cursor-pointer"
aria-label="Delete"
aria-label={$t('account.members.delete_aria')}
onclick={() => { showDeleteModal = true; deletingMemberId = member.id; }}
>
<svg xmlns="http://www.w3.org/2000/svg" width="1.5em" height="1.5em" viewBox="0 0 24 24">
Expand All @@ -183,7 +183,7 @@
</div>
{:else}
<div class="flex flex-col gap-4">
<p class="text-sm text-gray-500">Vous n'avez pas encore ajouté de membres...</p>
<p class="text-sm text-gray-500">{$t('account.members.empty_state')}</p>
<CodeClipboard code={organisation.code} />
</div>
{/if}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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')}
/>
</div>
</div>
Expand All @@ -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} <span class="text-red-500 text-xs mt-0.5 block">{$t('errors.validation_siret_format')}</span> {/if}
</div>
Expand Down
21 changes: 20 additions & 1 deletion frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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}\"?",
Expand Down Expand Up @@ -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": {
Expand Down
21 changes: 20 additions & 1 deletion frontend/src/lib/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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}\" ?",
Expand Down Expand Up @@ -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": {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/routes/(app)/mon-compte/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' };
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/(app)/mon-compte/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
{org.nom} {org.est_admin ? '(Admin)' : ''}
</option>
{/each}
<option value="new" selected={isCreatingOrg}>+ Rejoindre / Créer</option>
<option value="new" selected={isCreatingOrg}>{$t('account.organization.join_create_option')}</option>
</select>

{#if selectedOrganisation && selectedOrganisation.est_admin}
Expand Down
Loading