mirror of
https://github.com/ajnart/homarr.git
synced 2025-10-26 08:06:12 +01:00
📈 Add umami analytics using homarr.dev
This commit is contained in:
20
.env.example
20
.env.example
@@ -1,22 +1,14 @@
|
||||
# Since the ".env" file is gitignored, you can use the ".env.example" file to
|
||||
# build a new ".env" file when you clone the repo. Keep this file up-to-date
|
||||
# when you add new variables to `.env`.
|
||||
|
||||
# This file will be committed to version control, so make sure not to have any
|
||||
# secrets in it. If you are cloning this repo, create a copy of this file named
|
||||
# ".env" and populate it with your secrets.
|
||||
|
||||
# When adding additional environment variables, the schema in "/src/env.js"
|
||||
# should be updated accordingly.
|
||||
|
||||
# Database
|
||||
DATABASE_URL="file:./database/db.sqlite"
|
||||
|
||||
# Next Auth
|
||||
# You can generate a new secret on the command line with:
|
||||
# openssl rand -base64 32
|
||||
# https://next-auth.js.org/configuration/options#secret
|
||||
# NEXTAUTH_SECRET=""
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
|
||||
NEXTAUTH_SECRET=""
|
||||
NEXTAUTH_SECRET="anything"
|
||||
|
||||
# Disable analytics
|
||||
NEXT_PUBLIC_DISABLE_ANALYTICS="true"
|
||||
|
||||
DEFAULT_COLOR_SCHEME="light"
|
||||
@@ -48,7 +48,7 @@
|
||||
"@nivo/core": "^0.83.0",
|
||||
"@nivo/line": "^0.83.0",
|
||||
"@react-native-async-storage/async-storage": "^1.18.1",
|
||||
"@t3-oss/env-nextjs": "^0.6.0",
|
||||
"@t3-oss/env-nextjs": "^0.7.1",
|
||||
"@tabler/icons-react": "^2.20.0",
|
||||
"@tanstack/query-async-storage-persister": "^4.27.1",
|
||||
"@tanstack/query-sync-storage-persister": "^4.27.1",
|
||||
@@ -118,6 +118,7 @@
|
||||
"@types/node": "18.17.8",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
"@types/react": "^18.2.11",
|
||||
"@types/umami": "^0.1.4",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@types/video.js": "^7.3.51",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useStyles } from './styles';
|
||||
|
||||
interface GenericAvailableElementTypeProps {
|
||||
name: string;
|
||||
id: string;
|
||||
handleAddition: () => Promise<void>;
|
||||
description?: string;
|
||||
image: string | Icon;
|
||||
@@ -16,6 +17,7 @@ interface GenericAvailableElementTypeProps {
|
||||
|
||||
export const GenericAvailableElementType = ({
|
||||
name,
|
||||
id,
|
||||
description,
|
||||
image,
|
||||
disabled,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Grid, Text } from '@mantine/core';
|
||||
import { Container, Grid, Text } from '@mantine/core';
|
||||
import { IconCursorText } from '@tabler/icons-react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
@@ -21,12 +21,13 @@ export const AvailableStaticTypes = ({ onClickBack }: AvailableStaticTypesProps)
|
||||
</Text>
|
||||
|
||||
<Grid grow>
|
||||
{/*
|
||||
<GenericAvailableElementType
|
||||
name="Static Text"
|
||||
description="Display a fixed string on your dashboard"
|
||||
image={IconCursorText}
|
||||
handleAddition={/* TODO: add something? */ async () => {}}
|
||||
/>
|
||||
handleAddition={async () => {}}
|
||||
/> */}
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -3,10 +3,10 @@ import { showNotification } from '@mantine/notifications';
|
||||
import { Icon, IconChecks } from '@tabler/icons-react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { useConfigContext } from '~/config/provider';
|
||||
import { useConfigStore } from '~/config/store';
|
||||
import { IWidget, IWidgetDefinition } from '~/widgets/widgets';
|
||||
|
||||
import { useEditModeStore } from '../../../../Views/useEditModeStore';
|
||||
import { GenericAvailableElementType } from '../Shared/GenericElementType';
|
||||
|
||||
@@ -97,6 +97,7 @@ export const WidgetElementType = ({ id, image, disabled, widget }: WidgetElement
|
||||
icon: <IconChecks stroke={1.5} />,
|
||||
color: 'teal',
|
||||
});
|
||||
umami.track('Add widget', { id: widget.id });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -104,6 +105,7 @@ export const WidgetElementType = ({ id, image, disabled, widget }: WidgetElement
|
||||
name={t('descriptor.name')}
|
||||
description={t('descriptor.description') ?? undefined}
|
||||
image={image}
|
||||
id={widget.id}
|
||||
disabled={disabled}
|
||||
handleAddition={handleAddition}
|
||||
/>
|
||||
|
||||
@@ -58,7 +58,9 @@ export const CreateBoardModal = ({ id }: ContextModalProps<{}>) => {
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={async () => {}}
|
||||
onClick={async () => {
|
||||
umami.track('Create new board')
|
||||
}}
|
||||
disabled={isLoading}
|
||||
variant="light"
|
||||
color="green"
|
||||
|
||||
@@ -117,4 +117,5 @@ export const openDockerSelectBoardModal = (innerProps: InnerProps) => {
|
||||
),
|
||||
innerProps,
|
||||
});
|
||||
umami.track('Add to homarr modal')
|
||||
};
|
||||
|
||||
@@ -106,6 +106,7 @@ export const ReviewInputStep = ({ values, prevStep, nextStep }: ReviewInputStepP
|
||||
password: values.security.password,
|
||||
email: values.account.eMail === '' ? undefined : values.account.eMail,
|
||||
});
|
||||
umami.track('Create user', { username: values.account.username});
|
||||
}}
|
||||
loading={isLoading}
|
||||
rightIcon={<IconCheck size="1rem" />}
|
||||
|
||||
@@ -66,6 +66,7 @@ export const CreateAccountSecurityStep = ({
|
||||
onClick={async () => {
|
||||
const randomPassword = await mutateAsync();
|
||||
form.setFieldValue('password', randomPassword);
|
||||
umami.track('Generate random password');
|
||||
}}
|
||||
loading={isLoading}
|
||||
variant="default"
|
||||
|
||||
@@ -59,6 +59,7 @@ export const StepCreateAccount = ({
|
||||
<Text>
|
||||
Your administrator account <b>must be secure</b>, that's why we have so many rules surrounding it.
|
||||
<br/>Try not to make it adminadmin this time...
|
||||
<br/>Note: these password requirements <b>are not forced</b>, they are just recommendations.
|
||||
</Text>
|
||||
<form onSubmit={form.onSubmit(handleSubmit)}>
|
||||
<Stack>
|
||||
|
||||
@@ -23,6 +23,7 @@ import { useScreenLargerThan } from '~/hooks/useScreenLargerThan';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
import { MainLayout } from './MainLayout';
|
||||
import { env } from 'process';
|
||||
|
||||
type BoardLayoutProps = {
|
||||
dockerEnabled: boolean;
|
||||
|
||||
@@ -36,6 +36,7 @@ const env = createEnv({
|
||||
*/
|
||||
client: {
|
||||
// NEXT_PUBLIC_CLIENTVAR: z.string().min(1),
|
||||
NEXT_PUBLIC_DISABLE_ANALYTICS: z.string(),
|
||||
NEXT_PUBLIC_PORT: portSchema,
|
||||
NEXT_PUBLIC_NODE_ENV: envSchema,
|
||||
NEXT_PUBLIC_DEFAULT_COLOR_SCHEME: z
|
||||
@@ -46,7 +47,6 @@ const env = createEnv({
|
||||
.default('light'),
|
||||
NEXT_PUBLIC_DOCKER_HOST: z.string().optional(),
|
||||
},
|
||||
|
||||
/**
|
||||
* You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.
|
||||
* middlewares) or client-side so we need to destruct manually.
|
||||
@@ -55,6 +55,7 @@ const env = createEnv({
|
||||
DATABASE_URL: process.env.DATABASE_URL,
|
||||
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
|
||||
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
|
||||
NEXT_PUBLIC_DISABLE_ANALYTICS: process.env.NEXT_PUBLIC_DISABLE_ANALYTICS,
|
||||
DOCKER_HOST: process.env.DOCKER_HOST,
|
||||
DOCKER_PORT: process.env.DOCKER_PORT,
|
||||
VERCEL_URL: process.env.VERCEL_URL,
|
||||
|
||||
@@ -13,27 +13,28 @@ import { Session } from 'next-auth';
|
||||
import { SessionProvider, getSession } from 'next-auth/react';
|
||||
import { appWithTranslation } from 'next-i18next';
|
||||
import { AppProps } from 'next/app';
|
||||
import Script from 'next/script';
|
||||
import { useEffect, useState } from 'react';
|
||||
import 'video.js/dist/video-js.css';
|
||||
import { CommonHead } from '~/components/layout/Meta/CommonHead';
|
||||
import { ConfigProvider } from '~/config/provider';
|
||||
import { env } from '~/env.js';
|
||||
import { ColorSchemeProvider } from '~/hooks/use-colorscheme';
|
||||
import { modals } from '~/modals';
|
||||
import { ColorTheme } from '~/tools/color';
|
||||
import { getLanguageByCode } from '~/tools/language';
|
||||
import {
|
||||
ServerSidePackageAttributesType,
|
||||
getServiceSidePackageAttributes,
|
||||
} from '~/tools/server/getPackageVersion';
|
||||
import { theme } from '~/tools/server/theme/theme';
|
||||
import { ConfigType } from '~/types/config';
|
||||
import { api } from '~/utils/api';
|
||||
import { colorSchemeParser } from '~/validations/user';
|
||||
|
||||
import { COOKIE_COLOR_SCHEME_KEY, COOKIE_LOCALE_KEY } from '../../data/constants';
|
||||
import nextI18nextConfig from '../../next-i18next.config.js';
|
||||
import { ConfigProvider } from '~/config/provider';
|
||||
import '../styles/global.scss';
|
||||
import { ColorTheme } from '~/tools/color';
|
||||
import {
|
||||
ServerSidePackageAttributesType,
|
||||
getServiceSidePackageAttributes,
|
||||
} from '~/tools/server/getPackageVersion';
|
||||
import { theme } from '~/tools/server/theme/theme';
|
||||
|
||||
dayjs.extend(locale);
|
||||
dayjs.extend(utc);
|
||||
@@ -92,6 +93,13 @@ function App(
|
||||
return (
|
||||
<>
|
||||
<CommonHead />
|
||||
{env.NEXT_PUBLIC_DISABLE_ANALYTICS !== 'true' && (
|
||||
<Script
|
||||
src="https://umami.homarr.dev/script.js"
|
||||
data-website-id="f133f10c-30a7-4506-889c-3a803f328fa4"
|
||||
strategy="lazyOnload"
|
||||
/>
|
||||
)}
|
||||
<SessionProvider session={pageProps.session}>
|
||||
<ColorSchemeProvider {...pageProps}>
|
||||
{(colorScheme) => (
|
||||
|
||||
34
yarn.lock
34
yarn.lock
@@ -1919,25 +1919,31 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@t3-oss/env-core@npm:0.6.1":
|
||||
version: 0.6.1
|
||||
resolution: "@t3-oss/env-core@npm:0.6.1"
|
||||
"@t3-oss/env-core@npm:0.7.1":
|
||||
version: 0.7.1
|
||||
resolution: "@t3-oss/env-core@npm:0.7.1"
|
||||
peerDependencies:
|
||||
typescript: ">=4.7.2"
|
||||
zod: ^3.0.0
|
||||
checksum: 6a1dd9d2f88643f6315a3add7eb6053a436a953a3c2b59b9743a2d8f28dbafcdaf4f6bccf0e7dfe424189834f75fbb53b9ac3891076a19b289468e4b406a340b
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 1a8447f5009931eb24a2e653723acd817585539d882c6c97b1df590df605045dee0e9abb3e6af083ec1492a6c143469947c4e4fef8d6c4a7e64cdf61ee8748d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@t3-oss/env-nextjs@npm:^0.6.0":
|
||||
version: 0.6.1
|
||||
resolution: "@t3-oss/env-nextjs@npm:0.6.1"
|
||||
"@t3-oss/env-nextjs@npm:^0.7.1":
|
||||
version: 0.7.1
|
||||
resolution: "@t3-oss/env-nextjs@npm:0.7.1"
|
||||
dependencies:
|
||||
"@t3-oss/env-core": 0.6.1
|
||||
"@t3-oss/env-core": 0.7.1
|
||||
peerDependencies:
|
||||
typescript: ">=4.7.2"
|
||||
zod: ^3.0.0
|
||||
checksum: c103a501b186c2a1633ead602fbd4e2d3096f736dceecba2f88a8c7b016c6f982a42bb8eb948e8069df93bf8d51a8a973e49a0a497d3da9282933683ced665e5
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: a1183bca68de4c3670a6e2e61839a9e54ab6472fbe49d4fc34665e43f2f05b379ae9b1880a122eb1bc42f7d6bd1160a543bbd3727543022d8f1fdc5b26290984
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -3102,6 +3108,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/umami@npm:^0.1.4":
|
||||
version: 0.1.4
|
||||
resolution: "@types/umami@npm:0.1.4"
|
||||
checksum: d3a970aec4553db91475fd67d8ca734ae18033c00b7ba9251e7a90050b6bd0f7961bf50ac1f576575a24ffa9b7ab78960cac14df4005a7b8429cb1682af013c2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/uuid@npm:^9.0.0":
|
||||
version: 9.0.4
|
||||
resolution: "@types/uuid@npm:9.0.4"
|
||||
@@ -7581,7 +7594,7 @@ __metadata:
|
||||
"@nivo/core": ^0.83.0
|
||||
"@nivo/line": ^0.83.0
|
||||
"@react-native-async-storage/async-storage": ^1.18.1
|
||||
"@t3-oss/env-nextjs": ^0.6.0
|
||||
"@t3-oss/env-nextjs": ^0.7.1
|
||||
"@tabler/icons-react": ^2.20.0
|
||||
"@tanstack/query-async-storage-persister": ^4.27.1
|
||||
"@tanstack/query-sync-storage-persister": ^4.27.1
|
||||
@@ -7606,6 +7619,7 @@ __metadata:
|
||||
"@types/node": 18.17.8
|
||||
"@types/prismjs": ^1.26.0
|
||||
"@types/react": ^18.2.11
|
||||
"@types/umami": ^0.1.4
|
||||
"@types/uuid": ^9.0.0
|
||||
"@types/video.js": ^7.3.51
|
||||
"@typescript-eslint/eslint-plugin": ^6.0.0
|
||||
|
||||
Reference in New Issue
Block a user