diff --git a/src/app/(main)/settings/preferences/PreferenceSettings.tsx b/src/app/(main)/settings/preferences/PreferenceSettings.tsx index a2890ce9..cc2d1b62 100644 --- a/src/app/(main)/settings/preferences/PreferenceSettings.tsx +++ b/src/app/(main)/settings/preferences/PreferenceSettings.tsx @@ -4,6 +4,7 @@ import { DateRangeSetting } from './DateRangeSetting'; import { LanguageSetting } from './LanguageSetting'; import { ThemeSetting } from './ThemeSetting'; import { TimezoneSetting } from './TimezoneSetting'; +import { VersionSetting } from './VersionSetting'; export function PreferenceSettings() { const { user } = useLoginQuery(); @@ -31,6 +32,10 @@ export function PreferenceSettings() { + + + + ); } diff --git a/src/app/(main)/settings/preferences/VersionSetting.tsx b/src/app/(main)/settings/preferences/VersionSetting.tsx new file mode 100644 index 00000000..2cfdbeb7 --- /dev/null +++ b/src/app/(main)/settings/preferences/VersionSetting.tsx @@ -0,0 +1,31 @@ +'use client'; + +import { Text } from '@umami/react-zen'; +import { useEffect, useState } from 'react'; + +export function VersionSetting() { + const [version, setVersion] = useState(''); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchVersion = async () => { + try { + const response = await fetch('/api/version'); + const data = await response.json(); + setVersion(data.version || 'unknown'); + } catch (error) { + setVersion('unknown'); + } finally { + setLoading(false); + } + }; + + fetchVersion(); + }, []); + + if (loading) { + return Loading...; + } + + return {version}; +} diff --git a/src/app/api/version/route.ts b/src/app/api/version/route.ts new file mode 100644 index 00000000..af548f73 --- /dev/null +++ b/src/app/api/version/route.ts @@ -0,0 +1,35 @@ +import { readFile } from 'fs/promises'; +import { join } from 'path'; +import { parseRequest } from '@/lib/request'; +import { json } from '@/lib/response'; + +let cachedVersion: string | null = null; + +async function getVersion(): Promise { + if (cachedVersion) { + return cachedVersion; + } + + try { + const packageJsonPath = join(process.cwd(), 'package.json'); + const data = await readFile(packageJsonPath, 'utf-8'); + const packageJson = JSON.parse(data); + cachedVersion = packageJson.version || 'unknown'; + } catch (error) { + cachedVersion = 'unknown'; + } + + return cachedVersion; +} + +export async function GET(request: Request) { + const { error } = await parseRequest(request, null, { skipAuth: true }); + + if (error) { + return error(); + } + + const version = await getVersion(); + + return json({ version }); +} diff --git a/src/components/messages.ts b/src/components/messages.ts index 0438c06e..712495d8 100644 --- a/src/components/messages.ts +++ b/src/components/messages.ts @@ -351,6 +351,7 @@ export const labels = defineMessages({ growth: { id: 'label.growth', defaultMessage: 'Growth' }, account: { id: 'label.account', defaultMessage: 'Account' }, application: { id: 'label.application', defaultMessage: 'Application' }, + version: { id: 'label.version', defaultMessage: 'Version' }, saveSegment: { id: 'label.save-segment', defaultMessage: 'Save as segment' }, saveCohort: { id: 'label.save-cohort', defaultMessage: 'Save as cohort' }, analysis: { id: 'label.analysis', defaultMessage: 'Analysis' },