feat: Scaffold new Next.js website with core pages, components, and assets.

This commit is contained in:
1elle1
2026-02-06 11:19:57 +01:00
parent d63eb85218
commit db27ebf76f
53 changed files with 7756 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
import { company } from "@/lib/site-content";
export function ContactStrip() {
return (
<section id="kontakt" className="section-block pb-10">
<div className="container-shell">
<div className="rounded-3xl border border-copper-200 bg-copper-50 p-7 shadow-card sm:p-10">
<div className="grid gap-6 md:grid-cols-[1.2fr_1fr] md:items-center">
<div>
<p className="eyebrow text-copper-700">Direkter Kontakt</p>
<h2 className="mt-3 text-3xl font-semibold text-alpine-900">Ein Anruf klaert oft mehr als zehn Mails.</h2>
<p className="mt-4 max-w-2xl text-alpine-700">
Wenn Sie einen Tarif wechseln, einen Standort anbinden oder eine Stoerung melden wollen: Sie landen
nicht in einem anonymen Ticketsystem, sondern bei einem Team aus der Region.
</p>
</div>
<div className="rounded-2xl border border-copper-200 bg-white p-6">
<ul className="space-y-3 text-sm text-alpine-800">
<li>
<span className="font-semibold">Telefon:</span>{" "}
<a className="text-alpine-700 underline decoration-copper-400 underline-offset-4" href={`tel:${company.phone.replace(/\s+/g, "")}`}>
{company.phone}
</a>
</li>
<li>
<span className="font-semibold">Beratung:</span>{" "}
<a className="text-alpine-700 underline decoration-copper-400 underline-offset-4" href={`mailto:${company.email}`}>
{company.email}
</a>
</li>
<li>
<span className="font-semibold">Stoerung:</span>{" "}
<a className="text-alpine-700 underline decoration-copper-400 underline-offset-4" href={`mailto:${company.supportEmail}`}>
{company.supportEmail}
</a>
</li>
<li>
<span className="font-semibold">Erreichbarkeit:</span> {company.openingHours}
</li>
</ul>
</div>
</div>
</div>
</div>
</section>
);
}
+64
View File
@@ -0,0 +1,64 @@
import Link from "next/link";
import Image from "next/image";
type PageHeroProps = {
eyebrow: string;
title: string;
intro: string;
imageSrc: string;
imageAlt: string;
primaryCta?: { label: string; href: string };
secondaryCta?: { label: string; href: string };
};
export function PageHero({
eyebrow,
title,
intro,
imageSrc,
imageAlt,
primaryCta,
secondaryCta
}: PageHeroProps) {
return (
<section className="section-block pt-12 md:pt-16">
<div className="container-shell grid items-center gap-8 lg:grid-cols-[1.05fr_0.95fr]">
<div className="space-y-6">
<p className="eyebrow">{eyebrow}</p>
<h1 className="text-balance text-4xl font-semibold leading-tight text-alpine-900 sm:text-5xl">
{title}
</h1>
<p className="max-w-2xl text-lg leading-relaxed text-alpine-700">{intro}</p>
{(primaryCta || secondaryCta) && (
<div className="flex flex-wrap gap-3">
{primaryCta ? (
<Link className="btn-primary" href={primaryCta.href}>
{primaryCta.label}
</Link>
) : null}
{secondaryCta ? (
<Link className="btn-secondary" href={secondaryCta.href}>
{secondaryCta.label}
</Link>
) : null}
</div>
)}
</div>
<div className="relative overflow-hidden rounded-3xl border border-alpine-200 bg-white shadow-soft">
<div className="relative h-[300px] w-full sm:h-[360px]">
<Image
alt={imageAlt}
className="object-cover"
fill
priority
sizes="(min-width: 1024px) 42vw, 100vw"
src={imageSrc}
/>
</div>
<div className="absolute inset-x-0 bottom-0 h-24 bg-gradient-to-t from-alpine-900/55 to-transparent" />
</div>
</div>
</section>
);
}
+72
View File
@@ -0,0 +1,72 @@
import Link from "next/link";
import Image from "next/image";
import { company, mainNavigation } from "@/lib/site-content";
export function SiteFooter() {
return (
<footer className="mt-20 border-t border-alpine-200 bg-alpine-900 text-alpine-50">
<div className="container-shell grid gap-10 py-14 md:grid-cols-[1.2fr_1fr_1fr]">
<div className="space-y-4">
<Image
alt="TeleNetSystems Logo hell"
className="h-10 w-auto"
src="/assets/logo/logo-weiss-ffa4cbf6.png"
width={190}
height={50}
/>
<p className="max-w-sm text-sm leading-relaxed text-alpine-100">
TeleNetSystems verbindet technisches Know-how mit regionaler Naehe. Sie bekommen klare Tarife,
erreichbare Ansprechpartner und Support aus Tirol.
</p>
</div>
<div>
<h2 className="font-heading text-lg text-white">Seiten</h2>
<ul className="mt-4 space-y-2 text-sm text-alpine-100">
{mainNavigation.map((item) => (
<li key={item.href}>
<Link className="hover:text-copper-200" href={item.href}>
{item.label}
</Link>
</li>
))}
</ul>
</div>
<div>
<h2 className="font-heading text-lg text-white">Kontakt</h2>
<ul className="mt-4 space-y-2 text-sm text-alpine-100">
<li>{company.name}</li>
<li>{company.address}</li>
<li>
<a className="hover:text-copper-200" href={`tel:${company.phone.replace(/\s+/g, "")}`}>
{company.phone}
</a>
</li>
<li>
<a className="hover:text-copper-200" href={`mailto:${company.email}`}>
{company.email}
</a>
</li>
<li>{company.openingHours}</li>
</ul>
</div>
</div>
<div className="border-t border-alpine-700/80">
<div className="container-shell flex flex-wrap items-center justify-between gap-3 py-4 text-xs text-alpine-200">
<p>© {new Date().getFullYear()} TeleNetSystems GmbH</p>
<div className="flex gap-4">
<Link className="hover:text-copper-200" href="/impressum">
Impressum
</Link>
<Link className="hover:text-copper-200" href="/datenschutz">
Datenschutz
</Link>
</div>
</div>
</div>
</footer>
);
}
+57
View File
@@ -0,0 +1,57 @@
import Link from "next/link";
import Image from "next/image";
import { company, mainNavigation } from "@/lib/site-content";
export function SiteHeader() {
return (
<header className="sticky top-0 z-40 border-b border-alpine-100/70 bg-white/90 backdrop-blur">
<div className="bg-alpine-900 text-alpine-50">
<div className="container-shell flex flex-wrap items-center justify-between gap-2 py-2 text-xs sm:text-sm">
<p>{company.region} | Persoenlicher IT- und Telekom-Service</p>
<div className="flex flex-wrap gap-4">
<a className="hover:text-copper-200" href={`tel:${company.phone.replace(/\s+/g, "")}`}>
{company.phone}
</a>
<a className="hover:text-copper-200" href={`mailto:${company.email}`}>
{company.email}
</a>
</div>
</div>
</div>
<div className="container-shell flex flex-wrap items-center justify-between gap-6 py-4">
<Link className="group inline-flex items-center gap-3" href="/">
<Image
alt="TeleNetSystems Logo"
className="h-10 w-auto transition group-hover:scale-[1.02]"
src="/assets/logo/logo-systems-9fd0db14.png"
width={190}
height={50}
priority
/>
<span className="font-heading text-sm uppercase tracking-[0.22em] text-alpine-700">
Reutte | Tirol
</span>
</Link>
<nav aria-label="Hauptnavigation" className="w-full overflow-x-auto pb-1 lg:w-auto lg:pb-0">
<ul className="flex min-w-max items-center gap-2 text-sm font-semibold text-alpine-700">
{mainNavigation.map((item) => (
<li key={item.href}>
<Link className="nav-chip" href={item.href}>
{item.label}
</Link>
</li>
))}
<li>
<Link className="btn-primary ml-2" href="/#kontakt">
Beratung anfragen
</Link>
</li>
</ul>
</nav>
</div>
</header>
);
}