From 540931750163c945b333e8995de2de65e80c8bde Mon Sep 17 00:00:00 2001 From: PEDZEO Date: Mon, 19 Jan 2026 07:17:49 +0300 Subject: [PATCH] Add VITE_APP_VERSION environment variable and integrate versioning into the application - Introduced VITE_APP_VERSION in Dockerfile and GitHub workflows to capture the version from Git tags. - Updated vite.config.ts to define a global constant for the app version. - Enhanced Layout component to display the app version in the footer for admin pages. - Added logic to conditionally render the LanguageSwitcher based on active promotions. --- .github/workflows/docker.yml | 1 + .github/workflows/release.yml | 1 + Dockerfile | 2 + src/components/layout/Layout.tsx | 70 ++++++++++++++++++++++---------- src/vite-env.d.ts | 3 ++ vite.config.ts | 17 ++++++++ 6 files changed, 73 insertions(+), 21 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 57fbd02..00c644b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -62,3 +62,4 @@ jobs: VITE_TELEGRAM_BOT_USERNAME= VITE_APP_NAME=Cabinet VITE_APP_LOGO=V + VITE_APP_VERSION=${{ github.ref_name }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe4ab04..8122984 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,6 +34,7 @@ jobs: VITE_TELEGRAM_BOT_USERNAME: VITE_APP_NAME: Bedolaga Cabinet VITE_APP_LOGO: V + VITE_APP_VERSION: ${{ github.ref_name }} - name: Create dist archive run: | diff --git a/Dockerfile b/Dockerfile index 8293e10..47c7a63 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,12 +18,14 @@ ARG VITE_API_URL=/api ARG VITE_TELEGRAM_BOT_USERNAME ARG VITE_APP_NAME=Cabinet ARG VITE_APP_LOGO=V +ARG VITE_APP_VERSION # Set environment variables for build ENV VITE_API_URL=$VITE_API_URL ENV VITE_TELEGRAM_BOT_USERNAME=$VITE_TELEGRAM_BOT_USERNAME ENV VITE_APP_NAME=$VITE_APP_NAME ENV VITE_APP_LOGO=$VITE_APP_LOGO +ENV VITE_APP_VERSION=$VITE_APP_VERSION # Build the application RUN npm run build diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index ad725d1..d3a4734 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -11,6 +11,7 @@ import { pollsApi } from '../../api/polls' import { brandingApi } from '../../api/branding' import { wheelApi } from '../../api/wheel' import { themeColorsApi } from '../../api/themeColors' +import { promoApi } from '../../api/promo' import { useTheme } from '../../hooks/useTheme' // Fallback branding from environment variables @@ -210,6 +211,17 @@ export default function Layout({ children }: LayoutProps) { retry: false, }) + // Fetch active discount to determine mobile layout + const { data: activeDiscount } = useQuery({ + queryKey: ['active-discount'], + queryFn: promoApi.getActiveDiscount, + enabled: isAuthenticated, + staleTime: 30000, + }) + + // Check if promo is active (to hide language switcher on mobile) + const isPromoActive = activeDiscount?.is_active && activeDiscount?.discount_percent + const navItems = useMemo(() => { const items = [ { path: '/', label: t('nav.dashboard'), icon: HomeIcon }, @@ -339,7 +351,10 @@ export default function Layout({ children }: LayoutProps) { - + {/* Hide language switcher on mobile when promo is active */} +
+ +
{/* Profile - Desktop */}
@@ -389,29 +404,33 @@ export default function Layout({ children }: LayoutProps) {
{/* User info */} -
- {userPhotoUrl ? ( - Avatar { - e.currentTarget.style.display = 'none' - e.currentTarget.nextElementSibling?.classList.remove('hidden') - }} - /> - ) : null} -
- -
-
-
- {user?.first_name || user?.username} +
+
+ {userPhotoUrl ? ( + Avatar { + e.currentTarget.style.display = 'none' + e.currentTarget.nextElementSibling?.classList.remove('hidden') + }} + /> + ) : null} +
+
-
- @{user?.username || `ID: ${user?.telegram_id}`} +
+
+ {user?.first_name || user?.username} +
+
+ @{user?.username || `ID: ${user?.telegram_id}`} +
+ {/* Language switcher in mobile menu when promo is active */} + {isPromoActive && }
{/* Nav items */} @@ -480,6 +499,15 @@ export default function Layout({ children }: LayoutProps) {
{children}
+ + {/* Version footer for admin pages */} + {isAdminActive() && ( +
+ + Cabinet {__APP_VERSION__} + +
+ )} {/* Mobile Bottom Navigation - only core items */} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index c61a7b6..8add16d 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1,5 +1,8 @@ /// +// Global constant defined in vite.config.ts +declare const __APP_VERSION__: string + interface ImportMetaEnv { readonly VITE_API_URL: string readonly VITE_TELEGRAM_BOT_USERNAME?: string diff --git a/vite.config.ts b/vite.config.ts index 01d8f8a..45054e0 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,26 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' +import { execSync } from 'child_process' + +// Get version from Git tag or fallback to 'dev' +function getGitVersion(): string { + try { + // Try to get version from git tag + return execSync('git describe --tags --always', { encoding: 'utf-8' }).trim() + } catch { + return 'dev' + } +} + +const appVersion = process.env.VITE_APP_VERSION || getGitVersion() // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], + // Define global constants + define: { + __APP_VERSION__: JSON.stringify(appVersion), + }, // Base path - use '/' for standalone Docker deployment // Change to '/cabinet/' if serving from a sub-path base: '/',