Migrate from old project

This commit is contained in:
2025-04-02 18:25:10 +02:00
parent ce90c48825
commit 4566f2559f
55 changed files with 2774 additions and 233 deletions

View File

@@ -0,0 +1,100 @@
"use client";
import React, {useEffect, useContext} from "react";
import AOS from "aos";
import "aos/dist/aos.css";
import SmallHero from "@/components/Helper/SmallHero";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
const Contact = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Kontakt"
subtitle="Hast du Fragen? Wir sind für dich da!"
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</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) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<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 focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<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>
</div>
</form>
</div>
</div>
);
};
export default Contact;

View File

@@ -0,0 +1,24 @@
export const SectionDivider1 = () => {
return (
<div
className="w-full h-20 transition-all duration-500 ease-in-out"
style={{
background: `linear-gradient(to bottom, var(--primary-bg), var(--secondary-bg))`
}}
/>
);
};
export const SectionDivider2 = () => {
return (
<div
className="w-full h-20 transition-all duration-500 ease-in-out"
style={{
background: `linear-gradient(to bottom, var(--secondary-bg), var(--primary-bg))`
}}
/>
);
};

View File

@@ -0,0 +1,40 @@
import React from "react";
type SmallHeroProps = {
title: string;
subtitle?: string;
backgroundImage?: string; // Optional background image
};
const SmallHero = ({title, subtitle, backgroundImage}: SmallHeroProps) => {
return (
<div
className="w-full py-20 text-center flex flex-col items-center justify-center bg-cover bg-center"
style={{
backgroundColor: backgroundImage ? "transparent" : "var(--primary-bg)", // Fallback if no image
color: "var(--primary-text)",
backgroundImage: backgroundImage ? `url(${backgroundImage})` : "none",
backgroundSize: "cover",
backgroundPosition: "center",
backgroundBlendMode: "overlay",
transition: "background-color 0.4s ease-in-out, color 0.4s ease-in-out",
}}
>
<h1 className="text-3xl sm:text-4xl font-bold"
data-aos="fade-up"
>
{title}
</h1>
{subtitle &&
<p className="mt-2 text-lg text-[var(--secondary-text)]"
data-aos="fade-up"
data-aos-delay="200"
>
{subtitle}
</p>
}
</div>
);
};
export default SmallHero;

View File

@@ -0,0 +1,18 @@
"use server";
import {cookies} from "next/headers";
// ✅ Get theme from cookies OR detect system preference
export async function getInitialTheme(): Promise<"dark" | "light"> {
const themeCookie = (await cookies()).get("theme")?.value;
if (themeCookie === "dark" || themeCookie === "light") {
return themeCookie;
}
// Detect system preference
const prefersDarkMode =
typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
return prefersDarkMode ? "dark" : "light";
}

View File

@@ -0,0 +1,28 @@
export const themeColors: Record<
"light" | "dark",
{
primaryBg: string;
secondaryBg: string;
primaryText: string;
secondaryText: string;
inputFieldBg: string;
inputBorder: string;
}
> = {
dark: {
primaryBg: "#121212", // Dark gray/black background (closer to true dark mode)
secondaryBg: "#1e1e1e", // Slightly lighter gray for contrast
primaryText: "#e0e0e0", // Light gray for good readability
secondaryText: "#b0b0b0", // Muted gray for subtle contrast
inputFieldBg: "#252525", // Dark but slightly distinguishable from primaryBg
inputBorder: "#3a3a3a", // Slightly lighter gray for a soft contrast
},
light: {
primaryBg: "#f7f6fb",
secondaryBg: "#ffffff",
primaryText: "#1a1a2e",
secondaryText: "#4a4a4a", // Muted text color
inputFieldBg: "#ffffff", // White input field (same as secondaryBg)
inputBorder: "#dcdcdc", // Light gray border for subtle visibility
},
};

View File

