Frontend migration
This commit is contained in:
84
frontend/components/Home/Sections/About.tsx
Normal file
84
frontend/components/Home/Sections/About.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
'use client';
|
||||
|
||||
// import Link from 'next/link';
|
||||
// import {FiArrowRight} from 'react-icons/fi';
|
||||
import {motion} from 'framer-motion';
|
||||
import {useThemeColors} from '@/utils/useThemeColors';
|
||||
|
||||
const About = () => {
|
||||
const colors = useThemeColors();
|
||||
|
||||
return (
|
||||
<section
|
||||
className="relative w-full py-24 transition-colors duration-700 ease-in-out"
|
||||
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}
|
||||
>
|
||||
<div className="w-full max-w-6xl px-6 md:px-10 mx-auto">
|
||||
<div className="flex flex-col">
|
||||
{/* Title */}
|
||||
<motion.h2
|
||||
className="text-3xl md:text-4xl font-bold mb-1 text-left transition-colors duration-700 ease-in-out"
|
||||
>
|
||||
Über uns
|
||||
</motion.h2>
|
||||
|
||||
<motion.div
|
||||
className="w-12 h-[2px] mt-2 mb-6 bg-amber-500"
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.4, delay: 0.1}}
|
||||
/>
|
||||
|
||||
{/* Text */}
|
||||
<div className="p-0 max-w-4xl">
|
||||
<motion.p
|
||||
className="text-base md:text-lg leading-relaxed transition-colors duration-700 ease-in-out"
|
||||
style={{color: colors.secondaryText}}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2}}
|
||||
>
|
||||
Wir sind Rhein-Software – ein Team, das sich auf individuelle Softwarelösungen und digitale
|
||||
Services spezialisiert hat. Unsere Anwendungen sind technisch solide, skalierbar und
|
||||
durchdacht – gebaut für langfristigen Erfolg.
|
||||
</motion.p>
|
||||
|
||||
<motion.p
|
||||
className="mt-6 text-base md:text-lg leading-relaxed transition-colors duration-700 ease-in-out"
|
||||
style={{color: colors.secondaryText}}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3}}
|
||||
>
|
||||
Von der ersten Idee bis zum Go-Live begleiten wir Unternehmen und Startups mit einem
|
||||
flexiblen Netzwerk, klarer Kommunikation und einem hohen Anspruch an Qualität.
|
||||
Unsere Lösungen sind intuitiv, effizient – und genau auf deine Anforderungen zugeschnitten.
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
{/* CTA Button */}
|
||||
<motion.div
|
||||
className="mt-10 flex justify-end"
|
||||
initial={{opacity: 0, y: 10}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5}}
|
||||
>
|
||||
{/*<Link href="/about">*/}
|
||||
{/* <button*/}
|
||||
{/* className="flex items-center gap-2 bg-blue-700 hover:bg-blue-900 text-white font-semibold px-5 py-2 rounded-full shadow-lg transition-all"*/}
|
||||
{/* >*/}
|
||||
{/* Mehr über uns <FiArrowRight size={18}/>*/}
|
||||
{/* </button>*/}
|
||||
{/*</Link>*/}
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default About;
|
||||
62
frontend/components/Home/Sections/ContactCTA.tsx
Normal file
62
frontend/components/Home/Sections/ContactCTA.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import {motion} from 'framer-motion';
|
||||
import {FiArrowRight} from 'react-icons/fi';
|
||||
import {useThemeColors} from '@/utils/useThemeColors';
|
||||
|
||||
type ContactCTAProps = {
|
||||
title?: string;
|
||||
description?: string;
|
||||
buttonLabel?: string;
|
||||
};
|
||||
|
||||
const ContactCTA = ({
|
||||
title = "Interesse geweckt?",
|
||||
description = "Lass uns über dein Projekt sprechen. Wir freuen uns darauf, deine Ideen in die Realität umzusetzen.",
|
||||
buttonLabel = "Jetzt Kontakt aufnehmen",
|
||||
}: ContactCTAProps) => {
|
||||
const colors = useThemeColors();
|
||||
|
||||
return (
|
||||
<section
|
||||
className="relative w-full py-24 overflow-hidden transition-colors duration-700 ease-in-out"
|
||||
style={{backgroundColor: colors.primaryBg, color: colors.primaryText}}
|
||||
>
|
||||
<div className="w-full max-w-4xl px-6 md:px-10 mx-auto text-center">
|
||||
<motion.h2 className="text-3xl md:text-4xl font-bold">
|
||||
{title}
|
||||
</motion.h2>
|
||||
|
||||
<motion.p
|
||||
className="mt-4 text-sm md:text-base max-w-xl mx-auto"
|
||||
style={{color: colors.secondaryText}}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2}}
|
||||
>
|
||||
{description}
|
||||
</motion.p>
|
||||
|
||||
<motion.div
|
||||
className="mt-8 flex justify-center"
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3}}
|
||||
>
|
||||
<Link href="/contact">
|
||||
<button
|
||||
className="inline-flex items-center gap-2 px-6 py-3 text-sm md:text-base font-semibold rounded-full bg-blue-700 hover:bg-blue-900 text-white shadow-md transition-all duration-300"
|
||||
>
|
||||
{buttonLabel} <FiArrowRight size={18}/>
|
||||
</button>
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContactCTA;
|
||||
100
frontend/components/Home/Sections/Hero.tsx
Normal file
100
frontend/components/Home/Sections/Hero.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
import {Typewriter} from 'react-simple-typewriter';
|
||||
import {motion} from 'framer-motion';
|
||||
|
||||
const Hero = () => {
|
||||
return (
|
||||
<div
|
||||
className="relative w-full pt-[4vh] md:pt-[12vh] h-screen flex flex-col overflow-hidden"
|
||||
style={{
|
||||
backgroundColor: 'var(--primary-bg)',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
{/* Background Image */}
|
||||
<div className="absolute inset-0 z-0">
|
||||
<Image
|
||||
src="/images/home_hero.jpg"
|
||||
alt="Rhein river aerial view"
|
||||
layout="fill"
|
||||
objectFit="cover"
|
||||
className="blur-md scale-105"
|
||||
priority
|
||||
/>
|
||||
<div className="absolute inset-0 bg-black/40"/>
|
||||
</div>
|
||||
|
||||
{/* Main content */}
|
||||
<div className="relative z-10 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>
|
||||
<motion.h1
|
||||
className="text-3xl sm:text-4xl md:text-5xl mt-6 mb-6 font-bold text-white"
|
||||
initial={{opacity: 0, y: 30}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.6, ease: 'easeOut'}}
|
||||
>
|
||||
Rhein-Software Development
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
className="text-lg md:text-xl text-gray-400"
|
||||
initial={{opacity: 0, y: 30}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.6, delay: 0.2, ease: 'easeOut'}}
|
||||
>
|
||||
Digitale Lösungen für dein Unternehmen.
|
||||
</motion.p>
|
||||
|
||||
<motion.p
|
||||
className="mt-4 text-lg md:text-xl font-semibold text-white"
|
||||
initial={{opacity: 0}}
|
||||
animate={{opacity: 1}}
|
||||
transition={{delay: 0.9, duration: 0.6}}
|
||||
>
|
||||
<Typewriter
|
||||
words={['Beratung', 'Entwicklung', 'Wartung', 'Fehlerbehebung']}
|
||||
loop={true}
|
||||
cursor
|
||||
cursorStyle="_"
|
||||
typeSpeed={60}
|
||||
deleteSpeed={40}
|
||||
delaySpeed={1500}
|
||||
/>
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
{/* Floating Image */}
|
||||
<motion.div
|
||||
className="hidden lg:block"
|
||||
initial={{opacity: 0, y: 30}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.8, ease: 'easeOut', delay: 0.3}}
|
||||
>
|
||||
<motion.div
|
||||
animate={{y: [0, -10, 0]}}
|
||||
transition={{
|
||||
duration: 4,
|
||||
repeat: Infinity,
|
||||
ease: 'easeInOut',
|
||||
}}
|
||||
className="animate-float"
|
||||
>
|
||||
<Image
|
||||
src="/images/hero.png"
|
||||
alt="hero graphic"
|
||||
width={700}
|
||||
height={700}
|
||||
/>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
105
frontend/components/Home/Sections/HomeServices.tsx
Normal file
105
frontend/components/Home/Sections/HomeServices.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
'use client';
|
||||
|
||||
import {FiServer, FiTool, FiMonitor, FiZap, FiArrowRight} from 'react-icons/fi';
|
||||
import {motion} from 'framer-motion';
|
||||
import {useThemeColors} from '@/utils/useThemeColors';
|
||||
|
||||
const services = [
|
||||
{
|
||||
title: 'Beratung',
|
||||
icon: <FiMonitor size={24}/>,
|
||||
description:
|
||||
'Strategische und technische Beratung rund um digitale Produkte und Prozesse. Wir analysieren bestehende Systeme, identifizieren Potenziale und helfen dir, die passende Architektur für dein Projekt zu finden.',
|
||||
},
|
||||
{
|
||||
title: 'Entwicklung',
|
||||
icon: <FiZap size={24}/>,
|
||||
description:
|
||||
'Individuelle Softwareentwicklung – skalierbar, wartbar, zukunftssicher. Ob Web-App, API oder internes Tool: Wir setzen moderne Technologien ein, um genau die Lösung zu bauen, die du brauchst.',
|
||||
},
|
||||
{
|
||||
title: 'Managed Services',
|
||||
icon: <FiServer size={24}/>,
|
||||
description:
|
||||
'Wir betreuen Infrastruktur, Server und Systeme – verlässlich und performant. Unser Team kümmert sich um Hosting, Monitoring, Backups und sorgt für einen reibungslosen Betrieb deiner Plattform.',
|
||||
},
|
||||
{
|
||||
title: 'Fehlerbehebung',
|
||||
icon: <FiTool size={24}/>,
|
||||
description:
|
||||
'Schnelle Hilfe bei Bugs, Performance-Problemen oder Sicherheitslücken. Wir analysieren Probleme, beheben sie gezielt und sorgen dafür, dass dein System wieder stabil läuft – langfristig und zuverlässig.',
|
||||
},
|
||||
];
|
||||
|
||||
const HomeServices = () => {
|
||||
const colors = useThemeColors();
|
||||
|
||||
return (
|
||||
<section
|
||||
className="w-full py-24 transition-colors duration-700 ease-in-out"
|
||||
style={{backgroundColor: colors.primaryBg}}
|
||||
>
|
||||
<div className="w-full max-w-6xl px-6 md:px-10 mx-auto" style={{color: colors.primaryText}}>
|
||||
<motion.h2
|
||||
className="text-3xl md:text-4xl font-bold mb-1 text-left transition-colors duration-700 ease-in-out"
|
||||
>
|
||||
Leistungen
|
||||
</motion.h2>
|
||||
|
||||
<motion.div
|
||||
className="w-12 h-[2px] mt-2 mb-10 bg-amber-500"
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.4, delay: 0.1}}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{services.map((service, index) => (
|
||||
<motion.div
|
||||
key={service.title}
|
||||
className="p-6 rounded-xl border shadow-md transition-colors duration-700 ease-in-out"
|
||||
style={{
|
||||
backgroundColor: colors.secondaryBg,
|
||||
borderColor: colors.secondaryBg,
|
||||
color: colors.primaryText,
|
||||
}}
|
||||
whileHover={{
|
||||
scale: 1.03,
|
||||
boxShadow: '0px 10px 20px rgba(0,0,0,0.1)',
|
||||
}}
|
||||
initial={{opacity: 0, y: 30}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.4, delay: index * 0.1}}
|
||||
>
|
||||
<div className="mb-3 text-blue-600">{service.icon}</div>
|
||||
<h3 className="text-xl font-semibold mb-2">{service.title}</h3>
|
||||
<p className="text-sm leading-relaxed transition-colors duration-700 ease-in-out"
|
||||
style={{color: colors.secondaryText}}>
|
||||
{service.description}
|
||||
</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
className="mt-10 flex justify-end"
|
||||
initial={{opacity: 0}}
|
||||
whileInView={{opacity: 1}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.4, delay: 0.3}}
|
||||
>
|
||||
<a
|
||||
href="/services"
|
||||
className="text-sm font-semibold text-blue-600 hover:underline flex items-center gap-1"
|
||||
>
|
||||
Weitere Leistungen <FiArrowRight size={16}/>
|
||||
</a>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default HomeServices;
|
||||
139
frontend/components/Home/Sections/TechStack.tsx
Normal file
139
frontend/components/Home/Sections/TechStack.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
import {motion} from 'framer-motion';
|
||||
import {useThemeColors} from "@/utils/useThemeColors";
|
||||
|
||||
const techStack = {
|
||||
row1: [
|
||||
{
|
||||
category: 'Programmiersprachen & Frameworks – Backend',
|
||||
items: [
|
||||
{id: 'java', label: 'Java'},
|
||||
{id: 'dart', label: 'Dart'},
|
||||
{id: 'kotlin', label: 'Kotlin'},
|
||||
{id: 'spring', label: 'Spring'},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Programmiersprachen & Frameworks – Frontend',
|
||||
items: [
|
||||
{id: 'html', label: 'HTML'},
|
||||
{id: 'css', label: 'CSS'},
|
||||
{id: 'bootstrap', label: 'Bootstrap'},
|
||||
{id: 'nextjs', label: 'Next.js'},
|
||||
{id: 'typescript', label: 'TypeScript'},
|
||||
{id: 'flutter', label: 'Flutter'},
|
||||
],
|
||||
},
|
||||
],
|
||||
row2: [
|
||||
{
|
||||
category: 'Betriebssysteme',
|
||||
items: [
|
||||
{id: 'macos', label: 'macOS'},
|
||||
{id: 'debian', label: 'Debian'},
|
||||
{id: 'ubuntu', label: 'Ubuntu'},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'Version Control & Collaboration',
|
||||
items: [
|
||||
{id: 'gitlab', label: 'GitLab'},
|
||||
{id: 'outline', label: 'Outline'},
|
||||
],
|
||||
},
|
||||
{
|
||||
category: 'DevOps & Infrastruktur',
|
||||
items: [
|
||||
{id: 'gitlab-ci', label: 'GitLab CI'},
|
||||
{id: 'docker', label: 'Docker'},
|
||||
{id: 'proxmox', label: 'Proxmox'},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const TechStack = () => {
|
||||
const colors = useThemeColors();
|
||||
|
||||
return (
|
||||
<section
|
||||
className="w-full py-20 transition-colors duration-700 ease-in-out"
|
||||
style={{backgroundColor: colors.secondaryBg}}
|
||||
>
|
||||
<div className="w-full max-w-6xl px-6 md:px-10 mx-auto" style={{color: colors.primaryText}}>
|
||||
<motion.h2
|
||||
className="text-3xl md:text-4xl font-bold mb-1 text-left transition-colors duration-700 ease-in-out"
|
||||
>
|
||||
Technologien
|
||||
</motion.h2>
|
||||
|
||||
<motion.div
|
||||
className="w-12 h-[2px] mt-2 mb-6 bg-amber-500"
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.4, delay: 0.1}}
|
||||
/>
|
||||
|
||||
<motion.p
|
||||
className="text-sm md:text-base mb-10 transition-colors duration-700 ease-in-out"
|
||||
style={{color: colors.secondaryText}}
|
||||
>
|
||||
Mit diesen Technologien realisieren wir moderne, leistungsstarke Softwarelösungen.
|
||||
</motion.p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
|
||||
{techStack.row1.map((group, index) => (
|
||||
<TechCard key={group.category} group={group} delay={index * 0.2} colors={colors}/>
|
||||
))}
|
||||
</div>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{techStack.row2.map((group, index) => (
|
||||
<TechCard key={group.category} group={group} delay={index * 0.2 + 0.4} colors={colors}/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
const TechCard = ({
|
||||
group,
|
||||
delay,
|
||||
colors,
|
||||
}: {
|
||||
group: { category: string; items: { id: string; label: string }[] };
|
||||
delay: number;
|
||||
colors: ReturnType<typeof useThemeColors>;
|
||||
}) => (
|
||||
<motion.div
|
||||
className="p-4 rounded-lg border shadow-md transition-colors duration-700 ease-in-out"
|
||||
style={{
|
||||
backgroundColor: colors.primaryBg,
|
||||
borderColor: colors.primaryBg,
|
||||
color: colors.primaryText,
|
||||
}}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
whileHover={{scale: 1.03, boxShadow: '0 10px 20px rgba(0,0,0,0.1)'}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.4, delay}}
|
||||
>
|
||||
<h3 className="text-base font-semibold mb-4">{group.category}</h3>
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
{group.items.map(({id, label}) => (
|
||||
<div key={id} className="flex flex-col items-center text-center">
|
||||
<Image src={`/images/svg/${id}.svg`} alt={label} width={32} height={32} className="object-contain"/>
|
||||
<span className="text-[10px] mt-1 transition-colors duration-700 ease-in-out"
|
||||
style={{color: colors.secondaryText}}>
|
||||
{label}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
export default TechStack;
|
||||
Reference in New Issue
Block a user