Add version display in admin sidebar footer

- Add /api/version endpoint that returns build info from env vars
- Add version footer to Layout.tsx showing build version, git SHA, and image tag
- Update Dockerfile to accept build args for version info (APP_BUILD_VERSION, APP_GIT_SHA, APP_BUILD_TIME, CONTAINER_IMAGE_TAG)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Kelly
2025-11-30 10:01:10 -07:00
parent afc71e4225
commit 0083f6a510
4 changed files with 73 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
import { ReactNode } from 'react';
import { ReactNode, useEffect, useState } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useAuthStore } from '../store/authStore';
import { api } from '../lib/api';
import {
LayoutDashboard,
Store,
@@ -24,6 +25,13 @@ interface LayoutProps {
children: ReactNode;
}
interface VersionInfo {
build_version: string;
git_sha: string;
build_time: string;
image_tag: string;
}
interface NavLinkProps {
to: string;
icon: ReactNode;
@@ -69,6 +77,19 @@ export function Layout({ children }: LayoutProps) {
const navigate = useNavigate();
const location = useLocation();
const { user, logout } = useAuthStore();
const [versionInfo, setVersionInfo] = useState<VersionInfo | null>(null);
useEffect(() => {
const fetchVersion = async () => {
try {
const response = await api.get('/version');
setVersionInfo(response.data);
} catch (error) {
console.error('Failed to fetch version info:', error);
}
};
fetchVersion();
}, []);
const handleLogout = () => {
logout();
@@ -206,6 +227,18 @@ export function Layout({ children }: LayoutProps) {
<span>Logout</span>
</button>
</div>
{/* Version Footer */}
{versionInfo && (
<div className="px-3 py-2 border-t border-gray-200 bg-gray-50">
<p className="text-xs text-gray-500 text-center">
{versionInfo.build_version} ({versionInfo.git_sha.slice(0, 7)})
</p>
<p className="text-xs text-gray-400 text-center mt-0.5">
{versionInfo.image_tag}
</p>
</div>
)}
</div>
{/* Main Content */}