@@ -0,0 +1,58 @@
import Image from "next/image";
import React from "react";
const About = () => {
return (
<div
className="pt-24 pb-16 transition-theme"
style={{
backgroundColor: "var(--secondary-bg)", // Using CSS variable
color: "var(--primary-text)", // Ensuring text color follows theme
transition: "background-color 0.5s ease, color 0.5s ease", // Smooth transition
}}>
<h1
className="mt-6 text-2xl md:text-3xl capitalize font-bold text-center"
data-aos="fade-up"
style={{color: "var(--primary-text)"}}>
Über Uns
</h1>
<div className="w-[95%] sm:w-[80%] mx-auto items-center grid grid-cols-1 lg:grid-cols-2 gap-6 mt-10">
<div className="flex flex-col items-center" data-aos="fade-up" data-aos-anchor-placement="top-center">
<Image
src="/images/About_Picture.png"
alt="image"
width={400}
height={400}
className="object-contain"
/>
</div>
<div className="p-0">
<p
className="mt-4 text-sm font-medium leading-[2rem]"
data-aos="fade-up"
data-aos-delay="200"
style={{color: "var(--secondary-text)"}}
>
Wir sind Rhein Software Development ein Team, das sich auf maßgeschneiderte Softwarelösungen
und zuverlässige digitale Services spezialisiert hat. Unser Fokus liegt darauf, Software zu
entwickeln, die nicht nur funktioniert, sondern langfristig überzeugt.
</p>
<p
className="mt-4 text-sm font-medium leading-[2rem]"
data-aos="fade-up"
data-aos-delay="200"
style={{color: "var(--secondary-text)"}}
>
Von der ersten Idee bis zur fertigen Anwendung begleiten wir Unternehmen, Startups und
individuelle Projekte mit einer klaren Strategie und einem hohen Anspruch an Qualität. Wir
glauben daran, dass gute Software nicht kompliziert sein muss sondern effizient, intuitiv und
zukunftssicher.
</p>
</div>
</div>
</div>
);
};
export default About;

View File

@@ -0,0 +1,47 @@
import Link from "next/link";
import {useContext} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
const ContactCTA = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
return (
<div className="text-center py-16 transition-theme"
style={{backgroundColor: "var(--secondary-bg)"}}
>
<h2 className="text-2xl md:text-3xl font-bold transition-theme"
data-aos="fade-up"
style={{color: "var(--primary-text)"}}
>
Interesse geweckt?
</h2>
<p className="mt-4 text-sm md:text-base transition-theme"
data-aos="fade-up"
data-aos-delay="200"
style={{color: "var(--secondary-text)"}}
>
Lass uns über dein Projekt sprechen. Wir freuen uns darauf,
deine Ideen in die Realität umzusetzen.
</p>
<Link href="/contact"
data-aos="fade-up"
data-aos-delay="200"
>
<button className="mt-6 px-6 py-3 text-lg font-semibold rounded-lg shadow-md transition-theme"
data-aos="fade-up"
data-aos-delay="400"
style={{
backgroundColor: colors.primaryBg,
color: colors.secondaryText,
}}
>
📩 Jetzt Kontakt aufnehmen
</button>
</Link>
</div>
);
};
export default ContactCTA;

View File

