added routing in app.tsx

This commit is contained in:
2025-10-24 17:52:47 +02:00
parent 875db3aeb7
commit 05fa87c638
5 changed files with 98 additions and 105 deletions

View File

@@ -22,10 +22,11 @@
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
"start": "vite", "dev": "vite",
"build": "tsc --noEmit && vite build", "build": "tsc --noEmit && vite build",
"preview": "vite preview", "build:community": "vite build",
"type-check": "tsc --noEmit" "build:commercial": "git submodule update --init --recursive && ENABLE_PRO=true vite build",
"preview": "vite preview"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.27", "@types/react": "^18.0.27",

View File

@@ -1,4 +1,4 @@
// frontend/src/App.tsx - UPDATED WITH FOOTER LINKS // frontend/src/App.tsx - ONE-REPO SAFE WITHOUT DYNAMIC IMPORTS
import React from 'react'; import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { AuthProvider, useAuth } from './contexts/AuthContext'; import { AuthProvider, useAuth } from './contexts/AuthContext';
@@ -16,16 +16,67 @@ import Settings from './pages/Settings/Settings';
import Help from './pages/Help/Help'; import Help from './pages/Help/Help';
import Setup from './pages/Setup/Setup'; import Setup from './pages/Setup/Setup';
// Footer Link Pages // Free Footer Link Pages (always available)
import FAQ from './components/Layout/FooterLinks/FAQ/FAQ'; import FAQ from './components/Layout/FooterLinks/FAQ/FAQ';
import About from './components/Layout/FooterLinks/About/About'; import About from './components/Layout/FooterLinks/About/About';
import Features from './components/Layout/FooterLinks/Features/Features'; import Features from './components/Layout/FooterLinks/Features/Features';
// PREMIUM Footer Link Pages // Feature flag from environment
import { Contact } from '@premium-frontend/componentsPRO/FooterLinksPro/Contact/Contact'; const ENABLE_PRO = process.env.ENABLE_PRO === 'true';
import { Privacy } from '@premium-frontend/componentsPRO/FooterLinksPro/Privacy/Privacy';
import Imprint from '../../premium/frontendPRO/src/componentsPRO/FooterLinksPro/Imprint/Imprint'; // Community fallback components (always available)
import Terms from '../../premium/frontendPRO/src/componentsPRO/FooterLinksPro/Terms/Terms'; const CommunityContact: React.FC = () => (
<div style={{ padding: '40px 20px', maxWidth: '800px', margin: '0 auto' }}>
<h1>📞 Kontakt</h1>
<div style={{ backgroundColor: 'white', borderRadius: '12px', padding: '30px', marginTop: '20px' }}>
<h2 style={{ color: '#2c3e50' }}>Community Edition</h2>
<p>Kontaktfunktionen sind in der Premium Edition verfügbar.</p>
<p>
<a href="/features" style={{ color: '#3498db' }}>
Zu den Features
</a>
</p>
</div>
</div>
);
const CommunityLegalPage: React.FC<{ title: string }> = ({ title }) => (
<div style={{ padding: '40px 20px', maxWidth: '800px', margin: '0 auto' }}>
<h1>📄 {title}</h1>
<div style={{ backgroundColor: 'white', borderRadius: '12px', padding: '30px', marginTop: '20px' }}>
<h2 style={{ color: '#2c3e50' }}>Community Edition</h2>
<p>Rechtliche Dokumentation ist in der Premium Edition verfügbar.</p>
<p>
<a href="/features" style={{ color: '#3498db' }}>
Erfahren Sie mehr über Premium
</a>
</p>
</div>
</div>
);
// Conditional Premium Components
let PremiumContact: React.FC = CommunityContact;
let PremiumPrivacy: React.FC = () => <CommunityLegalPage title="Datenschutz" />;
let PremiumImprint: React.FC = () => <CommunityLegalPage title="Impressum" />;
let PremiumTerms: React.FC = () => <CommunityLegalPage title="AGB" />;
// Load premium components only when ENABLE_PRO is true
if (ENABLE_PRO) {
try {
// Use require with type assertions to avoid dynamic import issues
const premiumModule = require('@premium-frontend/components/FooterLinks');
if (premiumModule.Contact) PremiumContact = premiumModule.Contact;
if (premiumModule.Privacy) PremiumPrivacy = premiumModule.Privacy;
if (premiumModule.Imprint) PremiumImprint = premiumModule.Imprint;
if (premiumModule.Terms) PremiumTerms = premiumModule.Terms;
console.log('✅ Premium components loaded successfully');
} catch (error) {
console.warn('⚠️ Premium components not available, using community fallbacks:', error);
}
}
// Protected Route Component // Protected Route Component
const ProtectedRoute: React.FC<{ children: React.ReactNode; roles?: string[] }> = ({ const ProtectedRoute: React.FC<{ children: React.ReactNode; roles?: string[] }> = ({
@@ -72,7 +123,6 @@ const PublicRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => {
); );
} }
// If user is logged in, show with layout, otherwise without
return user ? <Layout>{children}</Layout> : <>{children}</>; return user ? <Layout>{children}</Layout> : <>{children}</>;
}; };
@@ -81,6 +131,7 @@ const AppContent: React.FC = () => {
const { loading, needsSetup, user } = useAuth(); const { loading, needsSetup, user } = useAuth();
console.log('🏠 AppContent rendering - loading:', loading, 'needsSetup:', needsSetup, 'user:', user); console.log('🏠 AppContent rendering - loading:', loading, 'needsSetup:', needsSetup, 'user:', user);
console.log('🎯 Premium features enabled:', ENABLE_PRO);
// Während des Ladens // Während des Ladens
if (loading) { if (loading) {
@@ -108,93 +159,31 @@ const AppContent: React.FC = () => {
return ( return (
<Routes> <Routes>
{/* Protected Routes (require login) */} {/* Protected Routes (require login) */}
<Route path="/" element={ <Route path="/" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
<ProtectedRoute> <Route path="/shift-plans" element={<ProtectedRoute><ShiftPlanList /></ProtectedRoute>} />
<Dashboard /> <Route path="/shift-plans/new" element={<ProtectedRoute roles={['admin', 'maintenance']}><ShiftPlanCreate /></ProtectedRoute>} />
</ProtectedRoute> <Route path="/shift-plans/:id/edit" element={<ProtectedRoute roles={['admin', 'maintenance']}><ShiftPlanEdit /></ProtectedRoute>} />
} /> <Route path="/shift-plans/:id" element={<ProtectedRoute><ShiftPlanView /></ProtectedRoute>} />
<Route path="/shift-plans" element={ <Route path="/employees" element={<ProtectedRoute roles={['admin', 'maintenance']}><EmployeeManagement /></ProtectedRoute>} />
<ProtectedRoute> <Route path="/settings" element={<ProtectedRoute><Settings /></ProtectedRoute>} />
<ShiftPlanList /> <Route path="/help" element={<ProtectedRoute><Help /></ProtectedRoute>} />
</ProtectedRoute>
} />
<Route path="/shift-plans/new" element={
<ProtectedRoute roles={['admin', 'maintenance']}>
<ShiftPlanCreate />
</ProtectedRoute>
} />
<Route path="/shift-plans/:id/edit" element={
<ProtectedRoute roles={['admin', 'maintenance']}>
<ShiftPlanEdit />
</ProtectedRoute>
} />
<Route path="/shift-plans/:id" element={
<ProtectedRoute>
<ShiftPlanView />
</ProtectedRoute>
} />
<Route path="/employees" element={
<ProtectedRoute roles={['admin', 'maintenance']}>
<EmployeeManagement />
</ProtectedRoute>
} />
<Route path="/settings" element={
<ProtectedRoute>
<Settings />
</ProtectedRoute>
} />
<Route path="/help" element={
<ProtectedRoute>
<Help />
</ProtectedRoute>
} />
{/* Public Footer Link Pages (accessible without login, but show layout if logged in) */} {/* Public Footer Link Pages (always available) */}
<Route path="/contact" element={ <Route path="/faq" element={<PublicRoute><FAQ /></PublicRoute>} />
<PublicRoute> <Route path="/about" element={<PublicRoute><About /></PublicRoute>} />
<Contact /> <Route path="/features" element={<PublicRoute><Features /></PublicRoute>} />
</PublicRoute>
} /> {/* PREMIUM Footer Link Pages (conditionally available) */}
<Route path="/faq" element={ <Route path="/contact" element={<PublicRoute><PremiumContact /></PublicRoute>} />
<PublicRoute> <Route path="/privacy" element={<PublicRoute><PremiumPrivacy /></PublicRoute>} />
<FAQ /> <Route path="/imprint" element={<PublicRoute><PremiumImprint /></PublicRoute>} />
</PublicRoute> <Route path="/terms" element={<PublicRoute><PremiumTerms /></PublicRoute>} />
} />
<Route path="/privacy" element={
<PublicRoute>
<Privacy />
</PublicRoute>
} />
<Route path="/imprint" element={
<PublicRoute>
<Imprint />
</PublicRoute>
} />
<Route path="/terms" element={
<PublicRoute>
<Terms />
</PublicRoute>
} />
<Route path="/about" element={
<PublicRoute>
<About />
</PublicRoute>
} />
<Route path="/features" element={
<PublicRoute>
<Features />
</PublicRoute>
} />
{/* Auth Routes */} {/* Auth Routes */}
<Route path="/login" element={<Login />} /> <Route path="/login" element={<Login />} />
{/* Catch-all Route */} {/* Catch-all Route */}
<Route path="*" element={ <Route path="*" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
} />
</Routes> </Routes>
); );
}; };

View File

@@ -1,21 +1,22 @@
// frontend/tsconfig.json - SO FUNKTIONIERT ES
{ {
"extends": "../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"lib": [ "target": "ES2022",
"ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"],
"DOM",
"DOM.Iterable"
],
"jsx": "react-jsx", "jsx": "react-jsx",
"noEmit": true, "noEmit": true,
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"skipLibCheck": true, "skipLibCheck": true,
"moduleResolution": "bundler" "moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true,
"paths": {
"@premium-frontend/*": ["../premium/frontendPRO/src/*"]
}
}, },
"include": [ "include": [
"src/**/*" "src/**/*"
],
"references": [
{ "path": "../premium" }
] ]
} }

View File

@@ -8,8 +8,10 @@ export default defineConfig({
resolve: { resolve: {
alias: { alias: {
'@': resolve(__dirname, './src'), '@': resolve(__dirname, './src'),
'@premium-frontend': resolve(__dirname, '../premium/frontendPRO/src'), '@premium-frontend': resolve(__dirname, '../premium/frontendPRO/src')
'@premium-backend': resolve(__dirname, '../premium/backendPRO/src')
} }
},
define: {
'process.env.ENABLE_PRO': JSON.stringify(process.env.ENABLE_PRO === 'true')
} }
}); });

Submodule premium updated: 21a4671c16...6da71aebad