Skip to main content

Version Management

The Ever Works Template includes a version management system that tracks the data repository version, displays version information to administrators, and provides automatic synchronization detection. This system monitors the Git-based CMS content repository and presents version details through configurable UI components.

Architecture Overview

ComponentPathPurpose
useVersionInfohooks/use-version-info.tsReact Query hook for fetching version data from the API
useVersionInfoUtilshooks/use-version-info.tsUtility hook for cache management
VersionDisplaycomponents/version/version-display.tsxConfigurable version display component
VersionTooltipcomponents/version/version-tooltip.tsxHover tooltip showing detailed version info
/api/versionapp/api/version/route.tsAPI endpoint returning current version data

Version Info Data Structure

The version system tracks the following data from the content repository:

FieldTypeDescription
commitstringShort commit hash of the current data version
datestringISO date string of the commit
authorstringCommit author name
messagestringCommit message
repositorystringRepository URL
lastSyncstringTimestamp of the last data synchronization

The useVersionInfo Hook

Interface

interface UseVersionInfoOptions {
refreshInterval?: number; // Auto-refresh interval in ms (default: 5 min)
retryOnError?: boolean; // Retry on failures (default: true)
enabled?: boolean; // Enable/disable the query (default: true)
}

interface UseVersionInfoReturn {
versionInfo: VersionInfo | null;
isLoading: boolean;
isError: boolean;
error: UseVersionInfoError | null;
refetch: () => Promise<any>;
isStale: boolean;
dataUpdatedAt: number;
invalidateVersionInfo: () => Promise<void>;
}

Usage

import { useVersionInfo } from '@/hooks/use-version-info';

function VersionIndicator() {
const { versionInfo, isLoading, error } = useVersionInfo({
refreshInterval: 5 * 60 * 1000, // 5 minutes
retryOnError: true
});

if (isLoading) return <span>Loading...</span>;
if (error) return <span>Version unavailable</span>;

return <span>v{versionInfo?.commit}</span>;
}

Caching Strategy

SettingValueDescription
staleTime5 minutesData considered fresh for 5 minutes
gcTime30 minutesGarbage collection after 30 minutes
refetchOnWindowFocusfalseNo refetch on tab switch
refetchOnReconnecttrueRefetch when network reconnects
refetchOnMountfalseSkip refetch if cache has data

Retry Logic

The hook implements intelligent retry with exponential backoff:

  • Does not retry on client errors (4xx status codes)
  • Retries network and server errors up to 2 times
  • Uses exponential backoff: min(1000 * 2^attempt, 30000ms)

Version Display Component

The VersionDisplay component supports three visual variants:

Inline Variant (Default)

A compact inline display showing the commit hash and relative time:

<VersionDisplay variant="inline" />
// Output: v abc1234 . 2h ago .

Badge Variant

A pill-shaped badge with gradient background:

<VersionDisplay variant="badge" />
// Output: [git-icon] v abc1234 . 2h ago

Detailed Variant

A card with full version information:

<VersionDisplay
variant="detailed"
showDetails={true}
refreshInterval={10 * 60 * 1000}
/>

The detailed variant shows:

  • Commit hash and relative time
  • Author name
  • Commit message (first line, quoted)
  • Last update timestamp (when showDetails is true)
  • Last sync timestamp
  • Repository name

Props

PropTypeDefaultDescription
classNamestring""Additional CSS classes
variant"inline" | "badge" | "detailed""inline"Display style
showDetailsbooleanfalseShow extended details (detailed variant only)
refreshIntervalnumber300000 (5 min)Auto-refresh interval in milliseconds

Access Control

The component respects user roles:

  • Regular users: Component is hidden when version info is unavailable
  • Dev/Admin users: Error state is shown with "Version unavailable" message
const isDevOrAdmin = useIsDevOrAdmin();

if (error || !versionInfo) {
if (!isDevOrAdmin) return null; // Hide for regular users
return <span>Version unavailable</span>; // Show error for admins
}

Version Tooltip

The VersionTooltip wraps any element with a hover tooltip displaying detailed version information:

import { VersionTooltip } from '@/components/version/version-tooltip';

function Footer() {
return (
<VersionTooltip delay={300}>
<span>Data v1.0</span>
</VersionTooltip>
);
}

Tooltip Features

FeatureDescription
Delayed showConfigurable delay before tooltip appears (default: 300ms)
Quick hide100ms delay on mouse leave for smooth interaction
Tooltip hoverTooltip stays visible when hovering over it
Keyboard supportEscape key dismisses the tooltip
AccessibilityARIA attributes (role="tooltip", aria-describedby)
Graceful degradationReturns children without tooltip when data is unavailable

Props

PropTypeDefaultDescription
childrenReactNoderequiredThe trigger element
classNamestring""Additional CSS classes
disabledbooleanfalseDisable tooltip entirely
delaynumber300Show delay in milliseconds

Cache Utilities

The useVersionInfoUtils hook provides cache management functions:

import { useVersionInfoUtils } from '@/hooks/use-version-info';

function AdminPanel() {
const {
prefetchVersionInfo,
invalidateVersionInfo,
getVersionInfoFromCache,
setVersionInfoInCache
} = useVersionInfoUtils();

// Prefetch version data before it is needed
useEffect(() => {
prefetchVersionInfo();
}, []);

// Force refresh
const handleRefresh = () => invalidateVersionInfo();

// Read directly from cache
const cached = getVersionInfoFromCache();
}

Date Formatting

The VersionDisplay component includes memoized date formatting utilities:

FunctionExample Output
formatDate"Jan 15, 2025, 02:30 PM"
getRelativeTime"Just now", "3h ago", "2d ago", "Jan 15"
getRepositoryName"ever-works/awesome-time-tracking-data"

Key Files

FilePath
Version Info Hookhooks/use-version-info.ts
Version Displaycomponents/version/version-display.tsx
Version Tooltipcomponents/version/version-tooltip.tsx
Version API Routeapp/api/version/route.ts