Skip to content

Commit 24001f2

Browse files
author
martinmeerAT
committed
Enable demo mode for GitHub Pages deployment - Use localStorage when no valid backend API is configured - Add demo mode notice banner in production - Smart backend detection checks for valid API URLs - Users can now test the app fully without backend
1 parent a4203f0 commit 24001f2

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

apps/main-app/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import { HashRouter, Route, Routes } from 'react-router'
55
import { AuthHandler } from './components/AuthHandler'
66
import { DevTools } from './components/DevTools'
7+
import { DemoModeNotice } from './components/DemoModeNotice'
78
import HomePage from './pages/Home'
89
import CarOverview from './pages/CarOverview'
910
import AddCar from './pages/AddCar'
@@ -17,6 +18,7 @@ import InMaintenance from './pages/InMaintenance'
1718
export default function App() {
1819
return (
1920
<AuthHandler>
21+
<DemoModeNotice />
2022
<HashRouter>
2123
<Routes>
2224
<Route path="/" element={<HomePage />} />
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// apps/main-app/src/components/DemoModeNotice.tsx
2+
import { useState, useEffect } from 'react';
3+
import { Alert, AlertDescription } from './ui/alert';
4+
import { Button } from './ui/button';
5+
import { Info, X } from 'lucide-react';
6+
import { ConfigService } from '../services/ConfigService';
7+
8+
/**
9+
* Notice banner shown in production when using demo/localStorage mode
10+
*/
11+
export function DemoModeNotice() {
12+
const [isDismissed, setIsDismissed] = useState(false);
13+
const [showNotice, setShowNotice] = useState(false);
14+
15+
useEffect(() => {
16+
// Only show in production when using localStorage (demo mode)
17+
const isProduction = process.env.NODE_ENV === 'production';
18+
const usingBackend = ConfigService.shouldUseBackend();
19+
const dismissed = sessionStorage.getItem('demo_notice_dismissed') === 'true';
20+
21+
setShowNotice(isProduction && !usingBackend && !dismissed);
22+
}, []);
23+
24+
const handleDismiss = () => {
25+
setIsDismissed(true);
26+
sessionStorage.setItem('demo_notice_dismissed', 'true');
27+
};
28+
29+
if (!showNotice || isDismissed) {
30+
return null;
31+
}
32+
33+
return (
34+
<div className="fixed top-0 left-0 right-0 z-50 p-4">
35+
<Alert className="bg-blue-50 border-blue-200 max-w-4xl mx-auto shadow-lg">
36+
<Info className="h-4 w-4 text-blue-600" />
37+
<AlertDescription className="flex items-start justify-between">
38+
<div className="flex-1 pr-4">
39+
<p className="text-sm text-blue-900 font-medium mb-1">
40+
🚀 Demo Mode
41+
</p>
42+
<p className="text-sm text-blue-800">
43+
You're using the demo version. All data is stored locally in your browser.
44+
Your data is private and will be saved for your next visit on this device.
45+
</p>
46+
</div>
47+
<Button
48+
variant="ghost"
49+
size="sm"
50+
onClick={handleDismiss}
51+
className="text-blue-600 hover:text-blue-800 hover:bg-blue-100"
52+
>
53+
<X className="h-4 w-4" />
54+
</Button>
55+
</AlertDescription>
56+
</Alert>
57+
</div>
58+
);
59+
}
60+

apps/main-app/src/services/ConfigService.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export class ConfigService {
99

1010
/**
1111
* Check if the app should use backend API or localStorage
12-
* Priority: localStorage override > environment variable > production default
12+
* Priority: localStorage override > valid API URL check > environment variable
1313
*/
1414
static shouldUseBackend(): boolean {
1515
// Check for manual override in localStorage (for development/testing)
@@ -18,9 +18,15 @@ export class ConfigService {
1818
return override === 'true';
1919
}
2020

21-
// Check environment variable
21+
// Check if we have a valid API URL configured
22+
const config = APP_CONFIG.getCurrentConfig();
23+
const hasValidApiUrl = config.API_URL &&
24+
!config.API_URL.includes('your-api-domain.com') &&
25+
!config.API_URL.includes('localhost');
26+
27+
// In production, only use backend if we have a valid API URL
2228
if (process.env.NODE_ENV === 'production') {
23-
return true;
29+
return hasValidApiUrl;
2430
}
2531

2632
// Development default - use localStorage

0 commit comments

Comments
 (0)