@@ -0,0 +1,96 @@
import React from "react";
import Link from "next/link";
const Footer = () => {
return (
<div className="py-10 transition-theme" style={{backgroundColor: "var(--footer-bg)"}}>
<div className="w-[90%] mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-8">
{/* Logo and description */}
<div>
{/* Logo */}
<h1 className="text-xl md:text-2xl font-bold transition-theme"
data-aos="fade-up"
style={{color: "var(--primary-text)"}}
>
<span className="text-3xl md:text-4xl text-pink-700">R</span>hein Software
</h1>
</div>
{/* Our information links */}
<div>
<h3 className="text-lg font-semibold transition-theme"
data-aos="fade-up"
style={{color: "var(--primary-text)"}}
>
Informationen
</h3>
<ul className="mt-4 space-y-4 text-sm font-semibold transition-theme"
data-aos="fade-up"
data-aos-delay="200"
style={{color: "var(--secondary-text)"}}>
<li>
<Link href="/contact" key="imprint">
<p className={`nav_link transition-all duration-300 ease-in-out`}>Kontakt</p>
</Link>
</li>
<li>
<Link href="/contact" key="imprint">
<p className={`nav_link transition-all duration-300 ease-in-out`}>Zahlung und
Versand</p>
</Link>
</li>
</ul>
</div>
{/* About us links */}
<div>
<h3 className="text-lg font-semibold transition-theme"
data-aos="fade-up"
style={{color: "var(--primary-text)"}}
>
Rechtliches
</h3>
<ul className="mt-4 space-y-4 text-sm font-semibold transition-theme"
data-aos="fade-up"
data-aos-delay="300"
style={{color: "var(--secondary-text)"}}
>
<li>
<Link href="/legal/terms-of-use" key="imprint">
<p className={`nav_link transition-all duration-300 ease-in-out`}>AGB</p>
</Link>
</li>
<li>
<Link href="/legal/revocation" key="imprint">
<p className={`nav_link transition-all duration-300 ease-in-out`}>Widerruf</p>
</Link>
</li>
<li>
<Link href="/legal/privacy" key="imprint">
<p className={`nav_link transition-all duration-300 ease-in-out`}>Datenschutz</p>
</Link>
</li>
<li>
<Link href="/legal/imprint" key="imprint">
<p className={`nav_link transition-all duration-300 ease-in-out`}>Impressum</p>
</Link>
</li>
</ul>
</div>
</div>
{/* Bottom Section */}
<div
className="mt-8 border-t pt-8 flex flex-col md:flex-row justify-between items-center text-sm transition-theme"
data-aos="fade-up"
style={{color: "var(--secondary-text)", borderColor: "var(--primary-text)"}}
>
<p className="text-center md:text-left">
Copyright © 2025 Rhein Software Development. All rights reserved
</p>
</div>
</div>
</div>
);
};
export default Footer;

View File

@@ -0,0 +1,45 @@
import Image from "next/image";
const Hero = () => {
return (
<div
className="relative w-full pt-[4vh] md:pt-[12vh] h-screen flex flex-col"
style={{
backgroundColor: "var(--primary-bg)",
color: "var(--primary-text)",
}}
>
<div className="flex justify-center flex-col w-[90%] sm:w-[80%] h-full mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-2 items-center gap-12">
{/* Text Content */}
<div>
<h1
data-aos="fade-up"
className="text-2xl sm:text-4xl md:text-5xl mt-6 mb-6 font-bold md:leading-[3rem] lg:leading-[3.5rem]"
>
Rhein Software Development
</h1>
<p data-aos="fade-up" data-aos-delay="200">
Wir entwickeln performante und zukunftssichere Software für deine Vision.
</p>
</div>
{/* Image Content */}
<div
data-aos="fade-up"
data-aos-delay="400"
className="hidden lg:block"
>
<Image src="/images/hero.png" alt="hero" width={700} height={700}/>
</div>
</div>
</div>
{/* Farbverlauf zum nächsten Bereich */}
{/*<div*/}
{/* className="absolute bottom-0 left-0 w-full h-20 bg-gradient-to-b from-[var(--primary-bg)] to-[var(--secondary-bg)]"*/}
{/*/>*/}
</div>
);
};
export default Hero;

40
components/Home/Home.tsx Normal file
View File

@@ -0,0 +1,40 @@
"use client";
import React, {useEffect} from "react";
import Hero from "./Hero/Hero";
import AOS from "aos";
import "aos/dist/aos.css";
import About from "@/components/Home/About/About";
import Offer from "@/components/Home/Offer/Offer";
import ContactCTA from "@/components/Home/Contact/ContactCTA";
import {SectionDivider1, SectionDivider2} from "@/components/Helper/SectionDivider";
const Home = () => {
useEffect(() => {
const initAOS = async () => {
await import("aos");
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
};
initAOS();
}, []);
return (
<div className="overflow-hidden">
<Hero/>
<SectionDivider1/>
<About/>
<SectionDivider2/>
<Offer/>
<SectionDivider1/>
<ContactCTA/>
<SectionDivider2/>
</div>
);
};
export default Home;

View File

