From 0f417b21213599204095ab3bc9bc955ebde59f05 Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Fri, 10 Jan 2025 16:39:02 +0100 Subject: [PATCH 1/7] WIP: test declaration --- data/factories/teleicare_history/__init__.py | 75 +++++++++++++++++++ data/tests/test_teleicare_history_importer.py | 29 ++++++- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/data/factories/teleicare_history/__init__.py b/data/factories/teleicare_history/__init__.py index 3494cff77..761d9a2cf 100644 --- a/data/factories/teleicare_history/__init__.py +++ b/data/factories/teleicare_history/__init__.py @@ -3,10 +3,17 @@ import factory import faker + from phonenumber_field.phonenumber import PhoneNumber +from datetime import datetime from data.choices import CountryChoices from data.models.teleicare_history.ica_etablissement import IcaEtablissement +from data.models.teleicare_history.ica_declaration import ( + IcaComplementAlimentaire, + IcaDeclaration, + IcaVersionDeclaration, +) from data.utils.string_utils import make_random_str from data.factories.company import _make_siret, _make_vat, _make_phone_number @@ -28,3 +35,71 @@ class Meta: etab_adre_ville = factory.Faker("city", locale="FR") etab_adre_cp = factory.Faker("postcode", locale="FR") etab_adre_voie = factory.Faker("street_address", locale="FR") + + +class ComplementAlimentaireFactory(factory.django.DjangoModelFactory): + class Meta: + model = IcaComplementAlimentaire + + cplalim_ident = factory.Sequence(lambda n: n + 1) + frmgal_ident = factory.Faker("pyint", min_value=0, max_value=20) + etab = factory.SubFactory(EtablissementFactory) + cplalim_marque = factory.Faker("text", max_nb_chars=20) + cplalim_gamme = factory.Faker("text", max_nb_chars=20) + cplalim_nom = factory.Faker("text", max_nb_chars=20) + dclencours_gout_arome_parfum = factory.Faker("text", max_nb_chars=20) + cplalim_forme_galenique_autre = factory.Faker("text", max_nb_chars=20) + + +class DeclarationFactory(factory.django.DjangoModelFactory): + class Meta: + model = IcaDeclaration + + dcl_ident = factory.Sequence(lambda n: n + 1) + cplalim = factory.SubFactory(ComplementAlimentaireFactory) + tydcl_ident = factory.Faker("pyint", min_value=0, max_value=20) + etab = factory.SubFactory(EtablissementFactory) + etab_ident_rmm_declarant = factory.Faker("pyint", min_value=0, max_value=20) + dcl_date = datetime.strftime(factory.Faker("date_time"), "%m/%d/%Y %H:%M:%S %p") + dcl_date_fin_commercialisation = factory.LazyFunction( + lambda: datetime.strftime(factory.Faker("date_time"), "%m/%d/%Y %H:%M:%S %p") + if random.random() > 0.3 + else None + ) + + +class VersionDeclarationFactory(factory.django.DjangoModelFactory): + class Meta: + model = IcaVersionDeclaration + + vrsdecl_ident = factory.Sequence(lambda n: n + 1) + ag_ident = factory.Faker("pyint", min_value=0, max_value=20) + typvrs_ident = factory.Faker("pyint", min_value=0, max_value=20) + unt_ident = factory.Faker("pyint", min_value=0, max_value=20) + pays_ident_adre = factory.Faker("pyint", min_value=0, max_value=8) + etab = factory.SubFactory(EtablissementFactory) + pays_ident_pays_de_reference = factory.Faker("pyint", min_value=0, max_value=8) + dcl = factory.SubFactory(DeclarationFactory) + stattdcl_ident = factory.Faker("pyint", min_value=0, max_value=8) + stadcl_ident = factory.Faker("pyint", min_value=0, max_value=8) + vrsdecl_numero = factory.Faker("pyint", min_value=0, max_value=20) + vrsdecl_commentaires = factory.Faker("text", max_nb_chars=20) + vrsdecl_mise_en_garde = factory.Faker("text", max_nb_chars=20) + vrsdecl_durabilite = factory.Faker("pyint", min_value=0, max_value=8) + vrsdecl_mode_emploi = factory.Faker("text", max_nb_chars=20) + vrsdecl_djr = factory.Faker("text", max_nb_chars=20) + vrsdecl_conditionnement = factory.Faker("text", max_nb_chars=20) + vrsdecl_poids_uc = factory.Faker("pyfloat") + vrsdecl_forme_galenique_autre = factory.Faker("text", max_nb_chars=20) + vrsdecl_date_limite_reponse_pro = factory.Faker("text", max_nb_chars=20) + vrsdecl_observations_ac = factory.Faker("text", max_nb_chars=20) + vrsdecl_observations_pro = factory.Faker("text", max_nb_chars=20) + vrsdecl_numero_dossiel = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_ville = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_cp = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_voie = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_comp = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_comp2 = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_dist = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_region = factory.Faker("text", max_nb_chars=20) + vrsdecl_adre_raison_sociale = factory.Faker("text", max_nb_chars=20) diff --git a/data/tests/test_teleicare_history_importer.py b/data/tests/test_teleicare_history_importer.py index 724798a29..515c2a60b 100644 --- a/data/tests/test_teleicare_history_importer.py +++ b/data/tests/test_teleicare_history_importer.py @@ -7,6 +7,7 @@ from data.factories.company import CompanyFactory, _make_siret, _make_vat from data.factories.teleicare_history import EtablissementFactory from data.models.company import Company +from data.models.declaration import Declaration from data.models.teleicare_history.ica_etablissement import IcaEtablissement @@ -90,15 +91,39 @@ def test_create_new_companies(self): """ etablissement_to_create_as_company = EtablissementFactory(etab_siret=None, etab_ica_importateur=True) - # ne sera pas créé car le numéro de téléphone est mal formatté + # devrait être créée malgré le numéro de téléphone mal formaté _ = EtablissementFactory(etab_siret=None, etab_ica_importateur=True, etab_telephone="0345") self.assertEqual(Company.objects.filter(siccrf_id=etablissement_to_create_as_company.etab_ident).count(), 0) match_companies_on_siret_or_vat(create_if_not_exist=True) - self.assertEqual(Company.objects.filter(siccrf_id=etablissement_to_create_as_company.etab_ident).count(), 1) + self.assertTrue(Company.objects.filter(siccrf_id=etablissement_to_create_as_company.etab_ident).exists()) + self.assertEqual(Company.objects.exclude(siccrf_id=None).count(), 2) created_company = Company.objects.get(siccrf_id=etablissement_to_create_as_company.etab_ident) self.assertEqual(created_company.siccrf_id, etablissement_to_create_as_company.etab_ident) self.assertEqual(created_company.address, etablissement_to_create_as_company.etab_adre_voie) self.assertEqual(created_company.postal_code, etablissement_to_create_as_company.etab_adre_cp) self.assertEqual(created_company.city, etablissement_to_create_as_company.etab_adre_ville) + + def test_create_declaration(self): + """ + Les déclarations sont créées à partir d'object historiques des modèles Ica_ + """ + + etablissement_to_create_as_company = EtablissementFactory(etab_siret=None, etab_ica_importateur=True) + # ne sera pas créé car le numéro de téléphone est mal formatté + _ = EtablissementFactory(etab_siret=None, etab_ica_importateur=True, etab_telephone="0345") + self.assertEqual( + Declaration.objects.filter(siccrf_id=etablissement_to_create_as_company.etab_ident).count(), 0 + ) + + match_companies_on_siret_or_vat(create_if_not_exist=True) + self.assertEqual( + Declaration.objects.filter(siccrf_id=etablissement_to_create_as_company.etab_ident).count(), 1 + ) + + created_declaration = Declaration.objects.get(siccrf_id=etablissement_to_create_as_company.etab_ident) + self.assertEqual(created_declaration.siccrf_id, etablissement_to_create_as_company.etab_ident) + self.assertEqual(created_declaration.address, etablissement_to_create_as_company.etab_adre_voie) + self.assertEqual(created_declaration.postal_code, etablissement_to_create_as_company.etab_adre_cp) + self.assertEqual(created_declaration.city, etablissement_to_create_as_company.etab_adre_ville) From 66143acb0db96011ef8daae44e5c0994913ce46b Mon Sep 17 00:00:00 2001 From: Perrine Letellier Date: Mon, 13 Jan 2025 11:12:41 +0100 Subject: [PATCH 2/7] finish basic test --- data/etl/teleicare_history/extractor.py | 6 ++ data/factories/teleicare_history/__init__.py | 19 ++++- .../teleicare_history/ica_declaration.py | 18 ++--- data/tests/test_teleicare_history_importer.py | 79 ++++++++++++++----- 4 files changed, 88 insertions(+), 34 deletions(-) diff --git a/data/etl/teleicare_history/extractor.py b/data/etl/teleicare_history/extractor.py index b96e8c9ec..acdec9f03 100644 --- a/data/etl/teleicare_history/extractor.py +++ b/data/etl/teleicare_history/extractor.py @@ -156,6 +156,7 @@ def create_declaration_from_teleicare_history(): * télédéclarante de la déclaration (cette relation n'est pour le moment pas conservée, car le BEPIAS ne sait pas ce qu'elle signifie) """ nb_created_declarations = 0 + for ica_complement_alimentaire in IcaComplementAlimentaire.objects.all(): # retrouve la déclaration la plus à jour correspondant à ce complément alimentaire all_ica_declarations = IcaDeclaration.objects.filter(cplalim_id=ica_complement_alimentaire.cplalim_ident) @@ -207,10 +208,15 @@ def create_declaration_from_teleicare_history(): # other_conditions= # effects= # other_effects= + # address= + # postal_code= + # city= + # country= status=Declaration.DeclarationStatus.WITHDRAWN if latest_ica_declaration.dcl_date_fin_commercialisation else DECLARATION_STATUS_MAPPING[latest_ica_version_declaration.stattdcl_ident], ) + try: declaration.save() nb_created_declarations += 1 diff --git a/data/factories/teleicare_history/__init__.py b/data/factories/teleicare_history/__init__.py index 761d9a2cf..a446b86cd 100644 --- a/data/factories/teleicare_history/__init__.py +++ b/data/factories/teleicare_history/__init__.py @@ -5,7 +5,8 @@ import faker from phonenumber_field.phonenumber import PhoneNumber -from datetime import datetime +from datetime import datetime, timedelta +from random import randrange from data.choices import CountryChoices from data.models.teleicare_history.ica_etablissement import IcaEtablissement @@ -18,6 +19,16 @@ from data.factories.company import _make_siret, _make_vat, _make_phone_number +def random_date(start, end=datetime.now()): + """ + Retourne une date random entre une date de début et une date de fin + """ + delta = end - start + int_delta = (delta.days * 24 * 60 * 60) + delta.seconds + random_second = randrange(int_delta) + return start + timedelta(seconds=random_second) + + class EtablissementFactory(factory.django.DjangoModelFactory): class Meta: model = IcaEtablissement @@ -60,9 +71,9 @@ class Meta: tydcl_ident = factory.Faker("pyint", min_value=0, max_value=20) etab = factory.SubFactory(EtablissementFactory) etab_ident_rmm_declarant = factory.Faker("pyint", min_value=0, max_value=20) - dcl_date = datetime.strftime(factory.Faker("date_time"), "%m/%d/%Y %H:%M:%S %p") + dcl_date = datetime.strftime(random_date(start=datetime(2016, 1, 1)), "%m/%d/%Y %H:%M:%S %p") dcl_date_fin_commercialisation = factory.LazyFunction( - lambda: datetime.strftime(factory.Faker("date_time"), "%m/%d/%Y %H:%M:%S %p") + lambda: datetime.strftime(random_date(start=datetime(2016, 1, 1)), "%m/%d/%Y %H:%M:%S %p") if random.random() > 0.3 else None ) @@ -87,7 +98,7 @@ class Meta: vrsdecl_mise_en_garde = factory.Faker("text", max_nb_chars=20) vrsdecl_durabilite = factory.Faker("pyint", min_value=0, max_value=8) vrsdecl_mode_emploi = factory.Faker("text", max_nb_chars=20) - vrsdecl_djr = factory.Faker("text", max_nb_chars=20) + vrsdecl_djr = factory.fuzzy.FuzzyText(length=4, chars=string.ascii_uppercase + string.digits) vrsdecl_conditionnement = factory.Faker("text", max_nb_chars=20) vrsdecl_poids_uc = factory.Faker("pyfloat") vrsdecl_forme_galenique_autre = factory.Faker("text", max_nb_chars=20) diff --git a/data/models/teleicare_history/ica_declaration.py b/data/models/teleicare_history/ica_declaration.py index 47c68d89e..f235b3099 100644 --- a/data/models/teleicare_history/ica_declaration.py +++ b/data/models/teleicare_history/ica_declaration.py @@ -41,10 +41,10 @@ class IcaDeclaration(models.Model): ) # correspond à l'entreprise gestionnaire de la déclaration etab_ident_rmm_declarant = models.IntegerField() dcl_date = models.TextField() - dcl_saisie_administration = models.BooleanField() - dcl_annee = models.IntegerField() - dcl_mois = models.IntegerField() - dcl_numero = models.IntegerField() + dcl_saisie_administration = models.BooleanField(null=True) # rendu nullable pour simplifier les Factories + dcl_annee = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories + dcl_mois = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories + dcl_numero = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories dcl_date_fin_commercialisation = models.TextField(blank=True, null=True) class Meta: @@ -55,20 +55,20 @@ class Meta: class IcaVersionDeclaration(models.Model): vrsdecl_ident = models.IntegerField(primary_key=True) ag_ident = models.IntegerField(blank=True, null=True) - typvrs_ident = models.IntegerField() + typvrs_ident = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories unt_ident = models.IntegerField(blank=True, null=True) pays_ident_adre = models.IntegerField(blank=True, null=True) etab = models.ForeignKey( IcaEtablissement, on_delete=models.CASCADE, db_column="etab_ident" ) # correspond à l'entreprise télédéclarante - ex_ident = models.IntegerField() + ex_ident = models.IntegerField(null=True) # rendu nullable pour simplifier les Factories pays_ident_pays_de_reference = models.IntegerField(blank=True, null=True) dcl = models.ForeignKey( IcaDeclaration, on_delete=models.CASCADE, db_column="dcl_ident" ) # dcl_ident est aussi une foreign_key vers IcaComplementAlimentaire stattdcl_ident = models.IntegerField(blank=True, null=True) stadcl_ident = models.IntegerField(blank=True, null=True) - vrsdecl_numero = models.IntegerField() + vrsdecl_numero = models.IntegerField(null=True) vrsdecl_commentaires = models.TextField(blank=True, null=True) vrsdecl_mise_en_garde = models.TextField(blank=True, null=True) vrsdecl_durabilite = models.IntegerField(blank=True, null=True) @@ -80,9 +80,9 @@ class IcaVersionDeclaration(models.Model): vrsdecl_date_limite_reponse_pro = models.TextField(blank=True, null=True) vrsdecl_observations_ac = models.TextField(blank=True, null=True) vrsdecl_observations_pro = models.TextField(blank=True, null=True) - vrsdecl_mode_json = models.BooleanField() + vrsdecl_mode_json = models.BooleanField(null=True) # rendu nullable pour simplifier les Factories vrsdecl_numero_dossiel = models.TextField(blank=True, null=True) - vrsdecl_mode_sans_verif = models.BooleanField() + vrsdecl_mode_sans_verif = models.BooleanField(null=True) # rendu nullable pour simplifier les Factories vrsdecl_adre_ville = models.TextField(blank=True, null=True) vrsdecl_adre_cp = models.TextField(blank=True, null=True) vrsdecl_adre_voie = models.TextField(blank=True, null=True) diff --git a/data/tests/test_teleicare_history_importer.py b/data/tests/test_teleicare_history_importer.py index 515c2a60b..247964189 100644 --- a/data/tests/test_teleicare_history_importer.py +++ b/data/tests/test_teleicare_history_importer.py @@ -3,11 +3,26 @@ from django.db import connection from django.test import TestCase -from data.etl.teleicare_history.extractor import match_companies_on_siret_or_vat +from data.etl.teleicare_history.extractor import ( + create_declaration_from_teleicare_history, + match_companies_on_siret_or_vat, +) from data.factories.company import CompanyFactory, _make_siret, _make_vat -from data.factories.teleicare_history import EtablissementFactory +from data.factories.galenic_formulation import GalenicFormulationFactory +from data.factories.teleicare_history import ( + ComplementAlimentaireFactory, + DeclarationFactory, + EtablissementFactory, + VersionDeclarationFactory, +) +from data.factories.unit import SubstanceUnitFactory from data.models.company import Company from data.models.declaration import Declaration +from data.models.teleicare_history.ica_declaration import ( + IcaComplementAlimentaire, + IcaDeclaration, + IcaVersionDeclaration, +) from data.models.teleicare_history.ica_etablissement import IcaEtablissement @@ -22,20 +37,20 @@ def setUp(self): """ super().setUp() with connection.schema_editor() as schema_editor: - schema_editor.create_model(IcaEtablissement) + for table in [IcaEtablissement, IcaComplementAlimentaire, IcaDeclaration, IcaVersionDeclaration]: + schema_editor.create_model(table) - if IcaEtablissement._meta.db_table not in connection.introspection.table_names(): - raise ValueError( - "Table `{table_name}` is missing in test database.".format( - table_name=IcaEtablissement._meta.db_table + if table._meta.db_table not in connection.introspection.table_names(): + raise ValueError( + "Table `{table_name}` is missing in test database.".format(table_name=table._meta.db_table) ) - ) def tearDown(self): super().tearDown() with connection.schema_editor() as schema_editor: - schema_editor.delete_model(IcaEtablissement) + for table in [IcaEtablissement, IcaComplementAlimentaire, IcaDeclaration, IcaVersionDeclaration]: + schema_editor.delete_model(table) def test_match_companies_on_siret_or_vat(self): """ @@ -109,21 +124,43 @@ def test_create_declaration(self): """ Les déclarations sont créées à partir d'object historiques des modèles Ica_ """ - + galenic_formulation_id = 1 + galenic_formulation = GalenicFormulationFactory(siccrf_id=galenic_formulation_id) + unit_id = 1 + unit = SubstanceUnitFactory(siccrf_id=unit_id) etablissement_to_create_as_company = EtablissementFactory(etab_siret=None, etab_ica_importateur=True) - # ne sera pas créé car le numéro de téléphone est mal formatté - _ = EtablissementFactory(etab_siret=None, etab_ica_importateur=True, etab_telephone="0345") - self.assertEqual( - Declaration.objects.filter(siccrf_id=etablissement_to_create_as_company.etab_ident).count(), 0 + + CA_to_create_as_declaration = ComplementAlimentaireFactory( + etab=etablissement_to_create_as_company, frmgal_ident=galenic_formulation_id + ) + declaration_to_create_as_declaration = DeclarationFactory(cplalim=CA_to_create_as_declaration) + version_declaration_to_create_as_declaration = VersionDeclarationFactory( + dcl=declaration_to_create_as_declaration, + stadcl_ident=8, + stattdcl_ident=2, + unt_ident=unit_id, + vrsdecl_djr="32 kg of ppo", ) match_companies_on_siret_or_vat(create_if_not_exist=True) + create_declaration_from_teleicare_history() + + version_declaration_to_create_as_declaration.refresh_from_db() + created_declaration = Declaration.objects.get(siccrf_id=CA_to_create_as_declaration.cplalim_ident) + self.assertEqual(created_declaration.name, CA_to_create_as_declaration.cplalim_nom) + self.assertEqual(created_declaration.brand, CA_to_create_as_declaration.cplalim_marque) + self.assertEqual(created_declaration.gamme, CA_to_create_as_declaration.cplalim_gamme) + self.assertEqual(created_declaration.flavor, CA_to_create_as_declaration.dclencours_gout_arome_parfum) + self.assertEqual(created_declaration.galenic_formulation, galenic_formulation) + self.assertEqual(created_declaration.unit_quantity, 32) + self.assertEqual(created_declaration.unit_measurement, unit) self.assertEqual( - Declaration.objects.filter(siccrf_id=etablissement_to_create_as_company.etab_ident).count(), 1 + created_declaration.conditioning, version_declaration_to_create_as_declaration.vrsdecl_conditionnement + ) + self.assertEqual( + created_declaration.daily_recommended_dose, + str(version_declaration_to_create_as_declaration.vrsdecl_poids_uc), + ) + self.assertEqual( + created_declaration.minimum_duration, str(version_declaration_to_create_as_declaration.vrsdecl_durabilite) ) - - created_declaration = Declaration.objects.get(siccrf_id=etablissement_to_create_as_company.etab_ident) - self.assertEqual(created_declaration.siccrf_id, etablissement_to_create_as_company.etab_ident) - self.assertEqual(created_declaration.address, etablissement_to_create_as_company.etab_adre_voie) - self.assertEqual(created_declaration.postal_code, etablissement_to_create_as_company.etab_adre_cp) - self.assertEqual(created_declaration.city, etablissement_to_create_as_company.etab_adre_ville) From 11eb1e1ecd863aa7b12cb189bccee67c8c4548c0 Mon Sep 17 00:00:00 2001 From: Alejandro MG Date: Mon, 13 Jan 2025 16:45:44 +0100 Subject: [PATCH 3/7] Adds FAQ page --- frontend/src/router/index.js | 9 + frontend/src/views/FaqPage.vue | 430 +++++++++++++++++++++++++++++++++ 2 files changed, 439 insertions(+) create mode 100644 frontend/src/views/FaqPage.vue diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index 92dd853fe..ec98fb297 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -35,6 +35,7 @@ import ContactForm from "@/views/ContactForm" import CompliancePage from "@/views/CompliancePage" import DeclaredElementPage from "@/views/DeclaredElementPage" import MandatedCompaniesPage from "@/views/MandatedCompaniesPage" +import FaqPage from "@/views/FaqPage" import { ref } from "vue" const routes = [ @@ -372,6 +373,14 @@ const routes = [ title: "Conformité au droit alimentaire", }, }, + { + path: "/faq", + name: "FaqPage", + component: FaqPage, + meta: { + title: "Foire aux questions", + }, + }, { path: "/:catchAll(.*)*", // https://stackoverflow.com/a/70343919/2255491 component: NotFound, diff --git a/frontend/src/views/FaqPage.vue b/frontend/src/views/FaqPage.vue new file mode 100644 index 000000000..0cbc2b61b --- /dev/null +++ b/frontend/src/views/FaqPage.vue @@ -0,0 +1,430 @@ + + + + From 262a1d2fc5646c44ea2d9efc19aff550f56b3c91 Mon Sep 17 00:00:00 2001 From: Alejandro MG Date: Mon, 13 Jan 2025 16:46:03 +0100 Subject: [PATCH 4/7] Adds blog post well --- frontend/src/views/BlogPostPage.vue | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/src/views/BlogPostPage.vue b/frontend/src/views/BlogPostPage.vue index 368ce9889..22548418c 100644 --- a/frontend/src/views/BlogPostPage.vue +++ b/frontend/src/views/BlogPostPage.vue @@ -10,9 +10,11 @@ />
-

