import React, { useCallback, useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import { ArrowLeft, ArrowUpCircle, CheckCircle2, Info, Loader2, Sparkles, AlertCircle } from 'lucide-react'; import { api } from '@/api'; import { useAuth } from '@/hooks/useAuth'; import { APP_VERSION } from '@/lib/version'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; const REPOSITORY_URL = 'https://dream.scheller.ltd/null/BillTracker'; function UpdateBadge({ status, loading }) { if (loading) { return ( Checking… ); } if (!status) return null; if (status.has_update) { return ( v{status.latest_version} available ); } if (status.up_to_date) { return ( Up to date ); } // up_to_date is null — check failed return ( Could not check ); } export default function AboutPage() { const { user } = useAuth(); const [about, setAbout] = useState(null); const [loading, setLoading] = useState(true); const [updateStatus, setUpdateStatus] = useState(null); const [updateLoading, setUpdateLoading] = useState(true); const load = useCallback(async () => { setLoading(true); try { setAbout(await api.about()); } finally { setLoading(false); } }, []); useEffect(() => { load(); }, [load]); useEffect(() => { setUpdateLoading(true); api.updateStatus() .then(setUpdateStatus) .catch(() => setUpdateStatus(null)) .finally(() => setUpdateLoading(false)); }, []); // Use Vite-injected APP_VERSION as the immediate source of truth. // api.about() version is shown once loaded as a cross-check; they should always match. const displayVersion = about?.version ?? APP_VERSION; return (
{about?.name || 'BillTracker'} {about?.description || ''}
{/* Version card — shows immediately via APP_VERSION, update status alongside */}

Version

v{displayVersion}

Backend

{about?.stack?.backend || 'Node.js / Express'}

Storage

{about?.stack?.database || 'SQLite'}

Produced with AI assistance

BillTracker is self-hosted software for personal bill planning and history. This product was produced with the assistance of AI.

{user == null && ( )}
); }