@@ -0,0 +1,96 @@
"use client";
import {navLinks} from "@/constant/Constant";
import Link from "next/link";
import React, {useContext, useEffect, useState} from "react";
import {HiBars3BottomRight} from "react-icons/hi2";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
type Props = {
openNav: () => void;
};
const Nav = ({openNav}: Props) => {
const [navBg, setNavBg] = useState(false);
const [navHeight, setNavHeight] = useState("h-[10vh]");
const [contentSize, setContentSize] = useState("text-base md:text-lg");
const [buttonSize, setButtonSize] = useState("md:px-6 md:py-2 px-4 py-1 text-sm");
const {theme, toggleTheme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
const handler = () => {
if (window.scrollY >= 90) {
setNavBg(true);
setNavHeight("h-[8vh]");
setContentSize("text-sm md:text-base");
setButtonSize("md:px-5 md:py-1.5 px-3 py-1 text-xs");
} else {
setNavBg(false);
setNavHeight("h-[10vh]");
setContentSize("text-base md:text-lg");
setButtonSize("md:px-6 md:py-2 px-4 py-1 text-sm");
}
};
window.addEventListener("scroll", handler);
return () => window.removeEventListener("scroll", handler);
}, []);
return (
<div
className={`fixed ${navBg ? "shadow-md" : "fixed"} w-full transition-all duration-300 ease-in-out ${navHeight} z-[1000]`}
style={{
backgroundColor: navBg ? "var(--nav-bg)" : "var(--primary-bg)",
color: "var(--primary-text)",
}}
>
<div
className="flex items-center h-full justify-between w-[90%] xl:w-[80%] mx-auto transition-all duration-300 ease-in-out">
{/* LOGO */}
<h1 className={`${contentSize} font-bold transition-all duration-300 ease-in-out`}
style={{color: colors.primaryText}}>
<span className="text-lg md:text-xl text-pink-700">R</span>hein Software
</h1>
{/* Desktop Nav Links */}
<div className="hidden lg:flex items-center space-x-6 transition-all duration-300 ease-in-out">
{navLinks.map((link) => (
<Link href={link.url} key={link.id}>
<p className={`nav_link ${contentSize} transition-all duration-300 ease-in-out`}
style={{color: colors.primaryText}}>{link.label}</p>
</Link>
))}
</div>
{/* Right Side Buttons */}
<div className="flex items-center space-x-3 transition-all duration-300 ease-in-out">
{/* Portal Button */}
<button
className={`${buttonSize} text-white font-semibold bg-blue-700 hover:bg-blue-900 transition-all duration-300 ease-in-out rounded-full`}
>
Portal
</button>
{/* Theme Toggle Button */}
<button
onClick={toggleTheme}
className="w-7 h-7 flex items-center justify-center rounded-full transition-all duration-300 ease-in-out"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}
>
{theme === "dark" ? "🌙" : "☀️"}
</button>
{/* Burger Menu (for mobile) */}
<HiBars3BottomRight
onClick={openNav}
className="w-6 h-6 cursor-pointer text-black lg:hidden transition-all duration-300 ease-in-out"
/>
</div>
</div>
</div>
);
};
export default Nav;

View File

@@ -0,0 +1,43 @@
import {navLinks} from "@/constant/Constant";
import Link from "next/link";
import React from "react";
import {CgClose} from "react-icons/cg";
type Props = {
showNav: boolean;
closeNav: () => void;
};
const MobileNav = ({closeNav, showNav}: Props) => {
const navOpen = showNav ? "translate-x-0" : "translate-x-[-100%]";
return (
<div>
{/* overlay */}
<div
className={`fixed ${navOpen} inset-0 transform transition-all duration-500 z-[10000] bg-black opacity-70 w-full h-screen`}
></div>
{/* Navlinks */}
<div
className={`text-white ${navOpen} fixed justify-center flex flex-col h-full transform transition-all duration-500 delay-300 w-[80%] sm:w-[60%] bg-indigo-900 space-y-6 z-[10006]`}
>
{navLinks.map((link) => {
return (
<Link href={link.url} key={link.id}>
<p className="nav__link text-white text-[20px] ml-12 border-b-[1.5px] pb-1 border-white sm:text-[30px]">
{link.label}
</p>
</Link>
);
})}
{/* Close icon */}
<CgClose
onClick={closeNav}
className="absolute top-[0.7rem] right-[1.4rem] sm:w-8 sm:h-8 w-6 h-6"
/>
</div>
</div>
);
};
export default MobileNav;

