Basic footer structure

This commit is contained in:
Connor Yoh 2025-08-28 16:28:54 +01:00
parent a7d5c80188
commit 5bb066dff8
3 changed files with 171 additions and 14 deletions

View File

@ -1,4 +1,5 @@
import React, { Suspense } from "react"; import React, { Suspense } from "react";
import { ScrollArea } from "@mantine/core";
import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider"; import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider";
import { FileContextProvider } from "./contexts/FileContext"; import { FileContextProvider } from "./contexts/FileContext";
import { NavigationProvider } from "./contexts/NavigationContext"; import { NavigationProvider } from "./contexts/NavigationContext";
@ -40,7 +41,9 @@ export default function App() {
<ToolWorkflowProvider> <ToolWorkflowProvider>
<SidebarProvider> <SidebarProvider>
<RightRailProvider> <RightRailProvider>
<HomePage /> <ScrollArea h="100vh" scrollbarSize={6} scrollHideDelay={1000}>
<HomePage />
</ScrollArea>
</RightRailProvider> </RightRailProvider>
</SidebarProvider> </SidebarProvider>
</ToolWorkflowProvider> </ToolWorkflowProvider>

View File

@ -0,0 +1,149 @@
import { Flex } from '@mantine/core';
import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
interface FooterProps {
privacyPolicy?: string;
termsAndConditions?: string;
accessibilityStatement?: string;
cookiePolicy?: string;
impressum?: string;
analyticsEnabled?: boolean;
}
export default function Footer({
privacyPolicy = '/privacy',
termsAndConditions = '/terms',
accessibilityStatement = 'accessibility',
cookiePolicy = 'cookie',
impressum = 'impressum',
analyticsEnabled = false
}: FooterProps) {
const { t } = useTranslation();
// Load cookie consent script when analytics is enabled
useEffect(() => {
if (analyticsEnabled) {
const script = document.createElement('script');
script.type = 'module';
script.src = '/js/thirdParty/cookieconsent-config.js';
document.head.appendChild(script);
return () => {
// Cleanup script when component unmounts
if (document.head.contains(script)) {
document.head.removeChild(script);
}
};
}
}, [analyticsEnabled]);
const handleCookiePreferences = () => {
if (typeof window !== 'undefined' && (window as any).CookieConsent) {
(window as any).CookieConsent.show(true);
}
};
return (
<div style={{
zIndex: 999999,
backgroundColor: 'var(--mantine-color-gray-1)',
borderTop: '1px solid var(--mantine-color-gray-3)',
paddingBottom: '0.5rem',
}}>
<Flex pt='sm' gap="md"
justify="center"
align="center"
direction="row"
wrap="wrap"
px="lg"
style={{ fontSize: '0.75rem' }}>
<a
className="footer-link px-3"
id="licenses"
target="_blank"
rel="noopener noreferrer"
href="/licenses"
>
{t('licenses.nav', 'Licenses')}
</a>
<a
className="footer-link px-3"
id="releases"
target="_blank"
rel="noopener noreferrer"
href="/releases"
>
{t('releases.footer', 'Releases')}
</a>
<a
className="footer-link px-3"
id="survey"
target="_blank"
rel="noopener noreferrer"
href="https://stirlingpdf.info/s/cm28y3niq000o56dv7liv8wsu"
>
{t('survey.nav', 'Survey')}
</a>
{privacyPolicy && (
<a
className="footer-link px-3"
target="_blank"
rel="noopener noreferrer"
href={privacyPolicy}
>
{t('legal.privacy', 'Privacy Policy')}
</a>
)}
{termsAndConditions && (
<a
className="footer-link px-3"
target="_blank"
rel="noopener noreferrer"
href={termsAndConditions}
>
{t('legal.terms', 'Terms and Conditions')}
</a>
)}
{accessibilityStatement && (
<a
className="footer-link px-3"
target="_blank"
rel="noopener noreferrer"
href={accessibilityStatement}
>
{t('legal.accessibility', 'Accessibility')}
</a>
)}
{cookiePolicy && (
<a
className="footer-link px-3"
target="_blank"
rel="noopener noreferrer"
href={cookiePolicy}
>
{t('legal.cookie', 'Cookie Preferecences')}
</a>
)}
{analyticsEnabled && (
<button
className="footer-link px-3"
id="cookieBanner"
onClick={handleCookiePreferences}
style={{ border: 'none', background: 'none', cursor: 'pointer' }}
>
{t('legal.showCookieBanner', 'Cookie Preferences')}
</button>
)}
</Flex>
{/* Powered by section */}
<Flex justify="center" align="center" gap={"sm"} >
<span>{t('poweredBy', 'Powered by')} </span>
<a href="https://stirlingpdf.com" className="stirling-link">
Stirling PDF
</a>
</Flex>
</div>
);
}

View File

@ -11,6 +11,7 @@ import Workbench from "../components/layout/Workbench";
import QuickAccessBar from "../components/shared/QuickAccessBar"; import QuickAccessBar from "../components/shared/QuickAccessBar";
import RightRail from "../components/shared/RightRail"; import RightRail from "../components/shared/RightRail";
import FileManager from "../components/FileManager"; import FileManager from "../components/FileManager";
import Footer from "../components/shared/Footer";
export default function HomePage() { export default function HomePage() {
@ -38,17 +39,21 @@ export default function HomePage() {
// Note: File selection limits are now handled directly by individual tools // Note: File selection limits are now handled directly by individual tools
return ( return (
<Group <div className="min-h-screen flex flex-col">
align="flex-start" <Group
gap={0} align="flex-start"
className="min-h-screen w-screen overflow-hidden flex-nowrap flex" gap={0}
> className="flex-nowrap flex"
<QuickAccessBar style={{ minHeight: '100vh' }}
ref={quickAccessRef} /> >
<ToolPanel /> <QuickAccessBar
<Workbench /> ref={quickAccessRef} />
<RightRail /> <ToolPanel />
<FileManager selectedTool={selectedTool as any /* FIX ME */} /> <Workbench />
</Group> <RightRail />
<FileManager selectedTool={selectedTool as any /* FIX ME */} />
</Group>
<Footer />
</div>
); );
} }