summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-02-23 18:11:37 +0100
committerGitHub <noreply@github.com>2022-02-23 18:11:37 +0100
commit84903c1e5182124b1bb618b7d8754cb70d0a6647 (patch)
treeb9202449b4eb17d2ecd93ce53fef76b0eee81f15 /src
parentc9b16994cd697b15ccb66be6879a119cf7bde7f7 (diff)
feat: improve Ackee tracking (#11)
* build(deps): add use-ackee hook package * chore: create a context provider for Ackee The provider allows users to change the 'detailed' settings. * chore: add a select menu to choose which info to share with Ackee * chore: add a tooltip for askee settings * chore: replace default select styles with custom styles * chore: register user choice in localstorage * chore: replace Matomo with Ackee in legal notice
Diffstat (limited to 'src')
-rw-r--r--src/components/Buttons/ButtonHelp/ButtonHelp.module.scss52
-rw-r--r--src/components/Buttons/ButtonHelp/ButtonHelp.tsx41
-rw-r--r--src/components/Buttons/index.tsx3
-rw-r--r--src/components/Form/Label/Label.module.scss22
-rw-r--r--src/components/Form/Label/Label.tsx24
-rw-r--r--src/components/Form/Select/Select.module.scss23
-rw-r--r--src/components/Form/Select/Select.tsx56
-rw-r--r--src/components/Form/index.tsx4
-rw-r--r--src/components/Settings/AckeeSelect/AckeeSelect.module.scss6
-rw-r--r--src/components/Settings/AckeeSelect/AckeeSelect.tsx83
-rw-r--r--src/components/Settings/Settings.tsx2
-rw-r--r--src/components/Tooltip/Tooltip.module.scss111
-rw-r--r--src/components/Tooltip/Tooltip.tsx57
m---------src/content0
-rw-r--r--src/pages/_app.tsx31
-rw-r--r--src/pages/mentions-legales.tsx8
-rw-r--r--src/utils/providers/ackee.tsx57
17 files changed, 563 insertions, 17 deletions
diff --git a/src/components/Buttons/ButtonHelp/ButtonHelp.module.scss b/src/components/Buttons/ButtonHelp/ButtonHelp.module.scss
new file mode 100644
index 0000000..b2a05d7
--- /dev/null
+++ b/src/components/Buttons/ButtonHelp/ButtonHelp.module.scss
@@ -0,0 +1,52 @@
+@use "@styles/abstracts/functions" as fun;
+@use "@styles/abstracts/mixins" as mix;
+
+.icon {
+ color: var(--color-primary-dark);
+ font-weight: 600;
+}
+
+.active {
+ .icon {
+ color: var(--color-fg-inverted);
+ }
+}
+
+.wrapper {
+ width: fun.convert-px(44);
+ height: fun.convert-px(44);
+ background: var(--color-bg);
+ border: fun.convert-px(3) solid var(--color-primary-dark);
+ border-radius: 50%;
+ box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow);
+ transition: all 0.3s ease-in-out 0s;
+
+ @include mix.pointer("fine") {
+ width: fun.convert-px(30);
+ height: fun.convert-px(30);
+ line-height: 1;
+ }
+
+ &:hover,
+ &:focus {
+ border-color: var(--color-primary-light);
+ color: var(--color-primary-light);
+ box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
+ var(--color-shadow-light),
+ fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
+ var(--color-shadow-light),
+ fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
+ var(--color-shadow-light),
+ fun.convert-px(7) fun.convert-px(10) fun.convert-px(12) fun.convert-px(-3)
+ var(--color-shadow-light);
+ transform: scale(1.1);
+
+ .icon {
+ transform: scale(1.1);
+ }
+ }
+
+ &.active {
+ background: var(--color-primary);
+ }
+}
diff --git a/src/components/Buttons/ButtonHelp/ButtonHelp.tsx b/src/components/Buttons/ButtonHelp/ButtonHelp.tsx
new file mode 100644
index 0000000..252e58c
--- /dev/null
+++ b/src/components/Buttons/ButtonHelp/ButtonHelp.tsx
@@ -0,0 +1,41 @@
+import { SetStateAction } from 'react';
+import { useIntl } from 'react-intl';
+import styles from './ButtonHelp.module.scss';
+
+const ButtonHelp = ({
+ showHelp,
+ setShowHelp,
+ title,
+}: {
+ showHelp: boolean;
+ setShowHelp: (value: SetStateAction<boolean>) => void;
+ title?: string;
+}) => {
+ const intl = useIntl();
+
+ const handleClick = () => {
+ setShowHelp((prev) => !prev);
+ };
+
+ const activeModifier = showHelp ? styles.active : '';
+
+ return (
+ <button
+ onClick={handleClick}
+ title={title}
+ className={`${styles.wrapper} ${activeModifier}`}
+ >
+ <span className={styles.icon} aria-hidden="true">
+ ?
+ </span>
+ <span className="screen-reader-text">
+ {intl.formatMessage({
+ defaultMessage: 'Help',
+ description: 'ButtonHelp: screen reader text',
+ })}
+ </span>
+ </button>
+ );
+};
+
+export default ButtonHelp;
diff --git a/src/components/Buttons/index.tsx b/src/components/Buttons/index.tsx
index 5c034ad..9b4b756 100644
--- a/src/components/Buttons/index.tsx
+++ b/src/components/Buttons/index.tsx
@@ -2,5 +2,6 @@ import Button from './Button/Button';
import ButtonLink from './ButtonLink/ButtonLink';
import ButtonToolbar from './ButtonToolbar/ButtonToolbar';
import ButtonSubmit from './ButtonSubmit/ButtonSubmit';
+import ButtonHelp from './ButtonHelp/ButtonHelp';
-export { Button, ButtonLink, ButtonToolbar, ButtonSubmit };
+export { Button, ButtonHelp, ButtonLink, ButtonToolbar, ButtonSubmit };
diff --git a/src/components/Form/Label/Label.module.scss b/src/components/Form/Label/Label.module.scss
new file mode 100644
index 0000000..c527b16
--- /dev/null
+++ b/src/components/Form/Label/Label.module.scss
@@ -0,0 +1,22 @@
+@use "@styles/abstracts/functions" as fun;
+
+.regular {
+ display: block;
+ color: var(--color-primary-darker);
+ font-size: var(--font-size-sm);
+ font-variant: small-caps;
+ font-weight: 600;
+}
+
+.settings {
+ --icon-size: #{fun.convert-px(25)};
+ --toggle-width: #{fun.convert-px(45)};
+ --toggle-height: calc(var(--toggle-width) / 2);
+
+ display: inline-flex;
+ align-items: center;
+}
+
+.required {
+ color: var(--color-secondary);
+}
diff --git a/src/components/Form/Label/Label.tsx b/src/components/Form/Label/Label.tsx
new file mode 100644
index 0000000..baedff0
--- /dev/null
+++ b/src/components/Form/Label/Label.tsx
@@ -0,0 +1,24 @@
+import styles from './Label.module.scss';
+
+type LabelKind = 'regular' | 'settings';
+
+const Label = ({
+ body,
+ htmlFor,
+ required = false,
+ kind = 'regular',
+}: {
+ body: string;
+ htmlFor: string;
+ required?: boolean;
+ kind?: LabelKind;
+}) => {
+ return (
+ <label htmlFor={htmlFor} className={styles[kind]}>
+ {body}
+ {required && <span className={styles.required}> *</span>}
+ </label>
+ );
+};
+
+export default Label;
diff --git a/src/components/Form/Select/Select.module.scss b/src/components/Form/Select/Select.module.scss
new file mode 100644
index 0000000..d4a40eb
--- /dev/null
+++ b/src/components/Form/Select/Select.module.scss
@@ -0,0 +1,23 @@
+@use "@styles/abstracts/functions" as fun;
+
+.wrapper {
+ padding: fun.convert-px(3) var(--spacing-xs);
+ background: var(--color-bg-tertiary);
+ border: fun.convert-px(2) solid var(--color-border);
+ box-shadow: fun.convert-px(3) fun.convert-px(3) 0 0 var(--color-shadow);
+ cursor: pointer;
+ transition: all 0.3s ease-in-out 0s;
+
+ &:hover {
+ box-shadow: fun.convert-px(4) fun.convert-px(4) 0 fun.convert-px(1)
+ var(--color-shadow);
+ transform: translate(#{fun.convert-px(-2)}, #{fun.convert-px(-2)});
+ }
+
+ &:focus {
+ background: var(--color-bg);
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 0 var(--color-shadow);
+ transform: translate(#{fun.convert-px(3)}, #{fun.convert-px(3)});
+ }
+}
diff --git a/src/components/Form/Select/Select.tsx b/src/components/Form/Select/Select.tsx
new file mode 100644
index 0000000..feab991
--- /dev/null
+++ b/src/components/Form/Select/Select.tsx
@@ -0,0 +1,56 @@
+import { ChangeEvent, ReactElement, SetStateAction } from 'react';
+import styles from './Select.module.scss';
+
+type SelectOptions = {
+ id: string;
+ name: string;
+ value: string;
+};
+
+const Select = ({
+ options,
+ id,
+ name,
+ value,
+ setValue,
+ required = false,
+ label,
+}: {
+ options: SelectOptions[];
+ id: string;
+ name: string;
+ value: string;
+ setValue: (value: SetStateAction<string>) => void;
+ required?: boolean;
+ label?: ReactElement;
+}) => {
+ const getOptions = () => {
+ return options.map((option) => (
+ <option key={option.id} value={option.value}>
+ {option.name}
+ </option>
+ ));
+ };
+
+ const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
+ setValue(event.target.value);
+ };
+
+ return (
+ <>
+ {label}
+ <select
+ name={name}
+ id={id}
+ value={value}
+ onChange={handleChange}
+ required={required}
+ className={styles.wrapper}
+ >
+ {getOptions()}
+ </select>
+ </>
+ );
+};
+
+export default Select;
diff --git a/src/components/Form/index.tsx b/src/components/Form/index.tsx
index 0908e9b..cbe1ec4 100644
--- a/src/components/Form/index.tsx
+++ b/src/components/Form/index.tsx
@@ -1,7 +1,9 @@
import Form from './Form';
import FormItem from './FormItem/FormItem';
import Input from './Input/Input';
+import Label from './Label/Label';
+import Select from './Select/Select';
import TextArea from './TextArea/TextArea';
import Toggle from './Toggle/Toggle';
-export { Form, FormItem, Input, TextArea, Toggle };
+export { Form, FormItem, Input, Label, Select, TextArea, Toggle };
diff --git a/src/components/Settings/AckeeSelect/AckeeSelect.module.scss b/src/components/Settings/AckeeSelect/AckeeSelect.module.scss
new file mode 100644
index 0000000..b145761
--- /dev/null
+++ b/src/components/Settings/AckeeSelect/AckeeSelect.module.scss
@@ -0,0 +1,6 @@
+.wrapper {
+ display: flex;
+ flex-flow: row wrap;
+ align-items: center;
+ gap: var(--spacing-xs);
+}
diff --git a/src/components/Settings/AckeeSelect/AckeeSelect.tsx b/src/components/Settings/AckeeSelect/AckeeSelect.tsx
new file mode 100644
index 0000000..58fc994
--- /dev/null
+++ b/src/components/Settings/AckeeSelect/AckeeSelect.tsx
@@ -0,0 +1,83 @@
+import { Label, Select } from '@components/Form';
+import Tooltip from '@components/Tooltip/Tooltip';
+import { LocalStorage } from '@services/local-storage';
+import { useAckeeTracker } from '@utils/providers/ackee';
+import { useEffect, useState } from 'react';
+import { useIntl } from 'react-intl';
+import styles from './AckeeSelect.module.scss';
+
+const AckeeSelect = () => {
+ const intl = useIntl();
+ const options = [
+ {
+ id: 'partial',
+ name: intl.formatMessage({
+ defaultMessage: 'Partial',
+ description: 'AckeeSelect: partial option name',
+ }),
+ value: 'partial',
+ },
+ {
+ id: 'full',
+ name: intl.formatMessage({
+ defaultMessage: 'Full',
+ description: 'AckeeSelect: full option name',
+ }),
+ value: 'full',
+ },
+ ];
+ const [value, setValue] = useState<string>('full');
+ const { setDetailed } = useAckeeTracker();
+
+ useEffect(() => {
+ setDetailed(value === 'full');
+ }, [setDetailed, value]);
+
+ useEffect(() => {
+ const initialState = LocalStorage.get('ackee-tracking');
+ if (initialState) setValue(initialState);
+ }, []);
+
+ useEffect(() => {
+ LocalStorage.set('ackee-tracking', `${value}`);
+ }, [value]);
+
+ const label = (
+ <Label
+ body={intl.formatMessage({
+ defaultMessage: 'Tracking:',
+ description: 'AckeeSelect: select label',
+ })}
+ htmlFor="ackee-settings"
+ kind="settings"
+ />
+ );
+
+ const message = [
+ intl.formatMessage({
+ defaultMessage: 'Partial includes only page url, views and duration.',
+ description: 'AckeeSelect: tooltip message',
+ }),
+ intl.formatMessage({
+ defaultMessage:
+ 'Full includes all information from partial as well as information about referrer, operating system, device, browser, screen size and language.',
+ description: 'AckeeSelect: tooltip message',
+ }),
+ ];
+
+ return (
+ <div className={styles.wrapper}>
+ <Select
+ id="ackee-settings"
+ name="ackee-settings"
+ label={label}
+ options={options}
+ value={value}
+ setValue={setValue}
+ />
+ <Tooltip message={message} title="Ackee tracking (analytics)" />
+ </div>
+ );
+};
+
+export default AckeeSelect;
diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx
index 9f38ecb..4ccb895 100644
--- a/src/components/Settings/Settings.tsx
+++ b/src/components/Settings/Settings.tsx
@@ -1,6 +1,7 @@
import { CogIcon } from '@components/Icons';
import ThemeToggle from '@components/Settings/ThemeToggle/ThemeToggle';
import { useIntl } from 'react-intl';
+import AckeeSelect from './AckeeSelect/AckeeSelect';
import PrismThemeToggle from './PrismThemeToggle/PrismThemeToggle';
import ReduceMotion from './ReduceMotion/ReduceMotion';
import styles from './Settings.module.scss';
@@ -20,6 +21,7 @@ const Settings = () => {
<ThemeToggle />
<ReduceMotion />
<PrismThemeToggle />
+ <AckeeSelect />
</>
);
};
diff --git a/src/components/Tooltip/Tooltip.module.scss b/src/components/Tooltip/Tooltip.module.scss
new file mode 100644
index 0000000..fb9fd94
--- /dev/null
+++ b/src/components/Tooltip/Tooltip.module.scss
@@ -0,0 +1,111 @@
+@use "@styles/abstracts/functions" as fun;
+@use "@styles/abstracts/mixins" as mix;
+
+.title {
+ padding: var(--spacing-2xs) var(--spacing-xs);
+ position: absolute;
+ top: calc(var(--spacing-sm) * -1);
+ left: var(--spacing-lg);
+ background: var(--color-bg);
+ border: fun.convert-px(1) solid var(--color-primary-dark);
+ box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow);
+ color: var(--color-primary-darker);
+ font-size: var(--font-size-sm);
+ font-variant: small-caps;
+ font-weight: 500;
+
+ @include mix.media("screen") {
+ @include mix.dimensions("md") {
+ left: var(--spacing-md);
+ }
+ }
+
+ &::before {
+ content: "?";
+ padding: var(--spacing-2xs);
+ position: absolute;
+ top: fun.convert-px(-1);
+ bottom: fun.convert-px(-1);
+ right: 100%;
+ background: var(--color-primary-dark);
+ border: fun.convert-px(1) solid var(--color-primary-dark);
+ box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow);
+ color: var(--color-fg-inverted);
+ font-weight: 600;
+ }
+}
+
+.message {
+ transition: all 0.5s ease-in-out 0;
+}
+
+.wrapper {
+ padding: var(--spacing-lg) var(--spacing-md) var(--spacing-sm)
+ var(--spacing-md);
+ position: absolute;
+ top: fun.convert-px(-30);
+ left: fun.convert-px(15);
+ right: fun.convert-px(15);
+ background: var(--color-bg);
+ border: fun.convert-px(2) solid var(--color-primary-dark);
+ border-radius: fun.convert-px(3);
+ box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow),
+ fun.convert-px(2) fun.convert-px(2) fun.convert-px(1) fun.convert-px(1)
+ var(--color-shadow-light);
+
+ @include mix.media("screen") {
+ @include mix.dimensions("sm") {
+ padding-top: var(--spacing-md);
+ bottom: unset;
+ left: fun.convert-px(15);
+ right: fun.convert-px(15);
+ top: calc(100% - #{fun.convert-px(4)});
+ }
+ }
+
+ ul,
+ p {
+ margin: 0;
+ padding: 0;
+ }
+}
+
+.hidden {
+ visibility: hidden;
+ opacity: 0;
+ max-height: 0;
+ transition: all 0.5s ease-in-out 0s, opacity 0.3s ease-in-out 0.2s;
+
+ .message,
+ .title {
+ opacity: 0;
+ }
+
+ .message {
+ transition: all 0.3s ease-in-out 0s;
+ }
+
+ .title {
+ transition: all 0.2s ease-in-out 0.2s;
+ }
+}
+
+.visible {
+ visibility: visible;
+ opacity: 1;
+ max-height: 100%;
+ transition: all 0.8s ease-in-out 0s, opacity 0.7s ease-in-out 0.2s;
+
+ .message,
+ .title {
+ opacity: 1;
+ }
+
+ .message {
+ transition: all 0.5s ease-in-out 0.2s;
+ }
+
+ .title {
+ transition: all 0.4s ease-in-out 0s;
+ }
+}
diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx
new file mode 100644
index 0000000..5929c96
--- /dev/null
+++ b/src/components/Tooltip/Tooltip.tsx
@@ -0,0 +1,57 @@
+import { ButtonHelp } from '@components/Buttons';
+import { useState } from 'react';
+import { useIntl } from 'react-intl';
+import styles from './Tooltip.module.scss';
+
+const Tooltip = ({
+ message,
+ title,
+}: {
+ message: string | string[];
+ title: string;
+}) => {
+ const intl = useIntl();
+ const [isOpen, setIsOpen] = useState<boolean>(false);
+
+ const getMessageFromArray = (strings: string[]) => {
+ let keyIndex = 0;
+ return (
+ <ul>
+ {strings.map((string) => {
+ keyIndex = keyIndex + 1;
+ return <li key={`message-${keyIndex}`}>{string}</li>;
+ })}
+ </ul>
+ );
+ };
+
+ const buttonTitle = isOpen
+ ? intl.formatMessage({
+ defaultMessage: 'Close help',
+ description: 'Tooltip: button title',
+ })
+ : intl.formatMessage({
+ defaultMessage: 'Show help',
+ description: 'Tooltip: button title',
+ });
+
+ const wrapperModifier = isOpen ? styles.visible : styles.hidden;
+
+ return (
+ <div>
+ <ButtonHelp
+ showHelp={isOpen}
+ setShowHelp={setIsOpen}
+ title={buttonTitle}
+ />
+ <div className={`${styles.wrapper} ${wrapperModifier}`}>
+ <div className={styles.title}>{title}</div>
+ <div className={styles.message}>
+ {Array.isArray(message) ? getMessageFromArray(message) : message}
+ </div>
+ </div>
+ </div>
+ );
+};
+
+export default Tooltip;
diff --git a/src/content b/src/content
-Subproject 697e897361e345b5829b092ecd6a5d4e8995590
+Subproject ff1f0159e077d8bb419b9eedb34bec1edcfd771
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 1f5be8f..e8c00de 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,5 +1,6 @@
import { AppPropsWithLayout } from '@ts/types/app';
import { settings } from '@utils/config';
+import { AckeeProvider } from '@utils/providers/ackee';
import { PrismThemeProvider } from '@utils/providers/prism';
import { ThemeProvider } from 'next-themes';
import { useRouter } from 'next/router';
@@ -12,21 +13,23 @@ const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => {
const getLayout = Component.getLayout ?? ((page) => page);
return (
- <IntlProvider
- locale={appLocale}
- defaultLocale={defaultLocale}
- messages={pageProps.translation}
- >
- <ThemeProvider
- defaultTheme="system"
- enableColorScheme={true}
- enableSystem={true}
+ <AckeeProvider domain={settings.ackee.url} siteId={settings.ackee.siteId}>
+ <IntlProvider
+ locale={appLocale}
+ defaultLocale={defaultLocale}
+ messages={pageProps.translation}
>
- <PrismThemeProvider>
- {getLayout(<Component {...pageProps} />)}
- </PrismThemeProvider>
- </ThemeProvider>
- </IntlProvider>
+ <ThemeProvider
+ defaultTheme="system"
+ enableColorScheme={true}
+ enableSystem={true}
+ >
+ <PrismThemeProvider>
+ {getLayout(<Component {...pageProps} />)}
+ </PrismThemeProvider>
+ </ThemeProvider>
+ </IntlProvider>
+ </AckeeProvider>
);
};
diff --git a/src/pages/mentions-legales.tsx b/src/pages/mentions-legales.tsx
index 67c4a97..1bc5c31 100644
--- a/src/pages/mentions-legales.tsx
+++ b/src/pages/mentions-legales.tsx
@@ -1,4 +1,5 @@
import { getLayout } from '@components/Layouts/Layout';
+import { Link } from '@components/MDX';
import PostHeader from '@components/PostHeader/PostHeader';
import Sidebar from '@components/Sidebar/Sidebar';
import { ToC } from '@components/Widgets';
@@ -11,6 +12,7 @@ import { NextPageWithLayout } from '@ts/types/app';
import { ArticleMeta } from '@ts/types/articles';
import { settings } from '@utils/config';
import { loadTranslation } from '@utils/helpers/i18n';
+import { NestedMDXComponents } from 'mdx/types';
import { GetStaticProps, GetStaticPropsContext } from 'next';
import Head from 'next/head';
import { useRouter } from 'next/router';
@@ -89,6 +91,10 @@ const LegalNotice: NextPageWithLayout = () => {
'@graph': [webpageSchema, articleSchema],
};
+ const components: NestedMDXComponents = {
+ Link: (props) => Link(props),
+ };
+
return (
<>
<Head>
@@ -113,7 +119,7 @@ const LegalNotice: NextPageWithLayout = () => {
<ToC />
</Sidebar>
<div className={styles.body}>
- <LegalNoticeContent />
+ <LegalNoticeContent components={components} />
</div>
</article>
</>
diff --git a/src/utils/providers/ackee.tsx b/src/utils/providers/ackee.tsx
new file mode 100644
index 0000000..c103668
--- /dev/null
+++ b/src/utils/providers/ackee.tsx
@@ -0,0 +1,57 @@
+import { useRouter } from 'next/router';
+import { createContext, FC, useContext, useState } from 'react';
+import useAckee from 'use-ackee';
+
+export type AckeeProps = {
+ domain: string;
+ siteId: string;
+ detailed?: boolean;
+ setDetailed: (isDetailed: boolean) => void;
+};
+
+export type AckeeProviderProps = {
+ domain: string;
+ siteId: string;
+ ignoreLocalhost?: boolean;
+ ignoreOwnVisits?: boolean;
+};
+
+export const AckeeContext = createContext<AckeeProps>({
+ domain: '',
+ siteId: '',
+ setDetailed: (_) => {
+ // Do nothing.
+ },
+});
+
+export const useAckeeTracker = () => useContext(AckeeContext);
+
+export const AckeeProvider: FC<AckeeProviderProps> = ({
+ domain,
+ siteId,
+ children,
+ ignoreLocalhost = true,
+ ignoreOwnVisits = true,
+}) => {
+ const [detailed, setDetailed] = useState<boolean>(false);
+ const { asPath } = useRouter();
+
+ useAckee(
+ asPath,
+ { server: domain, domainId: siteId },
+ { detailed, ignoreLocalhost, ignoreOwnVisits }
+ );
+
+ return (
+ <AckeeContext.Provider
+ value={{
+ domain,
+ siteId,
+ detailed,
+ setDetailed,
+ }}
+ >
+ {children}
+ </AckeeContext.Provider>
+ );
+};