View File

@@ -0,0 +1,24 @@
"use client";
import React, {useState} from "react";
import DesktopNav from "./DesktopNav";
import MobileNav from "./MobileNav";
const Nav = () => {
const [showNav, setShowNav] = useState(false);
const handleNavShow = () => {
setShowNav(true);
};
const handleNavHide = () => {
setShowNav(false);
};
return (
<div>
<DesktopNav openNav={handleNavShow}/>
<MobileNav showNav={showNav} closeNav={handleNavHide}/>
</div>
);
};
export default Nav;

View File

@@ -0,0 +1,75 @@
import React from "react";
import Image from "next/image";
const FullStack = () => {
return (
<div
className="w-[95%] sm:w-[80%] mx-auto items-center grid grid-cols-1 lg:grid-cols-2 gap-6 mt-8 mb-16 transition-theme">
<div className="p-0"
>
<h1 data-aos="fade-up"
className="mt-4 text-xl sm:text-2xl md:text-3xl font-bold"
style={{color: "var(--primary-text)"}} // Dynamic text color
>
💻 Full-Stack Entwicklung
</h1>
<div data-aos="fade-up"
data-aos-delay="200"
>
<p
className="mt-4 text-sm font-medium leading-[2rem]"
style={{color: "var(--secondary-text)"}} // Secondary text color
>
Wir entwickeln skalierbare Backends, performante Frontends und native Apps genau auf deine
Anforderungen zugeschnitten. Dabei setzen wir auf neueste und modernste Technologien, um
flexible
und zukunftssichere Lösungen zu schaffen.
</p>
{/* Technology Logos Section */}
<h2
className="mt-8 text-lg font-semibold"
style={{color: "var(--primary-text)"}}
>
🔧 Tech Stack
</h2>
<span
className="mt-4 text-sm font-medium leading-[2rem]"
style={{color: "var(--secondary-text)"}}
>
Programmiersprachen und Frameworks, die wir für unsere Lösungen einsetzen.
</span>
<div className="mt-6 flex flex-wrap items-center gap-8">
{/* Tech Stack Logos */}
{[
{src: "/images/flutter_logo.png", label: "Flutter", width: 30, height: 30},
{src: "/images/dart_logo.png", label: "Dart", width: 40, height: 40},
{src: "/images/java_logo.png", label: "Java", width: 40, height: 40},
{src: "/images/nextjs_logo.png", label: "NextJS", width: 40, height: 40},
].map(({src, label, width, height}) => (
<div key={label} className="flex flex-col items-center">
<Image src={src} alt={label} width={width} height={height} className="object-contain"/>
<span
className="text-xs mt-2"
style={{color: "var(--secondary-text)"}} // Match theme
>
{label}
</span>
</div>
))}
</div>
</div>
</div>
<div data-aos="fade-up" data-aos-anchor-placement="top-center" className="justify-self-center">
<Image
src="/images/software_dev.jpg"
alt="image"
width={200}
height={200}
className="object-contain"
/>
</div>
</div>
);
};
export default FullStack;

View File