{{ blogPost.title }}

-

{{ author }}

-

{{ date }}

+
+

{{ blogPost.title }}

+

{{ author }}

+

{{ date }}

+
From f75d85c18bdf02fb2697b74ba2998cf667b7b41b Mon Sep 17 00:00:00 2001 From: Alejandro MG Date: Mon, 13 Jan 2025 16:50:29 +0100 Subject: [PATCH 5/7] Adds FAQ to bar --- frontend/src/components/AppHeader.vue | 4 + frontend/src/views/FaqPage.vue | 845 +++++++++++++------------- 2 files changed, 432 insertions(+), 417 deletions(-) diff --git a/frontend/src/components/AppHeader.vue b/frontend/src/components/AppHeader.vue index 4441e0741..2309f3d2c 100644 --- a/frontend/src/components/AppHeader.vue +++ b/frontend/src/components/AppHeader.vue @@ -40,6 +40,10 @@ const navItems = [ to: "/blog", text: "Ressources", }, + { + to: "/faq", + text: "FAQ", + }, ] const loggedOnlyNavItems = [ { diff --git a/frontend/src/views/FaqPage.vue b/frontend/src/views/FaqPage.vue index 0cbc2b61b..9b3748fb5 100644 --- a/frontend/src/views/FaqPage.vue +++ b/frontend/src/views/FaqPage.vue @@ -1,421 +1,432 @@