From 5082788360032801409f3439cdf18c5613616e80 Mon Sep 17 00:00:00 2001 From: maxgfr <25312957+maxgfr@users.noreply.github.com> Date: Fri, 11 Mar 2022 17:01:42 +0100 Subject: [PATCH] fix: stats --- src/components/index.ts | 1 + src/components/mention/part.stories.tsx | 27 +++++++++++++ src/components/stats/index.ts | 1 + src/components/stats/tile.stories.tsx | 26 +++++++++++++ src/components/stats/tile.tsx | 23 +++++++++++ src/config/layout.ts | 4 ++ src/lib/index.ts | 1 + src/lib/matomo.ts | 25 ++++++++++++ src/pages/stats.tsx | 52 +++++++++++++++++++++++++ 9 files changed, 160 insertions(+) create mode 100644 src/components/mention/part.stories.tsx create mode 100644 src/components/stats/index.ts create mode 100644 src/components/stats/tile.stories.tsx create mode 100644 src/components/stats/tile.tsx create mode 100644 src/lib/index.ts create mode 100644 src/lib/matomo.ts create mode 100644 src/pages/stats.tsx diff --git a/src/components/index.ts b/src/components/index.ts index 9167d5d6..99285742 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -5,3 +5,4 @@ export * from "./header/type"; export * from "./footer/type"; export * from "./landing"; export * from "./mention"; +export * from "./stats"; diff --git a/src/components/mention/part.stories.tsx b/src/components/mention/part.stories.tsx new file mode 100644 index 00000000..4d524e62 --- /dev/null +++ b/src/components/mention/part.stories.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { ComponentStory, ComponentMeta } from "@storybook/react"; +import { MentionPart } from "./part"; + +export default { + title: "MentionPart", + component: MentionPart, +} as ComponentMeta; + +const Template: ComponentStory = args => ( + +); + +export const Default = Template.bind({}); +Default.args = { + title: "Random title", + description: + "Non id incididunt labore enim amet cupidatat et quis in tempor ipsum ad velit cillum.", +}; + +export const WithChildren = Template.bind({}); +WithChildren.args = { + title: "Random title", + description: + "Non id incididunt labore enim amet cupidatat et quis in tempor ipsum ad velit cillum.", + children:
Hello world
, +}; diff --git a/src/components/stats/index.ts b/src/components/stats/index.ts new file mode 100644 index 00000000..4c4a6629 --- /dev/null +++ b/src/components/stats/index.ts @@ -0,0 +1 @@ +export * from "./tile"; diff --git a/src/components/stats/tile.stories.tsx b/src/components/stats/tile.stories.tsx new file mode 100644 index 00000000..d014e27b --- /dev/null +++ b/src/components/stats/tile.stories.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { ComponentStory, ComponentMeta } from "@storybook/react"; +import { StatsTile } from "./tile"; + +export default { + title: "StatsTile", + component: StatsTile, +} as ComponentMeta; + +const Template: ComponentStory = args => ( + +); + +export const Default = Template.bind({}); +Default.args = { + title: "Nombre de visites", + stats: "1.000.000", + description: "C'est le nombre d'utilisateur unique ayant visité le site", +}; + +export const WithDescription = Template.bind({}); +WithDescription.args = { + title: "Nombre de visites", + stats: "1.000.000", + description: "C'est le nombre d'utilisateur unique ayant visité le site", +}; diff --git a/src/components/stats/tile.tsx b/src/components/stats/tile.tsx new file mode 100644 index 00000000..1377ff7a --- /dev/null +++ b/src/components/stats/tile.tsx @@ -0,0 +1,23 @@ +export type StatsTileProps = { + title: string; + stats: string | number; + description?: string | React.ReactNode; +}; + +export const StatsTile = (props: StatsTileProps): JSX.Element => { + return ( +
+
+
+ {props.stats} +

{props.title}

+ {props.description && ( +
+

{props.description}

+
+ )} +
+
+
+ ); +}; diff --git a/src/config/layout.ts b/src/config/layout.ts index 498c9678..db338474 100644 --- a/src/config/layout.ts +++ b/src/config/layout.ts @@ -185,6 +185,10 @@ export const footerBottomSection: FooterBottomSectionProps = { title: "Politique de confidentialité", href: "/politique-confidentialite", }, + { + title: "Statistiques", + href: "/stats", + }, ], version: process.env.NEXT_PUBLIC_APP_VERSION ?? "X.X.X", repositoryUrl: process.env.NEXT_PUBLIC_APP_REPOSITORY_URL ?? "", diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 00000000..979bc643 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1 @@ +export * from "./matomo"; diff --git a/src/lib/matomo.ts b/src/lib/matomo.ts new file mode 100644 index 00000000..668961aa --- /dev/null +++ b/src/lib/matomo.ts @@ -0,0 +1,25 @@ +export type MatomoResult = { + nbPageViews: number; + nbUniqPageViews: number; + nbVisits: number; +}; + +export const fetchMatomoData = async (): Promise => { + const MATOMO_URL = [ + `${process.env.NEXT_PUBLIC_MATOMO_URL}/?module=API&method=VisitsSummary.getVisits&idSite=${process.env.NEXT_PUBLIC_MATOMO_SITE_ID}&format=JSON&period=month&date=today`, + `${process.env.NEXT_PUBLIC_MATOMO_URL}/?module=API&method=Actions.get&idSite=${process.env.NEXT_PUBLIC_MATOMO_SITE_ID}&format=JSON&period=month&date=today`, + ]; + const promises = MATOMO_URL.map(url => + fetch(url) + .then(data => data.json()) + .catch(() => { + return null; + }) + ); + const [nbVisitData, infoData] = await Promise.all(promises); + return { + nbPageViews: infoData?.nb_pageviews ?? 0, + nbUniqPageViews: infoData?.nb_uniq_pageviews ?? 0, + nbVisits: nbVisitData?.value ?? 0, + }; +}; diff --git a/src/pages/stats.tsx b/src/pages/stats.tsx new file mode 100644 index 00000000..30e124a8 --- /dev/null +++ b/src/pages/stats.tsx @@ -0,0 +1,52 @@ +import { StatsTile } from "@components"; +import { fetchMatomoData, MatomoResult } from "@lib"; +import type { NextPage } from "next"; +import { NextSeo } from "next-seo"; +import React, { useEffect } from "react"; + +const Index: NextPage = () => { + const [matomoData, setMatomoData] = React.useState(); + + useEffect(() => { + (async () => { + const matomoData = await fetchMatomoData(); + setMatomoData(matomoData); + })(); + }, []); + return ( + <> + +
+

Statistiques d'utilisation

+
+ + + +
+
+ + ); +}; + +export default Index;