@@ -0,0 +1,57 @@
import React from "react";
import Image from "next/image";
import {TiChevronRightOutline} from "react-icons/ti";
const ManagedServices = () => {
return (
<div
className="w-[95%] sm:w-[80%] mx-auto items-center grid grid-cols-1 lg:grid-cols-2 gap-6 mt-8 mb-16"
data-aos="fade-up"
data-aos-delay="200"
>
{/* Image Section */}
<div
data-aos="fade-up"
data-aos-anchor-placement="top-center"
className="justify-self-center"
>
<Image
src="/images/software_dev.jpg"
alt="image"
width={200}
height={200}
className="object-contain"
/>
</div>
{/* Text Content */}
<div className="p-0">
<h1
className="mt-4 text-xl sm:text-2xl md:text-3xl font-bold transition-theme"
style={{color: "var(--primary-text)"}}>
Managed Services
</h1>
<p
className="mt-4 text-sm font-medium leading-[2rem] transition-theme"
style={{color: "var(--secondary-text)"}}>
Wir übernehmen das Hosting und Management deiner Server, damit du dich auf dein
Business konzentrieren kannst. Egal ob Cloud-Hosting, dedizierte Server oder hybride Lösungen wir
sorgen für eine sichere, performante und skalierbare Infrastruktur.
</p>
<ul className="mt-7 space-y-2">
{[
"Web- & Cloud-Hosting",
"Mailserver-Management",
"Webserver-Administration",
].map((item, index) => (
<li key={index} className="flex items-center font-semibold transition-theme">
<TiChevronRightOutline className="text-blue-500 mr-2"/>
<span style={{color: "var(--primary-text)"}}>{item}</span>
</li>
))}
</ul>
</div>
</div>
);
};
export default ManagedServices;

View File

@@ -0,0 +1,28 @@
import React from "react";
import FullStack from "@/components/Home/Offer/FullStack";
import ManagedServices from "@/components/Home/Offer/ManagedServices";
const Offer = () => {
return (
<div
className="transition-theme"
style={{
backgroundColor: "var(--primary-bg)", // Using CSS variable
color: "var(--primary-text)", // Ensuring text color follows theme
transition: "background-color 0.5s ease, color 0.5s ease", // Smooth transition
}}>
<div className="pt-24 pb-16">
<h1 className="mt-6 text-2xl md:text-3xl capitalize font-bold text-center"
data-aos="fade-up"
style={{color: "var(--primary-text)"}}
>
Was bieten wir?
</h1>
<FullStack/>
<ManagedServices/>
</div>
</div>
);
};
export default Offer;

View File

@@ -0,0 +1,99 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const ImprintComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Impressum"
subtitle=""
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</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) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<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 focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<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>
</div>
</form>
</div>
</div>
);
};
export default ImprintComp;

View File

@@ -0,0 +1,99 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const PrivacyComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Datenschutz"
subtitle=""
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</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) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<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 focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<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>
</div>
</form>
</div>
</div>
);
};
export default PrivacyComp;

View File

@@ -0,0 +1,98 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const RevocationComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Widerruf"
subtitle=""
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</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) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<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 focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<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>
</div>
</form>
</div>
</div>
);};
export default RevocationComp;

View File

@@ -0,0 +1,99 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const TermsOfUseComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* 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">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</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) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<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 focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<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>
</div>
</form>
</div>
</div>
);
};
export default TermsOfUseComp;

View File

@@ -0,0 +1,54 @@
"use client";
import { createContext, useEffect, useState } from "react";
import Cookies from "js-cookie";
// Define theme options
type ThemeType = "light" | "dark";
export const ThemeContext = createContext<{
theme: ThemeType;
toggleTheme: () => void;
}>({
theme: "light",
toggleTheme: () => {},
});
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
const [theme, setTheme] = useState<ThemeType>("light");
useEffect(() => {
// Get theme from cookies or system preference
const savedTheme = Cookies.get("theme") as ThemeType | undefined;
if (savedTheme === "dark" || savedTheme === "light") {
setTheme(savedTheme);
} else {
// Detect system preference
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
setTheme(prefersDark ? "dark" : "light");
Cookies.set("theme", prefersDark ? "dark" : "light", { expires: 365 });
}
}, []);
// Apply the transition effect when theme changes
useEffect(() => {
document.documentElement.classList.add("transition-theme");
document.documentElement.setAttribute("data-theme", theme);
return () => {
document.documentElement.classList.remove("transition-theme");
};
}, [theme]);
const toggleTheme = () => {
const newTheme: ThemeType = theme === "dark" ? "light" : "dark";
setTheme(newTheme);
Cookies.set("theme", newTheme, { expires: 365 });
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};