Refactor website to use shadcn components
This commit is contained in:
117
frontend/app/legal/imprint/ImprintComp.tsx
Normal file
117
frontend/app/legal/imprint/ImprintComp.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
"use client";
|
||||
|
||||
import {motion} from "framer-motion";
|
||||
|
||||
const fadeInUp = {
|
||||
hidden: {opacity: 0, y: 30},
|
||||
visible: (i: number) => ({
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
duration: 0.6,
|
||||
delay: i * 0.2,
|
||||
ease: "easeOut",
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const ImprintComp = () => {
|
||||
const sections = [
|
||||
{
|
||||
title: "Impressum",
|
||||
content: (
|
||||
<>
|
||||
Thatsaphorn Atchariyaphap<br/>
|
||||
Rhein-Software (Einzelunternehmer)<br/>
|
||||
Mühlenstrasse 13<br/>
|
||||
79664 Wehr
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Kontakt",
|
||||
content: (
|
||||
<>
|
||||
Telefon: +49 (0) 151 24003632<br/>
|
||||
E-Mail:{" "}
|
||||
<a
|
||||
href="mailto:contact@rhein-software.dev"
|
||||
className="underline text-primary"
|
||||
>
|
||||
contact@rhein-software.dev
|
||||
</a>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "EU-Streitschlichtung",
|
||||
content: (
|
||||
<>
|
||||
Die Europäische Kommission stellt eine Plattform zur
|
||||
Online-Streitbeilegung (OS) bereit:{" "}
|
||||
<a
|
||||
href="https://ec.europa.eu/consumers/odr/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline text-primary"
|
||||
>
|
||||
https://ec.europa.eu/consumers/odr/
|
||||
</a>
|
||||
.<br/>
|
||||
Unsere E-Mail-Adresse finden Sie oben im Impressum.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Verbraucherstreitbeilegung / Universalschlichtungsstelle",
|
||||
content: (
|
||||
<>
|
||||
Wir sind nicht bereit oder verpflichtet, an
|
||||
Streitbeilegungsverfahren vor einer
|
||||
Verbraucherschlichtungsstelle teilzunehmen.
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="overflow-hidden bg-background text-foreground">
|
||||
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12 space-y-10 text-base leading-relaxed">
|
||||
{sections.map((section, i) => (
|
||||
<motion.div
|
||||
key={section.title}
|
||||
custom={i}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{once: true, amount: 0.2}}
|
||||
variants={fadeInUp}
|
||||
>
|
||||
<h2 className="text-2xl font-bold mb-4">{section.title}</h2>
|
||||
<div className="space-y-4">{section.content}</div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
<motion.p
|
||||
className="text-sm text-muted-foreground"
|
||||
custom={4}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{once: true, amount: 0.2}}
|
||||
variants={fadeInUp}
|
||||
>
|
||||
Quelle:{" "}
|
||||
<a
|
||||
href="https://www.e-recht24.de"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline"
|
||||
>
|
||||
www.e-recht24.de
|
||||
</a>
|
||||
</motion.p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImprintComp;
|
||||
@@ -1,10 +1,17 @@
|
||||
import React from 'react';
|
||||
import ImprintComp from "@/components/Legal/Imprint/ImprintComp";
|
||||
import ImprintComp from "@/app/legal/imprint/ImprintComp";
|
||||
import type {Metadata} from "next";
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
return {
|
||||
title: "Impressum | Rhein Software",
|
||||
};
|
||||
}
|
||||
|
||||
const ImprintPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<ImprintComp />
|
||||
<ImprintComp/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import type {Metadata} from "next";
|
||||
import "../globals.css";
|
||||
|
||||
import Nav from "@/components/Navbar/Nav";
|
||||
import Footer from "@/components/Footer/Footer";
|
||||
import {ThemeProvider} from "@/components/provider/ThemeProvider";
|
||||
import React from "react";
|
||||
import {cookies} from "next/headers";
|
||||
import {themeColors} from "@/components/Helper/ThemeColors";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Rechtliches | Rhein Software",
|
||||
description: "Rhein Software Development",
|
||||
};
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const cookieStore = await cookies();
|
||||
const theme = cookieStore.get("theme")?.value === "dark" ? "dark" : "light";
|
||||
const bgColor = themeColors[theme].primaryBg;
|
||||
|
||||
return (
|
||||
<html lang="de" data-theme={theme}>
|
||||
<head/>
|
||||
<body className="antialiased" style={{backgroundColor: bgColor}}>
|
||||
<ThemeProvider>
|
||||
<Nav/>
|
||||
{children}
|
||||
<Footer/>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,60 @@
|
||||
import React from 'react';
|
||||
'use client'
|
||||
|
||||
const LegalPage = () => {
|
||||
import Link from 'next/link'
|
||||
import {motion} from 'framer-motion'
|
||||
import SmallHero from '@/components/Helper/SmallHero'
|
||||
import {Card, CardContent} from '@/components/ui/card'
|
||||
|
||||
const legalLinks = [
|
||||
{
|
||||
label: 'Impressum',
|
||||
href: '/legal/imprint',
|
||||
},
|
||||
{
|
||||
label: 'Datenschutz',
|
||||
href: '/legal/privacy',
|
||||
},
|
||||
{
|
||||
label: 'Widerrufsrecht',
|
||||
href: '/legal/revocation',
|
||||
},
|
||||
{
|
||||
label: 'Nutzungsbedingungen',
|
||||
href: '/legal/terms-of-use',
|
||||
},
|
||||
]
|
||||
|
||||
export default function LegalOverviewPage() {
|
||||
return (
|
||||
<div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
<>
|
||||
<SmallHero
|
||||
title="Rechtliches"
|
||||
subtitle="Alle rechtlich relevanten Informationen auf einen Blick."
|
||||
backgroundImage="/images/contact.png"
|
||||
blurBackground
|
||||
/>
|
||||
|
||||
export default LegalPage;
|
||||
<section className="px-6 sm:px-12 py-16 max-w-6xl mx-auto">
|
||||
<motion.div
|
||||
className="grid grid-cols-1 sm:grid-cols-2 gap-6"
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.5, delay: 0.3}}
|
||||
>
|
||||
{legalLinks.map(({label, href}) => (
|
||||
<Card key={href} className="hover:shadow-md transition-shadow">
|
||||
<CardContent className="p-6">
|
||||
<Link
|
||||
href={href}
|
||||
className="text-primary font-medium text-lg hover:underline"
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</motion.div>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
124
frontend/app/legal/privacy/PrivacyComp.tsx
Normal file
124
frontend/app/legal/privacy/PrivacyComp.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
"use client";
|
||||
|
||||
import {motion} from "framer-motion";
|
||||
|
||||
const fadeInUp = {
|
||||
hidden: {opacity: 0, y: 30},
|
||||
visible: (i: number) => ({
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
duration: 0.6,
|
||||
delay: i * 0.2,
|
||||
ease: "easeOut",
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const PrivacyComp = () => {
|
||||
const sections = [
|
||||
{
|
||||
title: "1. Datenschutz auf einen Blick",
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen
|
||||
Daten passiert, wenn Sie diese Website besuchen. Personenbezogene Daten sind alle Daten, mit
|
||||
denen Sie persönlich identifiziert werden können.
|
||||
</p>
|
||||
<p>
|
||||
Die Datenverarbeitung auf dieser Website erfolgt durch den Websitebetreiber. Dessen Kontaktdaten
|
||||
finden Sie im Abschnitt „Hinweis zur Verantwortlichen Stelle“.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "2. Allgemeine Hinweise und Pflichtinformationen",
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Wir behandeln Ihre personenbezogenen Daten vertraulich und entsprechend den gesetzlichen
|
||||
Datenschutzvorschriften sowie dieser Datenschutzerklärung. Wir weisen darauf hin, dass die
|
||||
Datenübertragung im Internet Sicherheitslücken aufweisen kann.
|
||||
</p>
|
||||
<p>
|
||||
Verantwortlich für die Datenverarbeitung:
|
||||
<br/>
|
||||
Rhein-Software Development
|
||||
<br/>
|
||||
Mühlenstrasse 13
|
||||
<br/>
|
||||
79664 Wehr
|
||||
<br/>
|
||||
<br/>
|
||||
Telefon: +49 (0) 151 24003632
|
||||
<br/>
|
||||
E-Mail: <a href="mailto:contact@rhein-software.dev"
|
||||
className="underline text-primary">contact@rhein-software.dev</a>
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "3. Ihre Rechte",
|
||||
content: (
|
||||
<p>
|
||||
Sie haben das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung,
|
||||
Datenübertragbarkeit sowie auf Widerspruch gegen die Verarbeitung Ihrer Daten. Zudem haben Sie
|
||||
ein Beschwerderecht bei der zuständigen Aufsichtsbehörde.
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "4. Analyse-Tools und Cookies",
|
||||
content: (
|
||||
<p>
|
||||
Beim Besuch dieser Website kann Ihr Surfverhalten statistisch ausgewertet werden. Das geschieht
|
||||
vor allem mit sogenannten Analyseprogrammen und Cookies. Detaillierte Informationen hierzu
|
||||
entnehmen Sie bitte unserer vollständigen Datenschutzerklärung.
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "5. Sicherheit",
|
||||
content: (
|
||||
<p>
|
||||
Diese Seite nutzt eine SSL- bzw. TLS-Verschlüsselung. Eine verschlüsselte Verbindung erkennen
|
||||
Sie an der Adresszeile des Browsers („https://“) und dem Schloss-Symbol.
|
||||
</p>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Quelle",
|
||||
content: (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Quelle: <a href="https://www.e-recht24.de" target="_blank" rel="noopener noreferrer"
|
||||
className="underline">www.e-recht24.de</a>
|
||||
</p>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="overflow-hidden bg-background text-foreground">
|
||||
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12 space-y-10 text-base leading-relaxed">
|
||||
{sections.map((section, i) => (
|
||||
<motion.div
|
||||
key={section.title}
|
||||
custom={i}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{once: true, amount: 0.2}}
|
||||
variants={fadeInUp}
|
||||
>
|
||||
<h2 className="text-2xl font-bold mb-4">{section.title}</h2>
|
||||
<div className="space-y-4">{section.content}</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PrivacyComp;
|
||||
@@ -1,5 +1,12 @@
|
||||
import React from 'react';
|
||||
import PrivacyComp from "@/components/Legal/Privacy/PrivacyComp";
|
||||
import PrivacyComp from "@/app/legal/privacy/PrivacyComp";
|
||||
import type {Metadata} from "next";
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
return {
|
||||
title: "Datenschutz | Rhein Software",
|
||||
};
|
||||
}
|
||||
|
||||
const PrivacyPage = () => {
|
||||
return (
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react';
|
||||
import RevocationComp from "@/components/Legal/RevocationComp";
|
||||
|
||||
const RevocationPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<RevocationComp />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RevocationPage;
|
||||
98
frontend/app/legal/terms-of-use/TermsOfUseComp.tsx
Normal file
98
frontend/app/legal/terms-of-use/TermsOfUseComp.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
'use client';
|
||||
|
||||
import SmallHero from '@/components/Helper/SmallHero';
|
||||
import React from 'react';
|
||||
import {motion} from 'framer-motion';
|
||||
|
||||
const TermsOfUseComp = () => {
|
||||
return (
|
||||
<div className="overflow-hidden bg-background text-foreground">
|
||||
{/* Hero Section */}
|
||||
<div className="mt-[10vh]">
|
||||
<SmallHero
|
||||
title="AGB"
|
||||
subtitle=""
|
||||
backgroundImage="/images/contact.png"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Contact Form */}
|
||||
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
|
||||
<motion.h2
|
||||
className="text-2xl md:text-3xl font-bold text-center"
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.6}}
|
||||
>
|
||||
Schreib uns eine Nachricht
|
||||
</motion.h2>
|
||||
|
||||
<motion.p
|
||||
className="text-center mt-3 text-muted-foreground"
|
||||
initial={{opacity: 0, y: 10}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2}}
|
||||
>
|
||||
Wir melden uns schnellstmöglich bei dir!
|
||||
</motion.p>
|
||||
|
||||
<form className="mt-8 max-w-2xl mx-auto space-y-6">
|
||||
{/* Name & Email */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{["Dein Name", "Deine E-Mail"].map((label, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{opacity: 0, y: 10}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.2}}
|
||||
>
|
||||
<label className="block font-semibold">{label}</label>
|
||||
<input
|
||||
type={index === 0 ? "text" : "email"}
|
||||
placeholder={index === 0 ? "Max Mustermann" : "max@example.com"}
|
||||
className="w-full p-3 rounded-lg border border-border bg-card text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
|
||||
/>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Message */}
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 10}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5}}
|
||||
>
|
||||
<label className="block font-semibold">Deine Nachricht</label>
|
||||
<textarea
|
||||
rows={4}
|
||||
placeholder="Schreibe deine Nachricht..."
|
||||
className="w-full p-3 rounded-lg border border-border bg-card text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
{/* Submit Button */}
|
||||
<motion.div
|
||||
className="text-center"
|
||||
initial={{opacity: 0, y: 10}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.7}}
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-6 py-3 bg-blue-600 text-white text-lg font-semibold rounded-lg shadow-md hover:bg-blue-700 transition-all"
|
||||
>
|
||||
📩 Nachricht senden
|
||||
</button>
|
||||
</motion.div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TermsOfUseComp;
|
||||
@@ -1,5 +1,12 @@
|
||||
import React from 'react';
|
||||
import TermsOfUseComp from "@/components/Legal/TermsOfUseComp";
|
||||
import TermsOfUseComp from "@/app/legal/terms-of-use/TermsOfUseComp";
|
||||
import type {Metadata} from "next";
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
return {
|
||||
title: "Nutzungsbedingungen | Rhein Software",
|
||||
};
|
||||
}
|
||||
|
||||
const TermsOfUsePage = () => {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user