Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions frontend/src/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
ChevronDownIcon,
ChevronRightIcon,
RocketLaunchIcon,
LightBulbIcon,

Check warning on line 14 in frontend/src/app/about/page.tsx

View workflow job for this annotation

GitHub Actions / verify-frontend

'LightBulbIcon' is defined but never used
CheckCircleIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { ROUTES } from '@/lib/routes';

const AboutPage = () => {
const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set());
Expand Down Expand Up @@ -475,14 +476,14 @@

<div className="flex flex-col sm:flex-row gap-6 justify-center">
<Link
href="/builder"
href={ROUTES.builder}
className="inline-flex items-center justify-center rounded-xl bg-white px-8 py-4 text-lg font-semibold text-blue-600 shadow-lg hover:bg-gray-50 transition-all hover:scale-105"
>
<RocketLaunchIcon className="mr-3 h-6 w-6" />
Formular-Builder testen
</Link>
<Link
href="/erfassung"
href={ROUTES.erfassung}
className="inline-flex items-center justify-center rounded-xl bg-transparent border-2 border-white px-8 py-4 text-lg font-semibold text-white hover:bg-white hover:text-blue-600 transition-all hover:scale-105"
>
<CameraIcon className="mr-3 h-6 w-6" />
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { notFound } from 'next/navigation';
import { MDXContentClient } from './MDXContentClient';
import Image from 'next/image';
import Link from 'next/link';
import { ROUTES } from '@/lib/routes';

export const generateStaticParams = async () => allPosts.map((p) => ({ slug: p.slug }));

