feat(frontend): enhance API credentials system and build configuration

Add real API support in demo mode with credential checking, implement build-time version injection from package.json, and refactor update checking with 24-hour caching. Migrate landing page from Vue to Astro with comprehensive UI components including Hero, Features, Benefits, and Tech Stack sections. Update CI/CD workflow with expanded cache paths and security scanner version pinned.
This commit is contained in:
Tomas Dvorak
2026-02-10 16:25:57 +01:00
parent d27cf14110
commit b083dac3f0
95 changed files with 17610 additions and 2692 deletions
+60
View File
@@ -0,0 +1,60 @@
// Utility functions to check if credentials are configured in environment variables
// Check if database credentials are configured
export const hasDatabaseCredentials = (): boolean => {
return !!(import.meta.env.VITE_DB_HOST &&
import.meta.env.VITE_DB_USER &&
import.meta.env.VITE_DB_PASSWORD &&
import.meta.env.VITE_DB_NAME);
};
// Check if search API credentials are configured
export const hasSearchCredentials = (): boolean => {
return !!(import.meta.env.VITE_BRAVE_API_KEY ||
import.meta.env.VITE_SERPER_API_KEY ||
import.meta.env.VITE_SEARCH_API_PROVIDER);
};
// Check if AI service credentials are configured
export const hasAICredentials = (): boolean => {
return !!(import.meta.env.VITE_LONGCAT_API_KEY ||
import.meta.env.VITE_MISTRAL_API_KEY ||
import.meta.env.VITE_GROK_API_KEY ||
import.meta.env.VITE_DEEPSEEK_API_KEY ||
import.meta.env.VITE_OPENROUTER_API_KEY ||
import.meta.env.VITE_OLLAMA_BASE_URL);
};
// Check if any credentials are configured
export const hasAnyCredentials = (): boolean => {
return hasDatabaseCredentials() ||
hasSearchCredentials() ||
hasAICredentials();
};
// Check if backend should be available (based on database credentials)
export const isBackendAvailable = (): boolean => {
return hasDatabaseCredentials();
};
// Check if search APIs should be available
export const isSearchAvailable = (): boolean => {
return hasSearchCredentials();
};
// Check if AI services should be available
export const isAIAvailable = (): boolean => {
return hasAICredentials();
};
// Get configured search provider
export const getSearchProvider = (): string => {
return import.meta.env.VITE_SEARCH_API_PROVIDER ||
(import.meta.env.VITE_BRAVE_API_KEY ? 'brave' :
import.meta.env.VITE_SERPER_API_KEY ? 'serper' : 'demo');
};
// Get API base URL
export const getApiBaseUrl = (): string => {
return import.meta.env.VITE_API_URL || 'http://localhost:8080';
};
+2 -14
View File
@@ -9,19 +9,7 @@ import {
getMockTimeEntries,
getMockVideos,
getMockLearningPaths,
getMockCalendarEvents,
getMockActivities,
getMockStats,
getPopularTags,
type MockDocument,
type MockBookmark,
type MockTask,
type MockNote,
type MockTimeEntry,
type MockVideo,
type MockLearningPath,
type MockCalendarEvent,
type MockActivity
getMockStats
} from './mockData';
// Check if we're in demo mode
@@ -250,7 +238,7 @@ export class DemoModeApiClient {
return this.request<T>(endpoint, { method: 'DELETE' });
}
async upload<T>(endpoint: string, formData: FormData): Promise<T> {
async upload<T>(_endpoint: string, formData: FormData): Promise<T> {
// For demo mode, simulate file upload
const file = formData.get('file') as File;
return {
+23
View File
@@ -1,5 +1,7 @@
// Demo mode API interceptor to provide mock data instead of making real API calls
import { hasAnyCredentials, isBackendAvailable, isSearchAvailable } from './credentials';
// Check if demo mode is enabled via environment variable
export const isEnvDemoMode = (): boolean => {
const result = import.meta.env.VITE_DEMO_MODE === 'true';
@@ -13,6 +15,21 @@ export const isDemoMode = (): boolean => {
return isEnvDemoMode();
};
// Check if we should use real APIs even in demo mode
export const shouldUseRealAPIs = (): boolean => {
return hasAnyCredentials();
};
// Check if we should use real backend API
export const shouldUseRealBackend = (): boolean => {
return isBackendAvailable();
};
// Check if we should use real search APIs
export const shouldUseRealSearch = (): boolean => {
return isSearchAvailable();
};
// Clear demo mode from localStorage
export const clearDemoMode = (): void => {
localStorage.removeItem('demoMode');
@@ -181,6 +198,12 @@ const generateMockAIProviders = () => [
// Demo mode fetch interceptor
export const demoFetch = async (url: string, options?: RequestInit): Promise<Response> => {
// Check if we should use real APIs even in demo mode
if (shouldUseRealAPIs()) {
console.log('[Demo Mode] Real credentials detected, using real API for:', url);
return fetch(url, options);
}
if (!isDemoMode()) {
return fetch(url, options);
}