feat(admin): Show version info at top of sidebar
- Add package.json version to /api/version endpoint - Move version display from footer to top (next to logo) - Show format: v1.5.1 (abc1234) - 12/9/2024 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,18 @@
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
const router = Router();
|
||||
|
||||
// Read package.json version at startup
|
||||
let packageVersion = 'unknown';
|
||||
try {
|
||||
const packageJson = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));
|
||||
packageVersion = packageJson.version || 'unknown';
|
||||
} catch {
|
||||
// Fallback if package.json not found
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/version
|
||||
* Returns build version information for display in admin UI
|
||||
@@ -10,10 +21,11 @@ router.get('/', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const gitSha = process.env.APP_GIT_SHA || 'unknown';
|
||||
const versionInfo = {
|
||||
version: packageVersion,
|
||||
build_version: process.env.APP_BUILD_VERSION?.slice(0, 8) || 'dev',
|
||||
git_sha: gitSha.slice(0, 8) || 'unknown',
|
||||
git_sha_full: gitSha,
|
||||
build_time: process.env.APP_BUILD_TIME || new Date().toISOString(),
|
||||
build_time: process.env.APP_BUILD_TIME || 'unknown',
|
||||
image_tag: process.env.CONTAINER_IMAGE_TAG?.slice(0, 8) || 'local',
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
Menu,
|
||||
X,
|
||||
Users,
|
||||
UserCog,
|
||||
ListOrdered,
|
||||
Key,
|
||||
Bot
|
||||
@@ -30,6 +31,7 @@ interface LayoutProps {
|
||||
}
|
||||
|
||||
interface VersionInfo {
|
||||
version: string;
|
||||
build_version: string;
|
||||
git_sha: string;
|
||||
build_time: string;
|
||||
@@ -124,7 +126,14 @@ export function Layout({ children }: LayoutProps) {
|
||||
<path d="M3.5 6C2 8 1 10.5 1 13C1 18.5 6 22 12 22C18 22 23 18.5 23 13C23 10.5 22 8 20.5 6L12 12L3.5 6Z" opacity="0.7" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-lg font-bold text-gray-900">CannaIQ</span>
|
||||
<div>
|
||||
<span className="text-lg font-bold text-gray-900">CannaIQ</span>
|
||||
{versionInfo && (
|
||||
<p className="text-xs text-gray-400">
|
||||
v{versionInfo.version} ({versionInfo.git_sha}) {versionInfo.build_time !== 'unknown' && `- ${new Date(versionInfo.build_time).toLocaleDateString()}`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 mt-2 truncate">{user?.email}</p>
|
||||
</div>
|
||||
@@ -152,6 +161,7 @@ export function Layout({ children }: LayoutProps) {
|
||||
|
||||
<NavSection title="Admin">
|
||||
<NavLink to="/admin/orchestrator" icon={<Activity className="w-4 h-4" />} label="Orchestrator" isActive={isActive('/admin/orchestrator')} />
|
||||
<NavLink to="/users" icon={<UserCog className="w-4 h-4" />} label="Users" isActive={isActive('/users')} />
|
||||
<NavLink to="/workers" icon={<Users className="w-4 h-4" />} label="Workers" isActive={isActive('/workers')} />
|
||||
<NavLink to="/job-queue" icon={<ListOrdered className="w-4 h-4" />} label="Job Queue" isActive={isActive('/job-queue')} />
|
||||
<NavLink to="/admin/seo" icon={<FileText className="w-4 h-4" />} label="SEO Pages" isActive={isActive('/admin/seo')} />
|
||||
@@ -169,14 +179,6 @@ 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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user