Expand Down Expand Up @@ -45,7 +46,7 @@ export default async function BlogPostPage({ params }: PageProps) {
<div className="mt-16 border-t pt-10 text-center">
<h2 className="text-2xl font-bold mb-4">Teste den Universal Form Builder selbst</h2>
<Link
href="/builder"
href={ROUTES.builder}
className="inline-block rounded-lg bg-indigo-600 px-6 py-3 text-white font-semibold hover:bg-indigo-700"
>
Zum Builder →
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/app/components/FormCaptureLanding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ServerIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { ROUTES } from '@/lib/routes';

interface FormCaptureLandingProps {
onStartBuilding: () => void;
Expand Down Expand Up @@ -410,7 +411,7 @@ export function FormCaptureLanding({ onStartBuilding }: FormCaptureLandingProps)
Formular erstellen
</button>
<Link
href="/erfassung"
href={ROUTES.erfassung}
className="inline-flex items-center justify-center rounded-xl bg-white/10 border border-white/20 px-8 py-4 text-lg font-semibold text-white shadow-lg hover:bg-white/20 transition-colors"
>
Produkt-Erfassung erkunden →
Expand Down
9 changes: 5 additions & 4 deletions frontend/src/app/components/GlobalNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

import { usePathname, useRouter } from 'next/navigation';
import { TopNavigation } from './TopNavigation';
import { ROUTES } from '@/lib/routes';

function mapPathToView(path: string): 'builder' | 'templates' | 'saved-forms' | 'about' {
if (path.startsWith('/templates')) return 'templates';
if (path.startsWith('/forms')) return 'saved-forms';
if (path.startsWith('/about')) return 'about';
if (path.startsWith(ROUTES.templates)) return 'templates';
if (path.startsWith(ROUTES.forms)) return 'saved-forms';
if (path.startsWith(ROUTES.about)) return 'about';
return 'builder';
}

Expand All @@ -22,7 +23,7 @@ export default function GlobalNavigation() {
<TopNavigation
currentView={currentView}
onViewChange={(view) => {
const target = view === 'saved-forms' ? '/forms' : `/${view}`;
const target = view === 'saved-forms' ? ROUTES.forms : `/${view}`;
router.push(target);
}}
/>
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/app/components/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { useState } from 'react';
import Link from 'next/link';
import { useAuth } from '../context/AuthContext';
import { http, ApiSuccess } from '../services/http';
import { ROUTES } from '@/lib/routes';

interface LoginFormProps {
onSuccess?: () => void; // Optional callback for successful login
Expand Down Expand Up @@ -90,7 +91,10 @@ export function LoginForm({ onSuccess, showRegisterLink = true, className = '' }
{showRegisterLink && (
<p className="text-sm text-center text-gray-600 dark:text-gray-400">
Noch kein Konto?{' '}
<Link href="/register" className="font-medium text-indigo-600 hover:text-indigo-500">
<Link
href={ROUTES.register}
className="font-medium text-indigo-600 hover:text-indigo-500"
>
Registrieren
</Link>
</p>
Expand Down
46 changes: 25 additions & 21 deletions frontend/src/app/components/TopNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Link from 'next/link';
import Image from 'next/image';
import { useAuth } from '../context/AuthContext';
import { useBrandName } from '../../hooks/useBranding';
import { ROUTES } from '@/lib/routes';

// Define types for navigation items
type NavItem = {
Expand Down Expand Up @@ -96,11 +97,11 @@ interface TopNavigationProps {
}

const navigation = [
{ name: 'Builder', href: '/builder' },
{ name: 'Forms', href: '/forms' },
{ name: 'Templates', href: '/templates' },
{ name: 'About', href: '/about' },
{ name: 'Blog', href: '/blog' },
{ name: 'Builder', href: ROUTES.builder },
{ name: 'Forms', href: ROUTES.forms },
{ name: 'Templates', href: ROUTES.templates },
{ name: 'About', href: ROUTES.about },
{ name: 'Blog', href: ROUTES.blog },
];

export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavigationProps) {
Expand All @@ -117,13 +118,13 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
const primaryLinks: NavItem[] = [
{
name: 'Form-Tool',
href: '/builder',
href: ROUTES.builder,
description: 'Builder, Bibliothek & Gespeicherte unter einem Dach.',
icon: DocumentChartBarIcon,
},
{
name: 'Foto-Inventar',
href: '/erfassung',
href: ROUTES.erfassung,
description: 'Inventar-Erfassung per Fotoscan mit KI.',
icon: CameraIcon,
},
Expand All @@ -133,19 +134,19 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
const formSubmenuItems: NavItem[] = [
{
name: 'Form Builder',
href: '/builder',
href: ROUTES.builder,
description: 'Erstelle neue Formulare mit unserem Builder.',
icon: DocumentChartBarIcon,
},
{
name: 'Template Library',
href: '/templates',
href: ROUTES.templates,
description: 'Durchsuche vorgefertigte Form-Templates.',
icon: FolderIcon,
},
{
name: 'Saved Forms',
href: '/forms',
href: ROUTES.forms,
description: 'Verwalte deine gespeicherten Formulare.',
icon: DocumentDuplicateIcon,
},
Expand Down Expand Up @@ -259,9 +260,9 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
key={subItem.name}
href={subItem.href}
onClick={(e) => {
if (subItem.href === '/forms' && !token) {
if (subItem.href === ROUTES.forms && !token) {
e.preventDefault();
window.location.href = '/login';
window.location.href = ROUTES.login;
return;
}
e.preventDefault();
Expand Down Expand Up @@ -324,7 +325,7 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
<div className="px-5 py-5 bg-gray-50 dark:bg-gray-800 space-y-6 sm:flex sm:space-y-0 sm:space-x-10 sm:px-8">
<div className="flow-root">
<Link
href="/about"
href={ROUTES.about}
onClick={() => {
onViewChange('about');
setMegaMenuOpen(false);
Expand Down Expand Up @@ -356,21 +357,21 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
</div>

<Link
href="/about"
href={ROUTES.about}
onClick={() => onViewChange('about')}
className="text-base font-medium text-gray-500 hover:text-gray-900"
>
Über uns
</Link>
<Link
href="/about/faq"
href={ROUTES.aboutFaq}
onClick={() => onViewChange('about')}
className="text-base font-medium text-gray-500 hover:text-gray-900"
>
FAQ
</Link>
<Link
href="/blog"
href={ROUTES.blog}
onClick={() => onViewChange('about')}
className="text-base font-medium text-gray-500 hover:text-gray-900"
>
Expand Down Expand Up @@ -402,7 +403,7 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
<Menu.Item>
{({ active }) => (
<Link
href="/profile"
href={ROUTES.profile}
className={`${active ? 'bg-gray-100 dark:bg-gray-700' : ''} group flex w-full items-center rounded-md px-2 py-2 text-sm text-gray-900 dark:text-gray-100`}
>
Profil
Expand All @@ -426,13 +427,13 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
) : (
<>
<Link
href="/login"
href={ROUTES.login}
className="text-base font-medium text-gray-500 hover:text-gray-900"
>
Anmelden
</Link>
<Link
href="/register"
href={ROUTES.register}
className="inline-flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700"
>
Registrieren
Expand Down Expand Up @@ -496,14 +497,17 @@ export function TopNavigation({ currentView, onViewChange = () => {} }: TopNavig
) : (
<div>
<Link
href="/register"
href={ROUTES.register}
className="w-full flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700"
>
Registrieren
</Link>
<p className="mt-6 text-center text-base font-medium text-gray-500">
Bestehender Kunde?{' '}
<Link href="/login" className="text-indigo-600 hover:text-indigo-500">
<Link
href={ROUTES.login}
className="text-indigo-600 hover:text-indigo-500"
>
Anmelden
</Link>
</p>
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/app/context/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React, { createContext, useContext, ReactNode } from 'react';
import { signOut, signIn, useSession } from 'next-auth/react';
import { useRouter } from 'next/navigation';
import { ROUTES } from '@/lib/routes';

interface User {
id: string;
Expand All @@ -28,15 +29,15 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
const loginWithCredentials = async (email: string, password: string) => {
const res = await signIn('credentials', { redirect: false, email, password });
if (res?.ok) {
router.push('/builder');
router.push(ROUTES.builder);
return true;
}
return false;
};

const logout = async () => {
await signOut({ redirect: false });
router.push('/login');
router.push(ROUTES.login);
};

const value: AuthContextType = {
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/app/databases/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ArrowDownTrayIcon,
} from '@heroicons/react/24/outline';
import { useAuth } from '../context/AuthContext';
import { ROUTES } from '@/lib/routes';

interface Database {
id: string;
Expand Down Expand Up @@ -123,7 +124,7 @@ export default function DatabasesPage() {
</p>
</div>
<Link
href="/forms"
href={ROUTES.forms}
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700"
>
<PlusIcon className="h-5 w-5 mr-2" />
Expand Down Expand Up @@ -328,7 +329,7 @@ export default function DatabasesPage() {
</p>
<div className="mt-6">
<Link
href="/forms"
href={ROUTES.forms}
className="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700"
>
<PlusIcon className="h-5 w-5 mr-2" />
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/app/erfassung/components/TableOverviewStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { DocumentChartBarIcon, PlusIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { WorkflowProduct } from './ErfassungWorkflow';
import { ROUTES } from '@/lib/routes';

interface TableOverviewStepProps {
product: WorkflowProduct;
Expand Down Expand Up @@ -125,7 +126,7 @@ export function TableOverviewStep({ product, onBackToWorkflow }: TableOverviewSt
{/* Action Buttons */}
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Link
href="/erfassung/table"
href={ROUTES.erfassungTable}
className="inline-flex items-center justify-center px-6 py-3 bg-indigo-600 text-white rounded-md font-medium hover:bg-indigo-700 transition-colors"
>
<DocumentChartBarIcon className="h-5 w-5 mr-2" />
Expand All @@ -141,7 +142,7 @@ export function TableOverviewStep({ product, onBackToWorkflow }: TableOverviewSt
</button>

<Link
href="/erfassung"
href={ROUTES.erfassung}
className="inline-flex items-center justify-center px-6 py-3 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 rounded-md font-medium hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
Zurück zur Übersicht
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/app/erfassung/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { CameraIcon, DocumentChartBarIcon, ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { ROUTES } from '@/lib/routes';

export default function ErfassungPage() {
return (
Expand All @@ -22,14 +23,14 @@ export default function ErfassungPage() {
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Link
href="/erfassung/new"
href={ROUTES.erfassungNew}
className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 transition-colors"
>
<CameraIcon className="h-5 w-5 mr-2" />
Produkt scannen
</Link>
<Link
href="/erfassung/table"
href={ROUTES.erfassungTable}
className="inline-flex items-center px-6 py-3 border border-gray-300 dark:border-gray-600 text-base font-medium rounded-md text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
<DocumentChartBarIcon className="h-5 w-5 mr-2" />
Expand Down Expand Up @@ -216,7 +217,7 @@ export default function ErfassungPage() {
KI-gestützten Katalogisierung.
</p>
<Link
href="/erfassung/new"
href={ROUTES.erfassungNew}
className="inline-flex items-center px-8 py-3 border border-transparent text-lg font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 transition-colors"
>
<CameraIcon className="h-6 w-6 mr-3" />
Expand Down
Loading
Loading