Total TTC
{formatValue(
diff --git a/src/app/(layout-with-navigation)/(pages-statiques)/budget/_components/SelectYear.tsx b/src/app/(layout-with-navigation)/(pages-statiques)/budget/_components/SelectYear.tsx
index 3a1227b0e..6a6c16b6f 100644
--- a/src/app/(layout-with-navigation)/(pages-statiques)/budget/_components/SelectYear.tsx
+++ b/src/app/(layout-with-navigation)/(pages-statiques)/budget/_components/SelectYear.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { ReactNode, useState } from 'react'
import budget from '../_data/budget.yaml'
diff --git a/src/app/(layout-with-navigation)/(pages-statiques)/budget/page.tsx b/src/app/(layout-with-navigation)/(pages-statiques)/budget/page.tsx
index bddd14e80..10d9d401d 100644
--- a/src/app/(layout-with-navigation)/(pages-statiques)/budget/page.tsx
+++ b/src/app/(layout-with-navigation)/(pages-statiques)/budget/page.tsx
@@ -1,5 +1,10 @@
+import MDXContent from '@/components/mdx/MDXContent'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
-import Budget from './_components/Budget'
+import contentEnBottom from '@/locales/pages/en/budgetBottom.mdx'
+import contentEnTop from '@/locales/pages/en/budgetTop.mdx'
+import contentFrBottom from '@/locales/pages/fr/budgetBottom.mdx'
+import contentFrTop from '@/locales/pages/fr/budgetTop.mdx'
+import SelectYear from './_components/SelectYear'
export async function generateMetadata() {
return getMetadataObject({
@@ -9,5 +14,11 @@ export async function generateMetadata() {
}
export default function BudgetPage() {
- return
+ return (
+ <>
+
+
+
+ >
+ )
}
diff --git a/src/app/(layout-with-navigation)/(pages-statiques)/contact/page.tsx b/src/app/(layout-with-navigation)/(pages-statiques)/contact/page.tsx
index f2c9cf0a7..e8c27550c 100644
--- a/src/app/(layout-with-navigation)/(pages-statiques)/contact/page.tsx
+++ b/src/app/(layout-with-navigation)/(pages-statiques)/contact/page.tsx
@@ -1,8 +1,10 @@
-import GithubContributionForm from '@/components/misc/GithubContributionForm'
+import Link from '@/components/Link'
import Trans from '@/components/translation/Trans'
import Card from '@/design-system/layout/Card'
import Title from '@/design-system/layout/Title'
+import Emoji from '@/design-system/utils/Emoji'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
+import Script from 'next/script'
export async function generateMetadata() {
return getMetadataObject({
@@ -14,51 +16,39 @@ export async function generateMetadata() {
export default function Contact() {
return (
-
Contact} />
-
-
- 🙋♀️{' '}
-
- J'ai une question
-
-
+
+ Contact
+ 📨
+ >
+ }
+ />
-
+
N'hésitez pas à consulter notre{' '}
- FAQ avant de nous écire, vous y
- trouverez sans doute la réponse à votre question !
+ FAQ avant de nous écrire,
+ vous y trouverez sans doute la réponse à votre question !
-
- Pour toute remarque ou question,{' '}
-
- nous vous recommandons{' '}
-
- d'ouvrir un ticket directement sur GitHub
-
- {' '}
- afin de suivre les échanges plus facilement. Vous pouvez également
- nous envoyer un message via le formulaire de contact ci-dessous.
+
+ Pour toute autre remarque ou question, vous pouvez nous envoyer un
+ message via le formulaire de contact ci-dessous.
-
-
-
+
+
-
-
- Enfin, vous avez la possibilité de nous envoyer un mail à l'adresse{' '}
-
- contact@nosgestesclimat.fr
-
- . Cependant, le délais de réponse sera plus long que les solutions
- précédentes.
-
-
+
)
}
diff --git a/src/app/(layout-with-navigation)/(pages-statiques)/international/page.tsx b/src/app/(layout-with-navigation)/(pages-statiques)/international/page.tsx
index ea78db624..dccad2784 100644
--- a/src/app/(layout-with-navigation)/(pages-statiques)/international/page.tsx
+++ b/src/app/(layout-with-navigation)/(pages-statiques)/international/page.tsx
@@ -64,7 +64,7 @@ export default async function International() {
/>
-
+
@@ -124,14 +124,14 @@ export default async function International() {
Explorez en détail les spécificités de chaque pays.
-
+
⏳️ À venir !
-
+
+
{demoDottedNames.map((el) => (
diff --git a/src/app/(layout-with-navigation)/(pages-statiques)/questions-frequentes/page.tsx b/src/app/(layout-with-navigation)/(pages-statiques)/questions-frequentes/page.tsx
index 52bc88705..58ed3a62a 100644
--- a/src/app/(layout-with-navigation)/(pages-statiques)/questions-frequentes/page.tsx
+++ b/src/app/(layout-with-navigation)/(pages-statiques)/questions-frequentes/page.tsx
@@ -1,10 +1,12 @@
+import Link from '@/components/Link'
import Trans from '@/components/translation/Trans'
+import Card from '@/design-system/layout/Card'
import Title from '@/design-system/layout/Title'
+import Emoji from '@/design-system/utils/Emoji'
import { getServerTranslation } from '@/helpers/getServerTranslation'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
import { getCurrentLangInfos } from '@/locales/translation'
import FAQListItem from './_components/FAQListItem'
-import GithubContributionCard from './_components/GithubContributionCard'
import Scroller from './_components/Scroller'
type FAQType = {
@@ -97,13 +99,20 @@ export default async function FAQPage() {
})}
-
- 🙋♀️
-
- J'ai une autre question
-
-
-
+
+
+
+ Je ne trouve pas réponse à ma question{' '}
+ 🙋♀️
+
+
+
+
+ Vous pouvez nous contacter via notre page de contact :{' '}
+ accéder à notre page de contact.
+
+
+
>
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/_components/ActionsTutorial.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/_components/ActionsTutorial.tsx
index 428179ac0..4c97d3b3c 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/_components/ActionsTutorial.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/_components/ActionsTutorial.tsx
@@ -20,7 +20,7 @@ export default function ActionsTutorial() {
const [value, unit] = getCarbonFootprint({ t, i18n }, bilan.nodeValue)
return (
-
+
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/_components/PetrolFilter.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/_components/PetrolFilter.tsx
index 884f6c0ba..1c6da0884 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/_components/PetrolFilter.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/_components/PetrolFilter.tsx
@@ -23,7 +23,7 @@ export default function PetrolFilter() {
return (
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/_components/SimulationMissing.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/_components/SimulationMissing.tsx
index 085b8ab6c..d22b3f7a7 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/_components/SimulationMissing.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/_components/SimulationMissing.tsx
@@ -11,7 +11,7 @@ type Props = {
export default function SimulationMissing({ progression }: Props) {
return (
-
+
Calcul d'empreinte carbone manquant
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/Actions.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/Actions.tsx
index 0b9a5d597..20f44ae84 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/Actions.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/Actions.tsx
@@ -88,7 +88,7 @@ export default function Actions({
/>
@@ -115,7 +115,7 @@ export default function Actions({
{radical ? numberedActions : numberedActions.slice().reverse()}
-
+
-
+
cat === dottedName?.split(' . ')?.[0]
- )
-
- const categoryRuleObject = useRule(foundCategory || 'bilan')
-
- const categoryColor =
- categoryRuleObject?.color ||
- rules[dottedName.split(' . ')[0]]?.couleur ||
- 'var(--color)'
+ const { category } = useRule(dottedName)
const currentSimulation = getCurrentSimulation()
@@ -93,14 +86,15 @@ export default function ActionCard({
id={dottedName}
className={`relative flex h-[16rem] w-full flex-col items-center overflow-auto rounded-lg border-4 border-solid ${
!hasFormula ? 'h-[13rem]' : ''
- }`}
- style={{
- borderColor: isSelected ? 'rgb(45, 164, 78)' : categoryColor,
- backgroundColor: isSelected ? 'rgba(45, 164, 78, 0.23)' : '',
- }}>
+ } ${
+ isSelected
+ ? 'border-green-500 bg-green-500/[0.23]'
+ : getBorderColor(category)
+ }`}>
+ className={`flex h-[6rem] w-full items-center ${getBackgroundColor(
+ category
+ )}`}>
@@ -136,7 +130,7 @@ export default function ActionCard({
{hasRemainingQuestions && (
setFocusedAction(dottedName)}>
{remainingQuestionsText}
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionForm.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionForm.tsx
index bce8a6f10..14d23f6ca 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionForm.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionForm.tsx
@@ -44,7 +44,7 @@ export default function ActionForm({ category, onComplete }: Props) {
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3 }}
- className="mb-4 rounded-lg bg-primaryLight p-4 text-left">
+ className="bg-primary-100 mb-4 rounded-lg p-4 text-left">
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionValue.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionValue.tsx
index 460fef0f0..7a7c2d997 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionValue.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/_components/actions/_components/ActionValue.tsx
@@ -66,7 +66,7 @@ export default function ActionValue({
return (
@@ -76,7 +76,7 @@ export default function ActionValue({
{total && relativeValue > 0 && (
-
+
{relativeValue}%
)}
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/_components/categoryFilters/_components/Filter.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/_components/categoryFilters/_components/Filter.tsx
index 2f0e529b5..f1e0bd5c7 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/_components/categoryFilters/_components/Filter.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/_components/categoryFilters/_components/Filter.tsx
@@ -1,4 +1,5 @@
'use client'
+import { getBackgroundColor } from '@/helpers/getCategoryColorClass'
import { useRule } from '@/publicodes-state'
import { useRouter, useSearchParams } from 'next/navigation'
@@ -8,7 +9,7 @@ type Props = {
}
export default function Filter({ dottedName, countByCategory }: Props) {
- const rule = useRule(dottedName)
+ const { title } = useRule(dottedName)
const router = useRouter()
@@ -17,16 +18,6 @@ export default function Filter({ dottedName, countByCategory }: Props) {
const isSelected = categorySelected === dottedName
- const getBackgroundColor = () => {
- switch (true) {
- case categorySelected && !isSelected:
- return '#aaa'
- case categorySelected === dottedName:
- default:
- return rule.color
- }
- }
-
const buildURL = () => {
const siteURL = `${window.location.origin}${window.location.pathname}`
@@ -43,7 +34,11 @@ export default function Filter({ dottedName, countByCategory }: Props) {
return (
@@ -54,8 +49,8 @@ export default function Filter({ dottedName, countByCategory }: Props) {
scroll: false,
})
}}>
- {rule.title}{' '}
-
+ {title}{' '}
+
{countByCategory[dottedName] || 0}
diff --git a/src/app/(layout-with-navigation)/(simulation)/actions/page.tsx b/src/app/(layout-with-navigation)/(simulation)/actions/page.tsx
index 3106b1297..5334c5d85 100644
--- a/src/app/(layout-with-navigation)/(simulation)/actions/page.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/actions/page.tsx
@@ -4,9 +4,8 @@ import ActionPageContent from './_components/ActionPageContent'
export async function generateMetadata() {
return getMetadataObject({
title:
- "Actions, suite à votre simulation d'empreinte climat - Nos Gestes Climat",
- description:
- 'Découvrez les actions que vous pouvez mettre en place pour réduire votre empreinte carbone.',
+ 'Actions : comment réduire votre empreinte climat ? - Nos Gestes Climat',
+ description: 'Quelles sont les actions les plus efficaces ?',
})
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/_components/CreateOtherGroupsSection.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/_components/CreateOtherGroupsSection.tsx
index 2a9c17305..a090fb896 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/_components/CreateOtherGroupsSection.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/_components/CreateOtherGroupsSection.tsx
@@ -25,12 +25,14 @@ export default function CreateOtherGroupsSection({
Vous pouvez créer un nouveau groupe avec d’autres amis.
-
- Créer un autre groupe
-
+
+
+ Créer un autre groupe
+
+
>
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/_hooks/usFetchGroups.ts b/src/app/(layout-with-navigation)/(simulation)/amis/_hooks/usFetchGroups.ts
index 4663bd369..924f08a85 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/_hooks/usFetchGroups.ts
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/_hooks/usFetchGroups.ts
@@ -3,9 +3,11 @@ import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
export function useFetchGroups(userId: string) {
- return useQuery(['groups'], () =>
- axios.get(`${GROUP_URL}/user-groups/${userId}`).then((response) => {
- return response.data
- })
- )
+ return useQuery({
+ queryKey: ['groups'],
+ queryFn: () =>
+ axios.get(`${GROUP_URL}/user-groups/${userId}`).then((response) => {
+ return response.data
+ }),
+ })
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/creer/_component/GroupCreationForm.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/creer/_component/GroupCreationForm.tsx
index 12b8c601f..32f80eda9 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/creer/_component/GroupCreationForm.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/creer/_component/GroupCreationForm.tsx
@@ -48,7 +48,7 @@ export default function GroupCreationForm() {
const router = useRouter()
- const { mutateAsync: createGroup, isLoading } = useCreateGroup()
+ const { mutateAsync: createGroup, isPending } = useCreateGroup()
const { mutateAsync: sendGroupEmail } = useSendGroupConfirmationEmail()
@@ -141,7 +141,7 @@ export default function GroupCreationForm() {
type="submit"
data-cypress-id="button-create-group"
onClick={handleSubmit}
- aria-disabled={!prenom && !isLoading}>
+ aria-disabled={!prenom && !isPending}>
{hasCompletedTest ? (
Créer le groupe
) : (
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/page.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/page.tsx
index 038800aee..a26da9c25 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/page.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/page.tsx
@@ -3,15 +3,13 @@ import AutoCanonicalTag from '@/design-system/utils/AutoCanonicalTag'
import { getServerTranslation } from '@/helpers/getServerTranslation'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
import Groups from './_components/Groups'
-import FeedbackBlock from './resultats/_components/FeedbackBlock'
import SondagesBlock from './resultats/_components/SondagesBlock'
export async function generateMetadata() {
return getMetadataObject({
- title:
- "Groupes d'ami·e·s, simulateur d’empreinte carbone - Nos Gestes Climat",
+ title: 'Calculer votre empreinte carbone avec vos amis - Nos Gestes Climat',
description:
- 'Calculez votre empreinte carbone en groupe et comparez la avec l’empreinte de vos proches grâce au simulateur de bilan carbone personnel Nos Gestes Climat.',
+ 'Comparez vos résultats avec votre famille ou un groupe d’amis.',
})
}
@@ -19,7 +17,7 @@ export default async function GroupesPage() {
const { t } = await getServerTranslation()
return (
-
+ >
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Classement.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Classement.tsx
index 02ddacce5..43649ed51 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Classement.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Classement.tsx
@@ -30,7 +30,7 @@ export default function Classement({ group }: { group: Group }) {
return (
<>
-
+
{topThreeMembers.map((member, index) => {
let rank
switch (index) {
@@ -114,7 +114,7 @@ export default function Classement({ group }: { group: Group }) {
{group.members.length > 5 && !isExpanded && (
setIsExpanded(true)}
- className="bg-Transparent mt-4 w-full border-none text-center text-sm text-primary underline">
+ className="bg-Transparent text-primary-500 mt-4 w-full border-none text-center text-sm underline">
Voir les {String(group.members.length - 5)} autre{withS} participant
{withS}
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/FeedbackBlock.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/FeedbackBlock.tsx
index e68326e51..f9ffa14f2 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/FeedbackBlock.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/FeedbackBlock.tsx
@@ -37,71 +37,71 @@ function Flask() {
className="mt-1 flex-none">
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/GroupResults.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/GroupResults.tsx
index 1f240117e..0bcc0c71e 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/GroupResults.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/GroupResults.tsx
@@ -20,7 +20,7 @@ export default function GroupResults({ groupId }: { groupId: string }) {
const { data: group, refetch } = useFetchGroup(groupId)
- const { user } = useUser()
+ const { user, setGroupToRedirectToAfterTest } = useUser()
const userId = user?.id
@@ -37,6 +37,10 @@ export default function GroupResults({ groupId }: { groupId: string }) {
groupId,
})
+ useEffect(() => {
+ setGroupToRedirectToAfterTest(undefined)
+ }, [setGroupToRedirectToAfterTest])
+
useEffect(() => {
if (groupId && !group) {
intervalRef.current = setInterval(() => refetch(), 60000)
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Results.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Results.tsx
index ef2ad9a31..88a10d8fb 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Results.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/Results.tsx
@@ -4,17 +4,20 @@ import Trans from '@/components/translation/Trans'
import GoBackLink from '@/design-system/inputs/GoBackLink'
import AutoCanonicalTag from '@/design-system/utils/AutoCanonicalTag'
import { useRouter } from 'next/navigation'
+import { useEffect } from 'react'
import EditableGroupTitle from './EditableGroupTitle'
-import FeedbackBlock from './FeedbackBlock'
import Footer from './Footer'
import GroupResults from './GroupResults'
export default function Results({ groupId }: { groupId: string }) {
const router = useRouter()
- if (!groupId) {
- router.push('/amis')
- }
+ useEffect(() => {
+ if (!groupId) {
+ router.push('/amis')
+ }
+ }, [groupId, router])
+
return (
<>
@@ -24,8 +27,6 @@ export default function Results({ groupId }: { groupId: string }) {
-
-
Le classement
diff --git a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/VotreEmpreinte.tsx b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/VotreEmpreinte.tsx
index 3d78cbdec..af95934d9 100644
--- a/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/VotreEmpreinte.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/amis/resultats/_components/VotreEmpreinte.tsx
@@ -73,7 +73,7 @@ export default function VotreEmpreinte({
)}
-
+
{formatValue(categoryObject.value / 1000, {
precision: 1,
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/FeedbackBanner.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/FeedbackBanner.tsx
index b621601c3..279e12f16 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/FeedbackBanner.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/FeedbackBanner.tsx
@@ -22,25 +22,30 @@ type Props = {
export default function FeedbackBanner({ text, type, className }: Props) {
const { t } = useClientTranslation()
- const { user, updateNorthStarRatings } = useUser()
+ const { user, updateNorthStarRatings, currentSimulationId } = useUser()
const { getNumericValue } = useEngine()
const { categories, progression } = useForm()
const hasJustAnswered = useRef(false)
const {
mutate: saveRating,
- isLoading,
+ isPending,
isSuccess,
} = useMutation({
mutationKey: ['northstar', 'post'],
mutationFn: () =>
axios
.post(SIMULATION_URL, {
- results: progression > 0 && {
- categories: categories.map((category) => getNumericValue(category)),
- total: getNumericValue('bilan'),
+ data: {
+ results: progression > 0 && {
+ categories: categories.map((category) =>
+ getNumericValue(category)
+ ),
+ total: getNumericValue('bilan'),
+ },
+ ratings: user.northStarRatings,
},
- ratings: user.northStarRatings,
+ id: currentSimulationId,
})
.then((response) => response.data)
.catch((error) => captureException(error)),
@@ -82,7 +87,7 @@ export default function FeedbackBanner({ text, type, className }: Props) {
{text}
-
+
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/GetResultsByEmail.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/GetResultsByEmail.tsx
index b361e580d..4db83855b 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/GetResultsByEmail.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/GetResultsByEmail.tsx
@@ -25,7 +25,7 @@ export default function GetResultsByEmail({
const {
mutate: subscribeUser,
- isLoading,
+ isPending,
isSuccess,
isError,
error,
@@ -34,7 +34,7 @@ export default function GetResultsByEmail({
function handleSubmit(event: React.FormEvent) {
event.preventDefault()
- if (isLoading || !simulation) return
+ if (isPending || !simulation) return
trackEvent(matomoSaveSimulationByGivingEmail)
@@ -104,7 +104,7 @@ export default function GetResultsByEmail({
null}
type="submit"
- disabled={isLoading}
+ disabled={isPending}
className="mt-4">
Envoyer
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/GroupModePromotionBanner.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/GroupModePromotionBanner.tsx
index a4b5d94eb..f9068c78c 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/GroupModePromotionBanner.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/GroupModePromotionBanner.tsx
@@ -15,12 +15,12 @@ export default async function GroupModePromotionBanner({
return (
{
+ // The URL includes matching results, we assume the user has done the test
+ if (!detailsParamString.includes(details) && progression !== 1) {
+ router.push(progression > 0 ? '/simulateur/bilan' : '/tutoriel')
+ }
+ }, [categories, details, progression, router, detailsParamString])
+
+ return null
+}
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/Results.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/Results.tsx
index 634867f58..b47c2fa6d 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/Results.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/Results.tsx
@@ -1,10 +1,26 @@
+'use client'
+
import Trans from '@/components/translation/Trans'
import Separator from '@/design-system/layout/Separator'
+import { useEngine, useSimulation } from '@/publicodes-state'
+import { useMemo } from 'react'
import CategoriesAccordion from './results/CategoriesAccordion'
import CategoriesChart from './results/CategoriesChart'
import TotalCard from './results/TotalCard'
export default function Results() {
+ const { categories } = useSimulation()
+ const { getNumericValue } = useEngine()
+
+ const sortedCategories = useMemo(() => {
+ return categories.sort((categoryA, categoryB) => {
+ const valueA = getNumericValue(categoryA) ?? 0
+ const valueB = getNumericValue(categoryB) ?? 0
+
+ return valueB - valueA
+ })
+ }, [categories, getNumericValue])
+
return (
<>
@@ -14,10 +30,10 @@ export default function Results() {
-
+
-
+
>
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/CategoriesAccordion.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/CategoriesAccordion.tsx
index d15640280..9061ee6dd 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/CategoriesAccordion.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/CategoriesAccordion.tsx
@@ -4,14 +4,18 @@ import Accordion from '@/design-system/layout/Accordion'
import { useForm, useRule } from '@/publicodes-state'
import AccordionItemWithRule from './categoriesAccordion/AccordionItemWithRule'
-export default function CategoriesAccordion() {
+type Props = {
+ sortedCategories: string[]
+}
+
+export default function CategoriesAccordion({ sortedCategories }: Props) {
const { categories } = useForm()
const { numericValue: maxCategoryValue } = useRule(categories?.[0] ?? '')
return (
- {categories.map((categoryDottedName, index) => {
+ {sortedCategories.map((categoryDottedName, index) => {
return (
{
- return categories.sort((categoryA, categoryB) => {
- const valueA = getNumericValue(categoryA) ?? 0
- const valueB = getNumericValue(categoryB) ?? 0
-
- return valueB - valueA
- })
- }, [categories, getNumericValue])
-
+type Props = {
+ sortedCategories: string[]
+ className?: string
+}
+export default function CategoriesChart({
+ sortedCategories,
+ className,
+}: Props) {
const { numericValue: firstCategoryValue } = useRule(sortedCategories[0])
return (
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/TotalCard.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/TotalCard.tsx
index 031ef0b1e..769ae617c 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/TotalCard.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/TotalCard.tsx
@@ -16,7 +16,7 @@ export default function TotalCard() {
const { formattedValue, unit } = formatCarbonFootprint(numericValue)
return (
-
+
{formattedValue} {' '}
@@ -24,8 +24,8 @@ export default function TotalCard() {
- de CO₂-e{' '}
- chaque année
+ de CO₂-e{' '}
+ chaque année
- Qu'est-ce que ça veut dire ?
+ Qu'est-ce que ça veut dire ?
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/AccordionItemWithRule.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/AccordionItemWithRule.tsx
index 57e4e79cb..28c97090b 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/AccordionItemWithRule.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/AccordionItemWithRule.tsx
@@ -18,8 +18,6 @@ export default function AccordionItemWithRule({
const percentageOfTotalValue =
(1 - (maxValue - numericValue) / maxValue) * 0.9
- const isReadOnly = dottedName === 'services sociétaux'
-
return (
{icons} {' '}
+ className={`mb-0 underline decoration-dotted underline-offset-4`}>
{title}
@@ -48,7 +42,6 @@ export default function AccordionItemWithRule({
icons={icons || ''}
dottedName={dottedName}
content={ }
- isReadOnly={isReadOnly}
/>
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/accordionItemWithRule/subcategoriesList/SubcategoryListItem.tsx b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/accordionItemWithRule/subcategoriesList/SubcategoryListItem.tsx
index db7663f6c..b55daa248 100644
--- a/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/accordionItemWithRule/subcategoriesList/SubcategoryListItem.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/fin/_components/results/categoriesAccordion/accordionItemWithRule/subcategoriesList/SubcategoryListItem.tsx
@@ -31,7 +31,7 @@ export default function SubcategoryListItem({
{title}
-
+
{formatValue(roundValue(numericValue), { precision: 0 })}
{' '}
@@ -41,7 +41,7 @@ export default function SubcategoryListItem({
+
+
diff --git a/src/app/(layout-with-navigation)/(simulation)/plan-du-site/_components/LinkList.tsx b/src/app/(layout-with-navigation)/(simulation)/plan-du-site/_components/LinkList.tsx
new file mode 100644
index 000000000..bcab43431
--- /dev/null
+++ b/src/app/(layout-with-navigation)/(simulation)/plan-du-site/_components/LinkList.tsx
@@ -0,0 +1,19 @@
+'use client'
+
+import Link from '@/components/Link'
+
+type LinkListProps = {
+ entries: Record
+}
+
+export default function LinkList({ entries }: LinkListProps) {
+ return (
+
+ {Object.entries(entries).map(([linkKey, { title, href }]) => (
+
+ {title}
+
+ ))}
+
+ )
+}
diff --git a/src/app/(layout-with-navigation)/(simulation)/plan-du-site/page.tsx b/src/app/(layout-with-navigation)/(simulation)/plan-du-site/page.tsx
index 7dfa22fbf..db540bbf1 100644
--- a/src/app/(layout-with-navigation)/(simulation)/plan-du-site/page.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/plan-du-site/page.tsx
@@ -1,8 +1,9 @@
-import Link from '@/components/Link'
import Trans from '@/components/translation/Trans'
import Title from '@/design-system/layout/Title'
+import { getServerTranslation } from '@/helpers/getServerTranslation'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
import Actions from './_components/Actions'
+import LinkList from './_components/LinkList'
export async function generateMetadata() {
return getMetadataObject({
@@ -12,32 +13,82 @@ export async function generateMetadata() {
})
}
-const links = {
- 'Nos outils': {
- 'publicodes.planDuSite.bilan': '/simulateur/bilan',
- 'publicodes.planDuSite.profil': '/profil',
- 'publicodes.planDuSite.personas': '/personas',
- 'publicodes.planDuSite.actions': '/actions',
- 'publicodes.planDuSite.actionsPlus': '/actions/plus',
- },
- Informations: {
- 'publicodes.planDuSite.nouveautes': '/nouveautes',
- 'publicodes.planDuSite.aPropos': '/a-propos',
- 'publicodes.planDuSite.contact': '/contact',
- 'publicodes.planDuSite.viePrivee': '/vie-privee',
- 'publicodes.planDuSite.partenaires': '/partenaires',
- 'publicodes.planDuSite.faq': '/questions-frequentes',
- 'publicodes.planDuSite.stats': '/stats',
- Blog: '/blog',
- },
- Documentations: {
- 'publicodes.planDuSite.guide': '/guide',
- 'publicodes.planDuSite.modele': '/modele',
- 'publicodes.planDuSite.documentation': '/documentation',
- },
-}
+export default async function PlanDuSitePage() {
+ const { t } = await getServerTranslation()
+
+ const links = {
+ 'Nos outils': {
+ bilan: {
+ title: t('Le test'),
+ href: '/simulateur/bilan',
+ },
+ profil: {
+ title: t('Votre profil'),
+ href: '/profil',
+ },
+ personas: {
+ title: t('Nos utilisateurs types'),
+ href: '/personas',
+ },
+ actions: {
+ title: t('Nos actions pour réduire votre empreinte'),
+ href: '/actions',
+ },
+ actionsPlus: {
+ title: t('Les actions phares'),
+ href: '/actions-plus',
+ },
+ },
+ Informations: {
+ nouveautes: {
+ title: t('Nouveautés'),
+ href: '/nouveautes',
+ },
+ aPropos: {
+ title: t('À propos'),
+ href: '/a-propos',
+ },
+ contact: {
+ title: t('Contact'),
+ href: '/contact',
+ },
+ viePrivee: {
+ title: t('Vie privée'),
+ href: '/vie-privee',
+ },
+ partenaires: {
+ title: t('Partenaires'),
+ href: '/partenaires',
+ },
+ faq: {
+ title: t('FAQ'),
+ href: '/faq',
+ },
+ stats: {
+ title: t('Statistiques'),
+ href: '/stats',
+ },
+ Blog: {
+ title: t('Blog'),
+ href: '/blog',
+ },
+ },
+ Documentations: {
+ guide: {
+ title: t('Nos guides thématiques'),
+ href: '/documentation/guide',
+ },
+ modele: {
+ title: t('Le modèle Nos Gestes Climat'),
+ href: '/documentation/modele',
+ },
+ documentation: {
+ title: t('Documentation'),
+ href: '/documentation',
+ },
+ },
+ }
-export default function PlanDuSitePage() {
return (
- {Object.entries(links).map(([categoryTitle, categoryLinks]) => (
-
-
- {categoryTitle}
-
-
- {Object.entries(categoryLinks).map(([linkKey, linkUrl]) => (
-
-
- {linkKey}
-
-
- ))}
-
-
- ))}
+
+
+
+
+
diff --git a/src/app/(layout-with-navigation)/(simulation)/profil/_components/SimulationBanner.tsx b/src/app/(layout-with-navigation)/(simulation)/profil/_components/SimulationBanner.tsx
index f4acc2262..5a6699ba3 100644
--- a/src/app/(layout-with-navigation)/(simulation)/profil/_components/SimulationBanner.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/profil/_components/SimulationBanner.tsx
@@ -15,5 +15,5 @@ export default function SimulationBanner() {
return
}
- return
+ return
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/Category.tsx b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/Category.tsx
index 1b05f5123..0059a1b39 100644
--- a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/Category.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/Category.tsx
@@ -1,6 +1,10 @@
'use client'
import formatCarbonFootprint from '@/helpers/formatCarbonFootprint'
+import {
+ getBackgroundColor,
+ getTextColor,
+} from '@/helpers/getCategoryColorClass'
import { useForm, useRule } from '@/publicodes-state'
import { useState } from 'react'
import Subcategory from './category/Subcategory'
@@ -10,7 +14,7 @@ type Props = {
}
export default function Category({ category }: Props) {
- const { title, value, icons, color } = useRule(category)
+ const { title, value, icons } = useRule(category)
const { subcategories } = useForm()
const [isOpen, setIsOpen] = useState(false)
@@ -23,12 +27,14 @@ export default function Category({ category }: Props) {
className="block w-full"
onClick={() => setIsOpen((prevIsOpen) => !prevIsOpen)}>
+ className={`mb-0 flex w-full items-center justify-between gap-4 rounded-lg p-4 text-white ${getBackgroundColor(
+ category
+ )}`}>
{icons} {title}{' '}
+ className={`block rounded-lg bg-white px-4 py-2 text-lg ${getTextColor(
+ category
+ )}`}>
{formattedCarbonFootprint.formattedValue}{' '}
{formattedCarbonFootprint.unit}
diff --git a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/Subcategory.tsx b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/Subcategory.tsx
index eb2507322..a551b9f8f 100644
--- a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/Subcategory.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/Subcategory.tsx
@@ -1,6 +1,7 @@
'use client'
import formatCarbonFootprint from '@/helpers/formatCarbonFootprint'
+import { getBackgroundColor } from '@/helpers/getCategoryColorClass'
import { useForm, useRule } from '@/publicodes-state'
import { useState } from 'react'
import Question from './subcategory/Question'
@@ -10,14 +11,14 @@ type Props = {
}
export default function SubCategory({ subcategory }: Props) {
- const { title, value, icons, color } = useRule(subcategory)
+ const { title, value, icons, category } = useRule(subcategory)
const { relevantAnsweredQuestions } = useForm()
const [isOpen, setIsOpen] = useState(false)
const formattedCarbonFootprint = formatCarbonFootprint(value)
- //TODO: investigate why subcategory = repas and questions = plats
+ //TODO: Model shenanigans: investigate why subcategory = repas and questions = plats
const answeredQuestionOfSubcategory = relevantAnsweredQuestions.filter(
(question) =>
question.includes(subcategory) ||
@@ -26,10 +27,11 @@ export default function SubCategory({ subcategory }: Props) {
if (!answeredQuestionOfSubcategory.length) return null
return (
-
+
setIsOpen((prevIsOpen) => !prevIsOpen)}
diff --git a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/Question.tsx b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/Question.tsx
index cc5dac85f..8b4acb706 100644
--- a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/Question.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/Question.tsx
@@ -13,8 +13,15 @@ type Props = {
export default function Question({ question }: Props) {
const { t } = useClientTranslation()
- const { label, value, displayValue, unit, type, questionsOfMosaic } =
- useRule(question)
+ const {
+ label,
+ value,
+ displayValue,
+ unit,
+ type,
+ questionsOfMosaic,
+ isMissing,
+ } = useRule(question)
return (
{label}
-
- {type === 'number' && (
-
- )}
- {type === 'boolean' && (
- {t(displayValue.toString())}
- )}
- {type === 'choices' && (
-
- )}
-
+ {!isMissing ? (
+
+ {type === 'number' && (
+
+ )}
+ {type === 'boolean' && (
+ {t(displayValue.toString())}
+ )}
+ {type === 'choices' && (
+
+ )}
+
+ ) : null}
{questionsOfMosaic.length ? (
{questionsOfMosaic.map((questionOfMosaic) => (
-
+
))}
) : null}
diff --git a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/question/MosaicQuestion.tsx b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/question/MosaicQuestion.tsx
index 61ec84df1..bda8606a1 100644
--- a/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/question/MosaicQuestion.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/profil/_components/answerList/category/subcategory/question/MosaicQuestion.tsx
@@ -5,29 +5,34 @@ import NumberValue from '@/components/misc/NumberValue'
import { useClientTranslation } from '@/hooks/useClientTranslation'
import { useRule } from '@/publicodes-state'
-type Props = { question: string }
+type Props = {
+ question: string
+ isMissing: boolean
+}
-export default function MosaicQuestion({ question }: Props) {
+export default function MosaicQuestion({ question, isMissing }: Props) {
const { t } = useClientTranslation()
const { value, displayValue, unit, type, parent } = useRule(question)
const { title, icons } = useRule(parent)
return (
-
+
{icons} {title}
-
- {type === 'number' && (
-
- )}
- {type === 'boolean' && (
- {t(displayValue.toString())}
- )}
- {type === 'choices' && (
-
- )}
-
+ {!isMissing ? (
+
+ {type === 'number' && (
+
+ )}
+ {type === 'boolean' && (
+ {t(displayValue.toString())}
+ )}
+ {type === 'choices' && (
+
+ )}
+
+ ) : null}
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/profil/_components/localisation/RegionSelector.tsx b/src/app/(layout-with-navigation)/(simulation)/profil/_components/localisation/RegionSelector.tsx
index 6d59d8b84..31f579458 100644
--- a/src/app/(layout-with-navigation)/(simulation)/profil/_components/localisation/RegionSelector.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/profil/_components/localisation/RegionSelector.tsx
@@ -35,14 +35,13 @@ export default function RegionSelector({
const { isFetching } = useRules({
lang: locale,
region: region?.code ?? 'FR',
- isOptim: false,
})
return (
<>
diff --git a/src/app/(layout-with-navigation)/(simulation)/profil/_components/simulationBanner/SimulationStarted.tsx b/src/app/(layout-with-navigation)/(simulation)/profil/_components/simulationBanner/SimulationStarted.tsx
index 4619e207b..5d24f0977 100644
--- a/src/app/(layout-with-navigation)/(simulation)/profil/_components/simulationBanner/SimulationStarted.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/profil/_components/simulationBanner/SimulationStarted.tsx
@@ -3,23 +3,23 @@ import Trans from '@/components/translation/Trans'
import Button from '@/design-system/inputs/Button'
import ButtonLink from '@/design-system/inputs/ButtonLink'
import Card from '@/design-system/layout/Card'
+import Emoji from '@/design-system/utils/Emoji'
import ProgressCircle from '@/design-system/utils/ProgressCircle'
+import { formatResultToDetailParam } from '@/helpers/url/formatResultToDetailParam'
import { useClientTranslation } from '@/hooks/useClientTranslation'
-import { useForm, useUser } from '@/publicodes-state'
-import { Simulation } from '@/publicodes-state/types'
+import { useActions, useEngine, useForm, useUser } from '@/publicodes-state'
import TutorialLink from './_components/TutorialLink'
-type Props = {
- currentSimulation: Simulation
-}
-export default function SimulationStarted({ currentSimulation }: Props) {
+export default function SimulationStarted() {
const { t } = useClientTranslation()
- const { progression, relevantAnsweredQuestions } = useForm()
+ const { getValue } = useEngine()
+
+ const { progression, relevantAnsweredQuestions, categories } = useForm()
const { initSimulation } = useUser()
- const actionChoicesLength = currentSimulation?.actionChoices?.length || 0
+ const { chosenActions, declinedActions } = useActions()
const isFinished = progression === 1
@@ -31,10 +31,12 @@ export default function SimulationStarted({ currentSimulation }: Props) {
{t('publicodes.Profil.recap', {
percentFinished: (progression * 100).toFixed(0),
answeredQuestionsLength: relevantAnsweredQuestions.length,
- actionChoicesLength,
+ chosenActions: chosenActions.length,
+ declinedActions: declinedActions.length,
})}{' '}
+
@@ -52,6 +54,20 @@ export default function SimulationStarted({ currentSimulation }: Props) {
+ {isFinished && (
+
+
+ 👀 Voir mon résultat
+
+
+ )}
+
{!isFinished && (
+ everyQuestions.sort(
+ (a, b) =>
+ categories.indexOf(getCategory(a)) -
+ categories.indexOf(getCategory(b))
+ ),
+ [everyQuestions, categories, getCategory]
+ )
+
+ return (
+
+ {orderedQuestions.map((question) => (
+
+ ))}
+
+ )
+}
diff --git a/src/app/(layout-with-navigation)/(simulation)/questions/_components/questions/Question.tsx b/src/app/(layout-with-navigation)/(simulation)/questions/_components/questions/Question.tsx
new file mode 100644
index 000000000..82b3313a7
--- /dev/null
+++ b/src/app/(layout-with-navigation)/(simulation)/questions/_components/questions/Question.tsx
@@ -0,0 +1,10 @@
+'use client'
+
+import { useRule } from '@/publicodes-state'
+
+type Props = { question: string }
+
+export default function Question({ question }: Props) {
+ const { label } = useRule(question)
+ return {label}
+}
diff --git a/src/app/(layout-with-navigation)/(simulation)/questions/page.tsx b/src/app/(layout-with-navigation)/(simulation)/questions/page.tsx
new file mode 100644
index 000000000..0407140a3
--- /dev/null
+++ b/src/app/(layout-with-navigation)/(simulation)/questions/page.tsx
@@ -0,0 +1,23 @@
+import Trans from '@/components/translation/Trans'
+import Title from '@/design-system/layout/Title'
+import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
+import Questions from './_components/Questions'
+
+export async function generateMetadata() {
+ return getMetadataObject({
+ title: 'Liste des questions - Nos Gestes Climat',
+ description:
+ 'Calculez votre empreinte sur le climat en 10 minutes chrono. Découvrez les gestes qui comptent vraiment pour le climat.',
+ })
+}
+
+export default function QuestionsPage() {
+ return (
+ <>
+
+ Questions
+
+
+ >
+ )
+}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/Faq.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/Faq.tsx
index 96eb4266f..4af20cb3f 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/Faq.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/Faq.tsx
@@ -11,7 +11,7 @@ export default function Faq() {
if (isIframeOnlySimulation) return null
return (
-
+
Une question, un problème ?
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Charts.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Charts.tsx
index 9b96911c3..c2af2ca44 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Charts.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Charts.tsx
@@ -1,38 +1,9 @@
-import { useForm } from '@/publicodes-state'
-import { useState } from 'react'
-import BarChart from './charts/BarChart'
import InlineChart from './charts/InlineChart'
export default function Charts() {
- const { currentCategory } = useForm()
- const [isBarChartVisible, setIsBarChartVisible] = useState(false)
- if (!currentCategory) return
return (
-
- setIsBarChartVisible(
- (prevIsBarChartVisible) => !prevIsBarChartVisible
- )
- }>
-
-
-
-
- {isBarChartVisible ?
: null}
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Form.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Form.tsx
index 89e2892b3..886362d6e 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Form.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/Form.tsx
@@ -73,7 +73,7 @@ export default function Form() {
}
return (
-
+
{questions[currentQuestion] ? (
questions[currentQuestion]
@@ -93,7 +93,7 @@ export default function Form() {
return
}
router.push(
- `/fin?diapo=bilan&${formatResultToDetailParam({
+ `/fin?${formatResultToDetailParam({
categories,
getValue,
})}`
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/BarChart.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/BarChart.tsx
deleted file mode 100644
index 2f45f47bf..000000000
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/BarChart.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { useEngine, useForm } from '@/publicodes-state'
-import { useMemo, useState } from 'react'
-import { Flipped, Flipper } from 'react-flip-toolkit'
-
-import Category from './barChart/Category'
-
-export default function BarChart() {
- const { categories, currentCategory } = useForm()
-
- const { getNumericValue } = useEngine()
-
- const [isOpen, setIsOpen] = useState(null)
-
- const sortedCategories = useMemo(
- () =>
- categories.sort((a: string, b: string) => {
- const valueOfA = getNumericValue(a) || 0
- const valueOfB = getNumericValue(b) || 0
- return valueOfA > valueOfB ? -1 : 1
- }),
- [categories, getNumericValue]
- )
-
- const max = useMemo(() => {
- const maxValue = getNumericValue(sortedCategories[0]) || 0
- return maxValue > 5000 ? maxValue : 5000
- }, [sortedCategories, getNumericValue])
-
- return (
-
category).join('')}>
- {sortedCategories.map((category: string) => (
-
-
-
- ))}
-
- )
-}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/InlineChart.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/InlineChart.tsx
index 4cf9a9756..709ef76d3 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/InlineChart.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/InlineChart.tsx
@@ -1,10 +1,12 @@
+import { useForm } from '@/publicodes-state'
import CategoriesChart from './inlineChart/CategoriesChart'
import SubcategoriesChart from './inlineChart/SubcategoriesChart'
export default function InlineChart() {
+ const { currentCategory } = useForm()
return (
-
+ {currentCategory ? : null}
)
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/barChart/Category.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/barChart/Category.tsx
deleted file mode 100644
index da2338f6f..000000000
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/barChart/Category.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { useRule } from '@/publicodes-state'
-
-import BarChartItem from '@/components/misc/BarChartItem'
-import Subcategories from './category/Subcategories'
-
-type Props = {
- category: string
- max: number
- current: boolean
- isOpen: boolean
- setIsOpen: any
-}
-
-export default function Category({
- category,
- max,
- isOpen,
- setIsOpen,
- ...props
-}: Props) {
- const { title, icons, color, numericValue } = useRule(category)
-
- return (
-
- {
- setIsOpen((previsOpen: string | null) =>
- previsOpen === category ? null : category
- )
- }}
- />
- {isOpen ? : null}
-
- )
-}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/barChart/category/Subcategories.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/barChart/category/Subcategories.tsx
deleted file mode 100644
index 084feaf51..000000000
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/barChart/category/Subcategories.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { useEngine, useForm } from '@/publicodes-state'
-import { useMemo } from 'react'
-import { Flipped, Flipper } from 'react-flip-toolkit'
-
-import Subcategory from '@/components/misc/Subcategory'
-
-type Props = {
- category: string
- max: number
-}
-export default function Subcategories({ category, max }: Props) {
- const { subcategories } = useForm()
-
- const { getNumericValue, checkIfValid } = useEngine()
-
- const sortedSubcategories = useMemo(
- () =>
- subcategories[category]
- .filter((subcategory: string) => checkIfValid(subcategory))
- .sort((a: string, b: string) =>
- getNumericValue(a) > getNumericValue(b) ? -1 : 1
- ),
- [subcategories, category, getNumericValue, checkIfValid]
- )
-
- return (
-
subcategory)
- .join()}>
- {sortedSubcategories.map((subcategory: string) => (
-
-
-
- ))}
-
- )
-}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/inlineChart/SubcategoriesChart.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/inlineChart/SubcategoriesChart.tsx
index 60f21f973..2af734e52 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/inlineChart/SubcategoriesChart.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/charts/inlineChart/SubcategoriesChart.tsx
@@ -1,4 +1,5 @@
import ValueChangeDisplay from '@/components/misc/ValueChangeDisplay'
+import { getBackgroundColor } from '@/helpers/getCategoryColorClass'
import { useEngine, useForm, useRule } from '@/publicodes-state'
import { useMemo } from 'react'
import Subcategory from './subcategoriesChart/Subcategory'
@@ -6,8 +7,8 @@ import Subcategory from './subcategoriesChart/Subcategory'
export default function SubcategoriesChart() {
const { subcategories, currentCategory } = useForm()
- const { numericValue: total } = useRule(currentCategory || '')
- const { title, color } = useRule(currentCategory || '')
+ const { title, numericValue: total } = useRule(currentCategory || '')
+
const { checkIfValid } = useEngine()
const filteredSubcategories = useMemo(
@@ -30,7 +31,10 @@ export default function SubcategoriesChart() {
-
+
{filteredSubcategories.map((subcategory: string, index: number) => (
trackEvent(getMatomoEventClickCategoryGraph(category))}>
{current ? (
) : null}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/CategoryIntroduction.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/CategoryIntroduction.tsx
deleted file mode 100644
index 3a8fe1e0d..000000000
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/CategoryIntroduction.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import Trans from '@/components/translation/Trans'
-import Button from '@/design-system/inputs/Button'
-import { useRule } from '@/publicodes-state'
-import Image from 'next/image'
-
-type Props = {
- category: string
- startCategory: any
-}
-
-export default function CategoryIntroduction({
- category,
- startCategory,
-}: Props) {
- const { title, color } = useRule(category)
- return (
-
-
{title}
-
-
- Commencer
-
-
- )
-}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/ColorIndicator.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/ColorIndicator.tsx
index 647fb5bc3..759965f2d 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/ColorIndicator.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/ColorIndicator.tsx
@@ -1,3 +1,4 @@
+import { getBackgroundColor } from '@/helpers/getCategoryColorClass'
import { useRule } from '@/publicodes-state'
type Props = {
@@ -5,12 +6,13 @@ type Props = {
}
export default function ColorIndicator({ question }: Props) {
- const { color } = useRule(question)
+ const { category } = useRule(question)
return (
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/TestCompleted.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/TestCompleted.tsx
index db8a720f9..ee9b61f4b 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/TestCompleted.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/TestCompleted.tsx
@@ -12,7 +12,7 @@ export default function TestCompleted() {
const detailsParamString = formatResultToDetailParam({ categories, getValue })
return (
-
+
Vous avez terminé le test
@@ -20,9 +20,7 @@ export default function TestCompleted() {
+ href={`/fin${detailsParamString ? `?${detailsParamString}` : ''}`}>
Voir mon résultat
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/_hooks/useUpdateGroupAndRedirectToGroup.ts b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/_hooks/useUpdateGroupAndRedirectToGroup.ts
index 7b0fa9f5d..c3c52f79b 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/_hooks/useUpdateGroupAndRedirectToGroup.ts
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/form/_hooks/useUpdateGroupAndRedirectToGroup.ts
@@ -5,8 +5,7 @@ import { useRouter } from 'next/navigation'
import { useFetchUpdateGroupMember } from './useFetchUpdateGroupMember'
export function useUpdateGroupAndRedirectToGroup() {
- const { setGroupToRedirectToAfterTest, user, getCurrentSimulation } =
- useUser()
+ const { user, getCurrentSimulation } = useUser()
const { getValue } = useEngine()
@@ -21,8 +20,6 @@ export function useUpdateGroupAndRedirectToGroup() {
}) {
const groupId = group?._id
- setGroupToRedirectToAfterTest(undefined)
-
const results = getSimulationResults({
getValue,
})
@@ -35,8 +32,6 @@ export function useUpdateGroupAndRedirectToGroup() {
})
router.push(`/amis/resultats?groupId=${groupId}`)
-
- return
}
return handleUpdateGroupAndRedirectToGroup
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/summary/Question.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/summary/Question.tsx
index 4ac79c1be..9a94960b1 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/summary/Question.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/_components/simulateur/summary/Question.tsx
@@ -2,6 +2,8 @@ import ChoicesValue from '@/components/misc/ChoicesValue'
import NumberValue from '@/components/misc/NumberValue'
import Trans from '@/components/translation/Trans'
import { getMatomoEventClickQuestionsListLink } from '@/constants/matomo'
+import foldEveryQuestionsUntil from '@/helpers/foldEveryQuestionsUntil'
+import { getBackgroundColor } from '@/helpers/getCategoryColorClass'
import { useDebug } from '@/hooks/useDebug'
import { useForm, useRule } from '@/publicodes-state'
import { trackEvent } from '@/utils/matomo/trackEvent'
@@ -13,25 +15,41 @@ type Props = {
const statusClassNames = {
missing: 'bg-gray-100 text-gray-500',
- current: 'border-2 border-primary',
- default: 'bg-primaryLight',
+ current: 'border-2 border-primary-500 bg-primary-300',
+ default: 'bg-primary-200',
}
export default function Question({ question, toggleQuestionList }: Props) {
- const { label, isMissing, value, displayValue, unit, type, color } =
- useRule(question)
+ const {
+ label,
+ isMissing,
+ isFolded,
+ value,
+ displayValue,
+ unit,
+ type,
+ category,
+ addFoldedStep,
+ } = useRule(question)
- const { currentQuestion, setCurrentQuestion } = useForm()
+ const { currentQuestion, setCurrentQuestion, relevantQuestions } = useForm()
const isDebug = useDebug()
const status =
- currentQuestion === question ? 'current' : isMissing ? 'missing' : 'default'
+ currentQuestion === question ? 'current' : isFolded ? 'default' : 'missing'
return (
{
+ if (isDebug) {
+ foldEveryQuestionsUntil({
+ question,
+ relevantQuestions,
+ addFoldedStep,
+ })
+ }
setCurrentQuestion(question)
trackEvent(getMatomoEventClickQuestionsListLink(question))
@@ -39,8 +57,9 @@ export default function Question({ question, toggleQuestionList }: Props) {
toggleQuestionList()
}}>
{isDebug ? (
@@ -51,11 +70,11 @@ export default function Question({ question, toggleQuestionList }: Props) {
label
)}
-
- {displayValue !== 'mosaic' ? (
+ {!isMissing && displayValue !== 'mosaic' ? (
+
{type === 'number' && (
@@ -65,8 +84,8 @@ export default function Question({ question, toggleQuestionList }: Props) {
)}
- ) : null}
-
+
+ ) : null}
)
}
diff --git a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/page.tsx b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/page.tsx
index 15b5fda6d..513538e97 100644
--- a/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/page.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/simulateur/[root]/page.tsx
@@ -1,5 +1,3 @@
-import Trans from '@/components/translation/Trans'
-import Title from '@/design-system/layout/Title'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
import { FormProvider } from '@/publicodes-state'
import Faq from './_components/Faq'
@@ -19,9 +17,6 @@ export async function generateMetadata() {
export default function SimulateurPage({ params }: Props) {
return (
-
-
Votre bilan climat personnel} />
-
diff --git a/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AutresQuestions.tsx b/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AutresQuestions.tsx
index 22132b8db..cd6f9f48f 100644
--- a/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AutresQuestions.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AutresQuestions.tsx
@@ -9,7 +9,7 @@ export default function AutresQuestions() {
-
+
C’est quoi mon empreinte carbone ?
@@ -45,7 +45,7 @@ export default function AutresQuestions() {
-
+
Comment on la mesure ?
@@ -114,7 +114,7 @@ export default function AutresQuestions() {
-
+
D’où vient mon empreinte ?
diff --git a/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AvantDeCommencer.tsx b/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AvantDeCommencer.tsx
index a0e6c3847..1115906e3 100644
--- a/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AvantDeCommencer.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/tutoriel/_components/AvantDeCommencer.tsx
@@ -2,14 +2,14 @@ import Trans from '@/components/translation/Trans'
export default function AvantDeCommencer() {
return (
-
+
💡
-
+
Avant de commencer
diff --git a/src/app/(layout-with-navigation)/(simulation)/tutoriel/page.tsx b/src/app/(layout-with-navigation)/(simulation)/tutoriel/page.tsx
index cbb138905..9e532b159 100644
--- a/src/app/(layout-with-navigation)/(simulation)/tutoriel/page.tsx
+++ b/src/app/(layout-with-navigation)/(simulation)/tutoriel/page.tsx
@@ -10,7 +10,7 @@ import AvantDeCommencer from './_components/AvantDeCommencer'
export async function generateMetadata() {
return getMetadataObject({
- title: "Tutoriel du simulateur d'empreinte climat - Nos Gestes Climat",
+ title: 'Calculer votre empreinte carbone individuelle - Nos Gestes Climat',
description:
'Comprenez comment calculer votre empreinte sur le climat en 10min chrono.',
})
diff --git a/src/app/(layout-with-navigation)/_components/MobileHeader.tsx b/src/app/(layout-with-navigation)/_components/MobileHeader.tsx
deleted file mode 100644
index 00e1983bc..000000000
--- a/src/app/(layout-with-navigation)/_components/MobileHeader.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import Logo from '@/components/misc/Logo'
-
-export default function MobileHeader() {
- return (
-
-
-
- )
-}
diff --git a/src/app/(layout-with-navigation)/_components/Navigation.tsx b/src/app/(layout-with-navigation)/_components/Navigation.tsx
deleted file mode 100644
index 1e9d522c9..000000000
--- a/src/app/(layout-with-navigation)/_components/Navigation.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-'use client'
-
-// import { loadPreviousSimulation, resetLocalisation } from '@/actions/actions'
-import ProgressCircle from '@/design-system/utils/ProgressCircle'
-import CardGameIcon from '../../../components/icons/CardGameIcon'
-
-import Logo from '@/components/misc/Logo'
-import Trans from '@/components/translation/Trans'
-
-import { useClientTranslation } from '@/hooks/useClientTranslation'
-import { useDebug } from '@/hooks/useDebug'
-import { useUser } from '@/publicodes-state'
-import { capitalizeString } from '@/utils/capitalizeString'
-import Image from 'next/image'
-import NavLink from './navigation/NavLink'
-import PRIndicator from './navigation/PRIndicator'
-
-const ActionsInteractiveIcon = ({ className = '' }) => {
- const actionChoices = {}
- const count = Object.values(actionChoices).filter((a) => a === true).length
- return
-}
-
-const openmojis = {
- test: '25B6',
- action: 'E10C',
- conference: '1F3DF',
- sondage: '1F4CA',
- profile: 'silhouette',
- silhouettes: 'silhouettes',
- personas: '1F465',
- github: 'E045',
-}
-
-export const openmojiURL = (name: keyof typeof openmojis) =>
- `/images/misc/${openmojis[name]}.svg`
-
-export const actionImg = openmojiURL('action')
-export const conferenceImg = openmojiURL('conference')
-
-export default function Navigation() {
- const { t } = useClientTranslation()
-
- const isDebug = useDebug()
-
- const enquete = ''
-
- const { getCurrentSimulation } = useUser()
-
- const persona: string | undefined = getCurrentSimulation()?.persona
-
- return (
-
-
-
-
-
-
-
- Le test
-
-
-
-
-
-
-
- Agir
-
-
-
- {!enquete && (
-
-
-
-
-
- {!persona ? (
- t('Profil')
- ) : (
-
- {capitalizeString(persona.split(' . ')[1])}
-
- )}
-
-
- )}
-
- {!enquete && (
-
-
-
-
- Amis
-
-
- )}
-
- {isDebug ? (
-
- Debug
-
- ) : null}
-
-
-
- )
-}
diff --git a/src/app/(layout-with-navigation)/_components/navigation/NavLink.tsx b/src/app/(layout-with-navigation)/_components/navigation/NavLink.tsx
deleted file mode 100644
index 91fa2f5c3..000000000
--- a/src/app/(layout-with-navigation)/_components/navigation/NavLink.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-'use client'
-
-import ButtonLink from '@/design-system/inputs/ButtonLink'
-import { usePathname } from 'next/navigation'
-import { ReactNode } from 'react'
-
-type Props = {
- href: string
- children: ReactNode
- className?: string
-}
-
-export default function NavLink({
- href,
- children,
- className,
- ...props
-}: Props) {
- const pathName = usePathname()
- const isActive = pathName.includes(href)
-
- return (
-
-
- {children}
-
-
- )
-}
diff --git a/src/app/(layout-with-navigation)/layout.tsx b/src/app/(layout-with-navigation)/layout.tsx
index 0b35f3a19..d19007952 100644
--- a/src/app/(layout-with-navigation)/layout.tsx
+++ b/src/app/(layout-with-navigation)/layout.tsx
@@ -3,16 +3,11 @@ import { PropsWithChildren } from 'react'
import Footer from '@/components/layout/Footer'
-import MobileHeader from './_components/MobileHeader'
-import Navigation from './_components/Navigation'
-
export default async function PageLayout({ children }: PropsWithChildren) {
return (
<>
-
-
-
+
{children}
diff --git a/src/app/(layout-with-navigation)/personas/page.tsx b/src/app/(layout-with-navigation)/personas/page.tsx
index a4ee6959a..aca2f97fd 100644
--- a/src/app/(layout-with-navigation)/personas/page.tsx
+++ b/src/app/(layout-with-navigation)/personas/page.tsx
@@ -1,8 +1,7 @@
import Trans from '@/components/translation/Trans'
-import { NGC_MODEL_API_URL } from '@/constants/urls'
import Title from '@/design-system/layout/Title'
+import fetchPersonas from '@/helpers/fetchPersonas'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
-import { currentLocale } from 'next-i18n-router'
import Persona from './_components/Persona'
import PersonaExplanations from './_components/PersonaExplanations'
@@ -15,13 +14,7 @@ export async function generateMetadata() {
}
export default async function Personas() {
- const locale = currentLocale()
-
- // TODO: endpoint should not be static (and should point to local if available)
- const personas = await fetch(
- `${NGC_MODEL_API_URL}/personas-${locale}.json`
- ).then((res) => res.json())
-
+ const personas = await fetchPersonas()
return (
<>
Personas} data-cypress-id="personas-title" />
diff --git a/src/app/(layout-with-navigation)/stats/_components/content/Chart.js b/src/app/(layout-with-navigation)/stats/_components/content/Chart.js
index b21f59732..6b00db4e8 100644
--- a/src/app/(layout-with-navigation)/stats/_components/content/Chart.js
+++ b/src/app/(layout-with-navigation)/stats/_components/content/Chart.js
@@ -93,7 +93,7 @@ export default function Chart(props) {
type="monotone"
dataKey={'Visiteurs'}
stroke={props.color ?? '#32337B'}
- fill={props.color ?? '#5758BB'}
+ fill={props.color ?? '#491273'}
fillOpacity={1}
/>
diff --git a/src/app/(layout-with-navigation)/stats/_components/content/DurationChart.js b/src/app/(layout-with-navigation)/stats/_components/content/DurationChart.js
index ec528a090..63e8c1b44 100644
--- a/src/app/(layout-with-navigation)/stats/_components/content/DurationChart.js
+++ b/src/app/(layout-with-navigation)/stats/_components/content/DurationChart.js
@@ -33,7 +33,7 @@ export default function visitDuration(props) {
} />
-
+
diff --git a/src/app/(layout-with-navigation)/stats/_components/content/TotalChart.js b/src/app/(layout-with-navigation)/stats/_components/content/TotalChart.js
index 1aa9d2dfe..03380da32 100644
--- a/src/app/(layout-with-navigation)/stats/_components/content/TotalChart.js
+++ b/src/app/(layout-with-navigation)/stats/_components/content/TotalChart.js
@@ -26,7 +26,7 @@ export default function TotalChart(props) {
style={{
left: `${((elt - minValue) / (maxScore - minValue)) * 100}%`,
}}
- className="absolute bottom-0 top-0 -ml-2 h-full w-2 bg-primary opacity-5"
+ className="bg-primary-500 absolute bottom-0 top-0 -ml-2 h-full w-2 opacity-5"
title={humanWeight({ t, i18n }, elt, true, user?.region?.code).join(
' '
)}
diff --git a/src/app/(layout-with-navigation)/stats/_components/content/sources/Table.js b/src/app/(layout-with-navigation)/stats/_components/content/sources/Table.js
index 18c4d59c4..7fb5d272e 100644
--- a/src/app/(layout-with-navigation)/stats/_components/content/sources/Table.js
+++ b/src/app/(layout-with-navigation)/stats/_components/content/sources/Table.js
@@ -11,7 +11,7 @@ export default function Table(props) {
{props.title}{' '}
{props.setNewWebsites && (
props.setNewWebsites(
(prevNewWebsites) => !prevNewWebsites
diff --git a/src/app/(layout-with-navigation)/stats/_components/utils/FancySelect.js b/src/app/(layout-with-navigation)/stats/_components/utils/FancySelect.js
index 2faf2023d..d93a158cb 100644
--- a/src/app/(layout-with-navigation)/stats/_components/utils/FancySelect.js
+++ b/src/app/(layout-with-navigation)/stats/_components/utils/FancySelect.js
@@ -1,6 +1,6 @@
export default function FancySelect(props) {
return (
-
+
option.value === props.value)
@@ -19,7 +19,7 @@ export default function FancySelect(props) {
}}>
{props.options.map((option, index) => (
diff --git a/src/app/(layout-with-navigation)/stats/_components/utils/Tile.js b/src/app/(layout-with-navigation)/stats/_components/utils/Tile.js
index 80e78dc87..ebbe1317f 100644
--- a/src/app/(layout-with-navigation)/stats/_components/utils/Tile.js
+++ b/src/app/(layout-with-navigation)/stats/_components/utils/Tile.js
@@ -8,7 +8,7 @@ export default function Tile(props) {
return (
-
+
{props.title &&
{props.title} }
{props.text &&
{props.text}
}
diff --git a/src/app/_components/ErrorFallback.tsx b/src/app/_components/ErrorFallback.tsx
index 8e75fe4ad..39d5afee4 100644
--- a/src/app/_components/ErrorFallback.tsx
+++ b/src/app/_components/ErrorFallback.tsx
@@ -5,7 +5,7 @@ import Button from '@/design-system/inputs/Button'
export const ErrorFallback = () => {
return (
-
+
Une erreur s'est produite
@@ -18,8 +18,7 @@ export const ErrorFallback = () => {
{
window.location.reload()
- }}
- >
+ }}>
Recharger la page
diff --git a/src/app/_components/IllustrationSVG.tsx b/src/app/_components/IllustrationSVG.tsx
index 4326d1ef5..47bbbeee4 100644
--- a/src/app/_components/IllustrationSVG.tsx
+++ b/src/app/_components/IllustrationSVG.tsx
@@ -11,8 +11,7 @@ const IllustrationSVG = forwardRef(
xmlnsXlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
- {...props}
- >
+ {...props}>
+ className="prefix__ciel">
+ className="prefix__infra">
+ }}>
+ }}>
+ }}>
+ }}>
+ }}>
+ className="prefix__avion">
+ }}>
+ className="prefix__nuages">
+ className="prefix__immeubles">
+ transform="translate(44.653 1.13)">
+ }}>
+ }}>
-
+
diff --git a/src/app/_components/MainLayoutProviders.tsx b/src/app/_components/MainLayoutProviders.tsx
index 24a77a14f..86e4d783b 100644
--- a/src/app/_components/MainLayoutProviders.tsx
+++ b/src/app/_components/MainLayoutProviders.tsx
@@ -1,6 +1,7 @@
'use client'
import { IframeOptionsProvider } from '@/contexts/IframeOptionsContext'
+import { useTrackSplitTesting } from '@/hooks/useTrackSplitTesting'
import { UserProvider } from '@/publicodes-state'
import { PropsWithChildren } from 'react'
import CheckFixedRegion from './mainLayoutProviders/CheckFixedRegion'
@@ -14,6 +15,9 @@ export default function MainLayoutProviders({
children,
region,
}: PropsWithChildren<{ region: { code: string; name: string } }>) {
+ // Handles sending split testing data to Matomo
+ useTrackSplitTesting()
+
return (
diff --git a/src/app/_components/NewsBanner.tsx b/src/app/_components/NewsBanner.tsx
index d7314ea79..7a0f1347a 100644
--- a/src/app/_components/NewsBanner.tsx
+++ b/src/app/_components/NewsBanner.tsx
@@ -5,7 +5,7 @@ export const localStorageKey = 'last-viewed-release'
export default async function NewsBanner() {
const locale = currentLocale()
- const releases = await getPosts(`src/locales/nouveautes/${locale}/`)
+ const releases = await getPosts(`src/locales/nouveautes/${locale ?? 'fr'}/`)
return
}
diff --git a/src/app/_components/mainLayoutProviders/QueryClientProviderWrapper.tsx b/src/app/_components/mainLayoutProviders/QueryClientProviderWrapper.tsx
index 2f38047a1..4c28fa457 100644
--- a/src/app/_components/mainLayoutProviders/QueryClientProviderWrapper.tsx
+++ b/src/app/_components/mainLayoutProviders/QueryClientProviderWrapper.tsx
@@ -3,7 +3,13 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { PropsWithChildren } from 'react'
-const queryClient = new QueryClient()
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false,
+ },
+ },
+})
export default function QueryClientProviderWrapper({
children,
}: PropsWithChildren) {
diff --git a/src/app/_components/mainLayoutProviders/QueryParamsProvider.tsx b/src/app/_components/mainLayoutProviders/QueryParamsProvider.tsx
index 2684922c2..87e8b4171 100644
--- a/src/app/_components/mainLayoutProviders/QueryParamsProvider.tsx
+++ b/src/app/_components/mainLayoutProviders/QueryParamsProvider.tsx
@@ -1,9 +1,11 @@
import { useDebug } from '@/hooks/useDebug'
+import useModelVersion from '@/hooks/useModelVersion'
import { usePRNumber } from '@/hooks/usePRNumber'
import { PropsWithChildren } from 'react'
export default function QueryParamsProvider({ children }: PropsWithChildren) {
useDebug()
usePRNumber()
+ useModelVersion()
return children
}
diff --git a/src/app/_components/mainLayoutProviders/SimulationFromUrlLoader.tsx b/src/app/_components/mainLayoutProviders/SimulationFromUrlLoader.tsx
index 2e61d7c45..17464d9fc 100644
--- a/src/app/_components/mainLayoutProviders/SimulationFromUrlLoader.tsx
+++ b/src/app/_components/mainLayoutProviders/SimulationFromUrlLoader.tsx
@@ -21,14 +21,15 @@ export default function SimulationFromUrlLoader() {
const idSimulationDecoded = decodeURIComponent(idSimulation || '')
- const { data: simulationFromURL } = useQuery(
- ['simulationFromURL'],
- () =>
+ const { data: simulationFromURL } = useQuery({
+ queryKey: ['simulationFromURL'],
+ queryFn: () =>
axios
.get(`${EMAIL_SIMULATION_URL}${idSimulationDecoded}`)
.then((res) => res.data),
- { enabled: idSimulationDecoded ? true : false, refetchOnWindowFocus: false }
- )
+ enabled: idSimulationDecoded ? true : false,
+ refetchOnWindowFocus: false,
+ })
useEffect(() => {
const simulationReformated = simulationFromURL?.data && {
diff --git a/src/app/_components/newsBanner/Banner.tsx b/src/app/_components/newsBanner/Banner.tsx
index 5c4a566b8..54f438383 100644
--- a/src/app/_components/newsBanner/Banner.tsx
+++ b/src/app/_components/newsBanner/Banner.tsx
@@ -58,7 +58,7 @@ export default function Banner({ releases }: Props) {
return (
- {' '}
+ {' '}
Nouveautés
@@ -75,7 +75,7 @@ export default function Banner({ releases }: Props) {
×
diff --git a/src/app/api/email-service/route.ts b/src/app/api/email-service/route.ts
index 335536ed1..635fd2bc8 100644
--- a/src/app/api/email-service/route.ts
+++ b/src/app/api/email-service/route.ts
@@ -38,14 +38,6 @@ export async function POST(request: NextRequest) {
await axios.post(
'https://api.brevo.com/v3/smtp/email',
{
- sender: {
- name: 'Nos Gestes Climat',
- email: 'contact@nosgestesclimat.fr',
- },
- replyTo: {
- name: 'Nos Gestes Climat',
- email: 'contact@nosgestesclimat.fr',
- },
to: [
{
name: email,
diff --git a/src/app/api/send-group-email/route.ts b/src/app/api/send-group-email/route.ts
index d57825f5b..5a5d9dffe 100644
--- a/src/app/api/send-group-email/route.ts
+++ b/src/app/api/send-group-email/route.ts
@@ -35,14 +35,6 @@ export async function POST(req: Request) {
await axios.post(
'https://api.brevo.com/v3/smtp/email',
{
- sender: {
- name: 'Nos Gestes Climat',
- email: 'contact@nosgestesclimat.fr',
- },
- replyTo: {
- name: 'Nos Gestes Climat',
- email: 'contact@nosgestesclimat.fr',
- },
to: [
{
name: email,
diff --git a/src/app/documentation/[...slug]/_components/DocumentationRouter.tsx b/src/app/documentation/[...slug]/_components/DocumentationRouter.tsx
new file mode 100644
index 000000000..3402bb2b4
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/DocumentationRouter.tsx
@@ -0,0 +1,45 @@
+'use client'
+
+import Providers from '@/components/providers/Providers'
+import { useUser } from '@/publicodes-state'
+import { JSX, useContext, useEffect } from 'react'
+import { IsDocumentationClientContext } from '../../_contexts/DocumentationStateContext'
+import DocumentationClient from './documentationRouter/DocumentationClient'
+
+type Props = {
+ supportedRegions: any
+ slug: string[]
+ serverComponent: JSX.Element
+}
+
+export default function DocumentationRouter({
+ supportedRegions,
+ slug,
+ serverComponent,
+}: Props) {
+ const { isDocumentationClient, setIsDocumentationClient } = useContext(
+ IsDocumentationClientContext
+ )
+
+ const { getCurrentSimulation } = useUser()
+
+ const currentSimulation = getCurrentSimulation()
+
+ // Switch to client side documentation if the simulation has been started
+ useEffect(() => {
+ if (!currentSimulation?.foldedSteps) return
+
+ if (currentSimulation?.foldedSteps?.length > 0) {
+ setIsDocumentationClient(true)
+ }
+ }, [currentSimulation, setIsDocumentationClient])
+
+ if (isDocumentationClient)
+ return (
+
+
+
+ )
+
+ return serverComponent
+}
diff --git a/src/app/documentation/[...slug]/_components/documentationRouter/DocumentationClient.tsx b/src/app/documentation/[...slug]/_components/documentationRouter/DocumentationClient.tsx
new file mode 100644
index 000000000..3aa597deb
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/documentationRouter/DocumentationClient.tsx
@@ -0,0 +1,52 @@
+'use client'
+
+import Link from '@/components/Link'
+import BilanChart from '@/components/charts/BilanChart'
+import ServicesChart from '@/components/charts/ServicesChart'
+import Markdown from '@/design-system/utils/Markdown'
+import { useClientTranslation } from '@/hooks/useClientTranslation'
+import { useEngine } from '@/publicodes-state'
+import { SuppportedRegions } from '@/types/international'
+import Head from 'next/head'
+import Engine from 'publicodes'
+import { RulePage } from 'publicodes-react'
+import References from '../../../_components/References'
+
+type Props = {
+ supportedRegions: SuppportedRegions
+ slugs: string[]
+}
+export default function DocumentationClient({ slugs }: Props) {
+ const { i18n } = useClientTranslation()
+
+ const path = decodeURI(slugs.join('/'))
+
+ const { engine } = useEngine()
+
+ const documentationPath = '/documentation'
+
+ return (
+
+ {children},
+ Text: ({ children }) => (
+ <>
+ {children}
+ {children.includes(' ') && }
+ {children.includes(' ') && (
+
+ )}
+ >
+ ),
+ References: References as any,
+ }}
+ />
+
+ )
+}
diff --git a/src/app/documentation/[...slug]/_components/documentationRouter/DocumentationServer.tsx b/src/app/documentation/[...slug]/_components/documentationRouter/DocumentationServer.tsx
new file mode 100644
index 000000000..631644758
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/documentationRouter/DocumentationServer.tsx
@@ -0,0 +1,88 @@
+import Trans from '@/components/translation/Trans'
+import { NGC_MODEL_API_URL } from '@/constants/urls'
+import Card from '@/design-system/layout/Card'
+import Title from '@/design-system/layout/Title'
+import Markdown from '@/design-system/utils/Markdown'
+import { fetchModel } from '@/helpers/data/fetchModel'
+import { Rules } from '@/publicodes-state/types'
+import { SuppportedRegions } from '@/types/international'
+import { capitalizeString } from '@/utils/capitalizeString'
+import { decodeRuleNameFromPath } from '@/utils/decodeRuleNameFromPath'
+import { redirect } from 'next/navigation'
+import ButtonLaunch from './documentationServer/ButtonLaunch'
+import CalculDetail from './documentationServer/CalculDetail'
+import PagesProches from './documentationServer/PagesProches'
+import QuestionSection from './documentationServer/QuestionSection'
+
+type Props = {
+ supportedRegions: SuppportedRegions
+ slugs: string[]
+ locale?: string
+}
+export default async function DocumentationServer({
+ slugs,
+ // This is a hack, we should be able to use currentLocale() from the i18n package
+ // but it breaks the app when used in the server side
+ locale,
+}: Props) {
+ const ruleName = decodeRuleNameFromPath(slugs.join('/'))
+
+ if (!ruleName) {
+ redirect('/404')
+ }
+
+ // We load the default rules to render the server side documentation
+ const rules: Rules = await fetchModel({
+ dataServer: NGC_MODEL_API_URL,
+ regionCode: 'FR',
+ locale: locale ?? 'fr',
+ isOptim: false,
+ })
+
+ const rule = rules[ruleName]
+
+ if (!rule) {
+ redirect('/404')
+ }
+
+ return (
+
+
+
+ {rule.question &&
}
+
+ {!rule.question && rule.description && (
+
+ )}
+
+ {rule.note && (
+
+ )}
+
+
+
+
+
+
+ Pour en savoir plus sur cette règle de notre modèle, lancer le
+ calcul en cliquant sur le bouton ci-dessous.
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/ButtonLaunch.tsx b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/ButtonLaunch.tsx
new file mode 100644
index 000000000..e4c3f3919
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/ButtonLaunch.tsx
@@ -0,0 +1,15 @@
+'use client'
+
+import { IsDocumentationClientContext } from '@/app/documentation/_contexts/DocumentationStateContext'
+import Button from '@/design-system/inputs/Button'
+import { useContext } from 'react'
+
+export default function ButtonLaunch() {
+ const { setIsDocumentationClient } = useContext(IsDocumentationClientContext)
+
+ return (
+ setIsDocumentationClient(true)}>
+ Lancer le calcul
+
+ )
+}
diff --git a/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/CalculDetail.tsx b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/CalculDetail.tsx
new file mode 100644
index 000000000..04dfb6e77
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/CalculDetail.tsx
@@ -0,0 +1,26 @@
+import Trans from '@/components/translation/Trans'
+import { Rules } from '@/publicodes-state/types'
+import { Rule } from 'publicodes'
+import RuleDetail from './calculDetail/RuleDetail'
+
+export default function CalculDetail({
+ rule,
+ ruleName,
+ rules,
+}: {
+ rule: Rule
+ ruleName: string
+ rules: Rules
+}) {
+ return (
+ <>
+
+ Comment cette donnée est-elle calculée ?
+
+
+
+
+
+ >
+ )
+}
diff --git a/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/PagesProches.tsx b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/PagesProches.tsx
new file mode 100644
index 000000000..7b63339a9
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/PagesProches.tsx
@@ -0,0 +1,54 @@
+import Link from '@/components/Link'
+import { getRuleTitle } from '@/helpers/publicodes/getRuleTitle'
+import { Rules } from '@/publicodes-state/types'
+import { utils } from 'publicodes'
+
+export default function PagesProches({
+ rules,
+ ruleName,
+}: {
+ rules: Rules
+ ruleName: string
+}) {
+ const namespaceRules = Object.keys(rules).filter(
+ (key) => key.includes(ruleName) && key !== ruleName
+ )
+ if (!namespaceRules.length) return null
+ return (
+
+ Pages proches
+
+
+ {namespaceRules.map((ruleName) => {
+ const item = {
+ ...rules[ruleName],
+ dottedName: ruleName,
+ espace: ruleName.split(' . ').reverse(),
+ }
+
+ return (
+
+
+
+ {item.espace
+ .slice(1)
+ .reverse()
+ .map((name: string) => (
+ {name} ›
+ ))}
+
+
+
+ {rules[item.dottedName]?.icônes}
+
+ {getRuleTitle(item)}
+
+
+ )
+ })}
+
+
+ )
+}
diff --git a/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/QuestionSection.tsx b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/QuestionSection.tsx
new file mode 100644
index 000000000..fd592b641
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/QuestionSection.tsx
@@ -0,0 +1,29 @@
+import Trans from '@/components/translation/Trans'
+import Card from '@/design-system/layout/Card'
+import Emoji from '@/design-system/utils/Emoji'
+import Markdown from '@/design-system/utils/Markdown'
+import { Rule } from 'publicodes'
+
+export default function QuestionSection({ rule }: { rule: Rule }) {
+ if (!rule.question) return null
+ return (
+ <>
+
+
+ 💬 Question pour l'utilisateur
+
+
+ {rule.question}
+
+
+ {rule.description && (
+
+
+ ℹ️ Aide à la saisie
+
+ {rule.description}
+
+ )}
+ >
+ )
+}
diff --git a/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/calculDetail/RuleDetail.tsx b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/calculDetail/RuleDetail.tsx
new file mode 100644
index 000000000..31ec1e428
--- /dev/null
+++ b/src/app/documentation/[...slug]/_components/documentationRouter/documentationServer/calculDetail/RuleDetail.tsx
@@ -0,0 +1,117 @@
+import Link from '@/components/Link'
+import { Rules } from '@/publicodes-state/types'
+import { capitalizeString } from '@/utils/capitalizeString'
+import { encodeRuleName } from '@/utils/publicodes/encodeRuleName'
+import { Rule, utils } from 'publicodes'
+
+const KEYS_TO_OMIT = [
+ 'titre',
+ 'couleur',
+ 'abréviation',
+ 'icônes',
+ 'description',
+ 'résumé',
+ 'exposé',
+ 'unité',
+ 'question',
+ 'note',
+ 'références',
+ // specific to NGC actions
+ 'effort',
+ 'inactive',
+ // specific to NGC form generation, could be cool to visualize, but in a tag, since it's big
+ 'mosaique',
+]
+
+const getRuleFormatted = (rule: Rule) => {
+ const ruleFormatted = { ...rule }
+
+ for (const key in ruleFormatted) {
+ if (KEYS_TO_OMIT.indexOf(key) >= 0) {
+ delete ruleFormatted[key as keyof typeof ruleFormatted]
+ }
+ }
+
+ return ruleFormatted
+}
+
+export default function RuleDetail({
+ ruleData,
+ context,
+}: {
+ ruleData: Rule | string | number
+ context: {
+ dottedName: string
+ rules: Rules
+ }
+}) {
+ const isDataObject =
+ typeof ruleData !== 'string' && typeof ruleData !== 'number'
+ const ruleFormatted = isDataObject ? getRuleFormatted(ruleData) : ruleData
+
+ const isArray =
+ ruleData &&
+ isDataObject &&
+ Object.keys(ruleData).every((key) => Number.isInteger(+key))
+
+ if (typeof ruleFormatted === 'string') {
+ try {
+ if (!context) return {capitalizeString(ruleFormatted)}
+
+ const ruleString = utils.disambiguateReference(
+ context.rules,
+ context.dottedName,
+ ruleFormatted
+ )
+
+ return (
+
+ {capitalizeString(ruleFormatted)}
+
+ )
+ } catch (e) {
+ return {capitalizeString(ruleFormatted)}
+ }
+ }
+
+ if (typeof ruleFormatted === 'number') return {ruleFormatted}
+
+ if (isArray) {
+ return (
+
+ {Object.entries(ruleFormatted).map(([key, value]) => {
+ return (
+
+
+
+ )
+ })}
+
+ )
+ }
+
+ return (
+
+ {Object.entries(ruleFormatted).map(([key, value]) => {
+ if (typeof value === 'string' || typeof value === 'number') {
+ return (
+
+
+
+
+
+ )
+ }
+
+ return (
+
+ {capitalizeString(key)}:
+
+
+
+
+ )
+ })}
+
+ )
+}
diff --git a/src/app/documentation/[...slug]/layout.tsx b/src/app/documentation/[...slug]/layout.tsx
deleted file mode 100644
index 72916dd0b..000000000
--- a/src/app/documentation/[...slug]/layout.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import Providers from '@/components/providers/Providers'
-import { getSupportedRegions } from '@/helpers/getSupportedRegions'
-import { PropsWithChildren } from 'react'
-
-export default async function Layout({ children }: PropsWithChildren) {
- const supportedRegions = await getSupportedRegions()
- return (
-
- {children}
-
- )
-}
diff --git a/src/app/documentation/[...slug]/page.tsx b/src/app/documentation/[...slug]/page.tsx
index f95bb3e31..f9f529f15 100644
--- a/src/app/documentation/[...slug]/page.tsx
+++ b/src/app/documentation/[...slug]/page.tsx
@@ -1,6 +1,7 @@
import { getSupportedRegions } from '@/helpers/getSupportedRegions'
import { getMetadataObject } from '@/helpers/metadata/getMetadataObject'
-import DocumentationContent from '../_components/DocumentationContent'
+import DocumentationRouter from './_components/DocumentationRouter'
+import DocumentationServer from './_components/documentationRouter/DocumentationServer'
export async function generateMetadata() {
return getMetadataObject({
@@ -11,18 +12,22 @@ export async function generateMetadata() {
})
}
-type Props = {
- params: {
- slug: string[]
- }
-}
-export default async function DocumentationPage({ params }: Props) {
+// The page content is in layout.tsx in order to persist the state
+// between the server and the client
+export default async function DocumentationPage({
+ params: { slug },
+}: {
+ params: { slug: string[] }
+}) {
const supportedRegions = await getSupportedRegions()
return (
-
+ }
/>
)
}
diff --git a/src/app/documentation/_components/DocumentationContent.tsx b/src/app/documentation/_components/DocumentationContent.tsx
index 12fb214ae..aa97ca745 100644
--- a/src/app/documentation/_components/DocumentationContent.tsx
+++ b/src/app/documentation/_components/DocumentationContent.tsx
@@ -22,45 +22,36 @@ type Props = {
supportedRegions: SuppportedRegions
slugs: string[]
}
-export default function DocumentationContent({
+export default function DocumentationClient({
supportedRegions,
slugs,
}: Props) {
const { i18n } = useClientTranslation()
const path = decodeURI(slugs.join('/'))
-
const { user, getCurrentSimulation } = useUser()
-
const lang = useLocale()
-
const { data: rules } = useRules({
lang: lang || 'fr',
region: supportedRegions[user.region?.code] ? user.region.code : 'FR',
isOptim: false,
})
-
const currentSimulation = getCurrentSimulation()
const situation = currentSimulation?.situation
-
const engine = useMemo(
() => (rules ? new Engine(rules as Rules) : null),
[rules]
)
-
//TODO: this is shit
useEffect(() => {
if (engine && situation) {
const rules = Object.keys(engine.getParsedRules())
-
const safeSituation: Situation = safeGetSituation({
situation,
everyRules: rules,
})
-
engine.setSituation(safeSituation as any)
}
}, [engine, situation])
-
const documentationPath = '/documentation'
return (
diff --git a/src/app/documentation/_components/DocumentationLanding.tsx b/src/app/documentation/_components/DocumentationLanding.tsx
index 456a8c692..d3b190a71 100644
--- a/src/app/documentation/_components/DocumentationLanding.tsx
+++ b/src/app/documentation/_components/DocumentationLanding.tsx
@@ -5,16 +5,20 @@ import Title from '@/design-system/layout/Title'
import { useLocale } from '@/hooks/useLocale'
import { useRules } from '@/hooks/useRules'
import { useUser } from '@/publicodes-state'
-import Markdown from 'markdown-to-jsx'
-import { utils } from 'publicodes'
import Link from '@/components/Link'
-import Card from '@/design-system/layout/Card'
-import { NGCRules } from '@/publicodes-state/types'
-import editorialisedModels from '../_data/editorialisedModels.yaml'
+import DocumentationLandingCard from './DocumentationLandingCard'
import SearchBar from './SearchBar'
-const EMOJIS = ['👤', '🏛️', '🍽️', '🌡️', '🚗', '🗑️']
+// We want to be able to define an order for the cards and their summary here
+const FIXED_CARD_SUMMARIES = {
+ bilan: `Le coeur de Nos Gestes Climat, c'est **le bilan** d'empreinte climat personels`,
+ 'services sociétaux': `Les constantes de **services publics et marchands** calculées à partir des travaux du SDES`,
+ 'alimentation . plats': ` **6 repas** représentatifs de notre consommation`,
+ 'alimentation . déchets': `Un modèle inédit d'empreinte des **déchets**`,
+ 'logement . chauffage . empreinte par défaut': `Un calcul statistique du **chauffage** résidentiel français moyen`,
+ 'transport . voiture': `Le premier poste moyen d'empreinte, l'incontournable **voiture individuelle**`,
+} as Record
export default function DocumentationLanding() {
const locale = useLocale()
@@ -23,26 +27,12 @@ export default function DocumentationLanding() {
user: { region },
} = useUser()
- const { data } = useRules({
+ const { data: rules } = useRules({
lang: locale,
region: region?.code ?? 'FR',
})
- if (!data) return null
-
- const rules = data as NGCRules & {
- [key: string]: { couleur: string; résumé: string }
- }
-
- const editos = (editorialisedModels as unknown as string[]).map(
- (dottedName: string) => ({
- ...rules[dottedName],
- dottedName,
- })
- )
-
- const getColor = (dottedName: string) =>
- rules[dottedName.split(' . ')[0]].couleur
+ if (!rules) return null
return (
@@ -70,24 +60,14 @@ export default function DocumentationLanding() {
- {editos.map(({ dottedName, résumé }, index) => {
+ {Object.keys(FIXED_CARD_SUMMARIES).map((dottedName) => {
return (
-
-
- {EMOJIS[index]}
-
- {résumé && (
-
- {{résumé} }
-
- )}
-
+
)
})}
diff --git a/src/app/documentation/_components/DocumentationLandingCard.tsx b/src/app/documentation/_components/DocumentationLandingCard.tsx
new file mode 100644
index 000000000..ba1d7b361
--- /dev/null
+++ b/src/app/documentation/_components/DocumentationLandingCard.tsx
@@ -0,0 +1,41 @@
+'use client'
+
+import Link from '@/components/Link'
+import Card from '@/design-system/layout/Card'
+import Emoji from '@/design-system/utils/Emoji'
+import { getBackgroundColor } from '@/helpers/getCategoryColorClass'
+import { NGCRule } from '@/publicodes-state/types'
+import Markdown from 'markdown-to-jsx'
+import { utils } from 'publicodes'
+
+type Props = {
+ dottedName: string
+ summary: string
+ rule: NGCRule
+}
+export default function DocumentationLandingCard({
+ dottedName,
+ summary,
+ rule,
+}: Props) {
+ const category = dottedName.split(' . ')[0]
+
+ return (
+
+
+
+ {rule['icônes']}
+
+
+
+
+ {{summary} }
+
+
+ )
+}
diff --git a/src/app/documentation/_components/RuleListIem.tsx b/src/app/documentation/_components/RuleListIem.tsx
index 7cf3f84fb..6465af759 100644
--- a/src/app/documentation/_components/RuleListIem.tsx
+++ b/src/app/documentation/_components/RuleListIem.tsx
@@ -17,12 +17,10 @@ export default function RuleListItem({
return (
+ className="border-primary-100 my-2 border-b border-solid p-2">
+ className="decoration-none">
{item.espace
.slice(1)
diff --git a/src/app/documentation/_components/SearchBar.tsx b/src/app/documentation/_components/SearchBar.tsx
index efd4df7f8..8a6ed55c9 100644
--- a/src/app/documentation/_components/SearchBar.tsx
+++ b/src/app/documentation/_components/SearchBar.tsx
@@ -81,14 +81,13 @@ export default function SearchBar({ rules }: { rules: NGCRules }) {
return (
<>
-
+
+ className="mr-3 inline-block ">
🔍
Explorez nos modèles
@@ -96,13 +95,13 @@ export default function SearchBar({ rules }: { rules: NGCRules }) {
+ className="flex items-center py-2">
+ {' '}
{
const input = e.target.value
diff --git a/src/app/documentation/_contexts/DocumentationStateContext.tsx b/src/app/documentation/_contexts/DocumentationStateContext.tsx
new file mode 100644
index 000000000..aae1eb844
--- /dev/null
+++ b/src/app/documentation/_contexts/DocumentationStateContext.tsx
@@ -0,0 +1,32 @@
+'use client'
+
+import { createContext, useState } from 'react'
+
+type IsDocumentationClientContextType = {
+ isDocumentationClient: boolean
+ setIsDocumentationClient: (isDocumentationClient: boolean) => void
+}
+
+export const IsDocumentationClientContext =
+ createContext({
+ isDocumentationClient: false,
+ setIsDocumentationClient: () => {},
+ })
+
+export const IsDocumentationClientProvider = ({
+ children,
+}: {
+ children: React.ReactNode
+}) => {
+ const [isDocumentationClient, setIsDocumentationClient] = useState(false)
+
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/app/documentation/_data/editorialisedModels.yaml b/src/app/documentation/_data/editorialisedModels.yaml
deleted file mode 100644
index 219ef2264..000000000
--- a/src/app/documentation/_data/editorialisedModels.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-- bilan
-- services sociétaux
-- alimentation . plats
-- logement . chauffage . empreinte par défaut
-- transport . voiture
-- alimentation . déchets
diff --git a/src/app/documentation/_helpers/highlightMatches.tsx b/src/app/documentation/_helpers/highlightMatches.tsx
index 9842bcd3c..cc9f6f8f2 100644
--- a/src/app/documentation/_helpers/highlightMatches.tsx
+++ b/src/app/documentation/_helpers/highlightMatches.tsx
@@ -22,10 +22,7 @@ export default function highlightMatches(str: string, matches: Matches) {
currentIndice,
[
...acc,
-
+
{currentStr}
,
],
diff --git a/src/app/documentation/layout.tsx b/src/app/documentation/layout.tsx
index fdf9bf713..a3e277cac 100644
--- a/src/app/documentation/layout.tsx
+++ b/src/app/documentation/layout.tsx
@@ -1,20 +1,18 @@
import Footer from '@/components/layout/Footer'
-import Logo from '@/components/misc/Logo'
import Main from '@/design-system/layout/Main'
import { PropsWithChildren } from 'react'
+import { IsDocumentationClientProvider } from './_contexts/DocumentationStateContext'
-export default async function Layout({ children }: PropsWithChildren) {
+export default function Layout({ children }: PropsWithChildren) {
return (
- <>
-
+
-
+
{children}
+
- >
+
)
}
diff --git a/src/app/documentation/page.tsx b/src/app/documentation/page.tsx
index 97c3c9d4d..556f906a3 100644
--- a/src/app/documentation/page.tsx
+++ b/src/app/documentation/page.tsx
@@ -11,5 +11,9 @@ export async function generateMetadata() {
}
export default function Documentation() {
- return
+ return (
+
+
+
+ )
}
diff --git a/src/app/globals.css b/src/app/globals.css
index a663c4e42..10dddf9b8 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -14,7 +14,6 @@
h1 {
@apply text-2xl;
- @apply md:text-3xl;
@apply mb-6;
@apply font-bold;
}
@@ -77,25 +76,10 @@ html,
body {
margin: 0;
padding: 0;
- @apply text-primaryDark;
}
a {
- @apply inline-block text-primary underline transition-colors hover:text-primaryDark;
-}
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- @apply font-bold;
- @apply text-primaryDark;
-}
-
-h1 {
- @apply text-2xl;
+ @apply inline-block text-primary-500 underline transition-colors hover:text-primary-400;
}
img {
@@ -235,7 +219,7 @@ blockquote {
@apply rounded-md;
padding: 1rem 1rem 0.25rem;
margin: 1rem 0;
- @apply text-primaryDark;
+ @apply text-primary-700;
}
.news-page ul {
padding-left: 1rem;
@@ -250,10 +234,10 @@ blockquote {
Gamecard
*/
.game-card-1 {
- @apply fill-primary;
+ @apply fill-primary-500;
fill-opacity: 0.996078;
fill-rule: 'evenodd';
- @apply stroke-primaryDark;
+ @apply stroke-primary-700;
stroke-width: 7.2062;
stroke-linecap: 'round';
stroke-linejoin: 'round';
@@ -263,10 +247,10 @@ blockquote {
}
.game-card-2 {
- @apply fill-primary;
+ @apply fill-primary-500;
fill-opacity: 0.996078;
fill-rule: 'evenodd';
- @apply stroke-primaryDark;
+ @apply stroke-primary-500;
stroke-width: 7.2062;
stroke-linecap: 'round';
stroke-linejoin: 'round';
@@ -279,7 +263,7 @@ blockquote {
fill: white;
fill-opacity: 0.997404;
fill-rule: 'evenodd';
- @apply stroke-primaryDark;
+ @apply stroke-primary-700;
stroke-width: 10.1932;
stroke-linecap: 'round';
stroke-linejoin: 'round';
@@ -376,7 +360,6 @@ blockquote {
/*
Iframe
*/
-.iframeOnlySimulation header,
.iframeOnlySimulation footer {
display: none;
}
@@ -394,3 +377,54 @@ blockquote {
clip: rect(0, 0, 0, 0);
border: 0;
}
+
+/*
+ Markdown
+*/
+.markdown ul {
+ @apply pl-6;
+ @apply list-disc;
+ @apply mb-6;
+}
+
+.markdown ul > li {
+ @apply mb-2;
+}
+
+.markdown ol {
+ @apply pl-6;
+ list-style-type: decimal;
+ list-style-position: outside;
+ @apply mb-6;
+}
+
+.markdown h1 {
+ @apply text-4xl;
+ @apply mb-6;
+ @apply font-bold;
+ @apply leading-10;
+}
+
+.markdown h1,
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+ @apply mt-8;
+ @apply mb-6;
+}
+
+.markdown p {
+ @apply mb-6;
+}
+
+.markdown blockquote {
+ @apply mb-6;
+}
+
+.markdown img {
+ @apply border;
+ @apply border-gray-200;
+ @apply rounded-md;
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 4fa57a640..934a4f4f4 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,4 +1,5 @@
// Initialise react-i18next
+import Header from '@/components/layout/Header'
import getGeolocation from '@/helpers/getGeolocation'
import '@/locales/initClient'
import '@/locales/initServer'
@@ -55,10 +56,6 @@ export default async function RootLayout({ children }: PropsWithChildren) {
return (
-
-
-
-
-
+
{process.env.NEXT_PUBLIC_MATOMO_ID === '1' ? (