docs: add implementation plan for Pakete overview + VPN page
This commit is contained in:
parent
97102ff25c
commit
0889a86405
|
|
@ -0,0 +1,571 @@
|
||||||
|
# Pakete & Preise — Service-Übersicht + Zero-Trust-VPN
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Die `/pakete`-Seite zur Service-Übersicht mit 2 klickbaren Kacheln umbauen; bestehenden Nextcloud-Inhalt auf `/pakete/nextcloud` verschieben; neue VPN-Seite `/pakete/vpn` anlegen.
|
||||||
|
|
||||||
|
**Architecture:** Drei Next.js Server Components. `/pakete` wird zur Übersichtsseite, die zwei Unterseiten per `<Link>` verknüpft. Kein Client-State nötig. Bestehende Design-Token (`bg-[#18212f]`, `text-orange-400`, `.btn-primary`) und Layout-Muster aus der aktuellen Pakete-Seite werden übernommen.
|
||||||
|
|
||||||
|
**Tech Stack:** Next.js 15 App Router, TypeScript (strict), Tailwind CSS, `next/link`, `next/navigation`
|
||||||
|
|
||||||
|
## Global Constraints
|
||||||
|
|
||||||
|
- Kein `"use client"` — alle drei Seiten sind Server Components
|
||||||
|
- Importpfade via `@/`-Alias (z. B. `@/components/Logo`)
|
||||||
|
- `ReactElement` statt `JSX.Element` (Next.js 15 / React 19)
|
||||||
|
- Alle Preise zzgl. MwSt., Link für CTAs immer `/#contact`
|
||||||
|
- `npm run build` muss fehlerfrei durchlaufen
|
||||||
|
- Nach jedem Task: `npx tsc --noEmit` grün
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Datei-Übersicht
|
||||||
|
|
||||||
|
| Datei | Aktion |
|
||||||
|
|---|---|
|
||||||
|
| `app/pakete/page.tsx` | Umbau: wird zur Übersichtsseite |
|
||||||
|
| `app/pakete/nextcloud/page.tsx` | Neu: bestehender Pakete-Inhalt |
|
||||||
|
| `app/pakete/vpn/page.tsx` | Neu: Zero-Trust-VPN Seite |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Nextcloud-Unterseite anlegen
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `app/pakete/nextcloud/page.tsx`
|
||||||
|
- Modify: `app/pakete/page.tsx` (Zurück-Link anpassen, Inhalt entfernen — in Task 3)
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Produces: Route `/pakete/nextcloud` — vollständige Nextcloud + Paperless Pakete-Seite
|
||||||
|
|
||||||
|
- [ ] **Step 1: Datei anlegen — Inhalt aus aktuellem `/pakete/page.tsx` kopieren**
|
||||||
|
|
||||||
|
Erstelle `app/pakete/nextcloud/page.tsx` mit exakt dem Inhalt von `app/pakete/page.tsx`, aber mit diesen zwei Änderungen:
|
||||||
|
|
||||||
|
1. Metadata anpassen:
|
||||||
|
```tsx
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Nextcloud + Paperless | Pakete & Preise",
|
||||||
|
description:
|
||||||
|
"Nextcloud + Paperless-ngx auf Docker, Kubernetes oder Proxmox: Installation, Hosting und Wartung in Crailsheim. Individuelle Angebote auf Anfrage.",
|
||||||
|
openGraph: {
|
||||||
|
title: "Nextcloud + Paperless | MBO-Tech-IT",
|
||||||
|
description:
|
||||||
|
"Nextcloud + Paperless-ngx auf Docker, Kubernetes oder Proxmox: Installation, Hosting und Wartung in Crailsheim.",
|
||||||
|
url: "https://mbo-tech-it.de/pakete/nextcloud",
|
||||||
|
},
|
||||||
|
alternates: {
|
||||||
|
canonical: "https://mbo-tech-it.de/pakete/nextcloud",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
2. „← Zurück"-Link zeigt auf `/pakete` statt `/`:
|
||||||
|
```tsx
|
||||||
|
<Link
|
||||||
|
href="/pakete"
|
||||||
|
className="flex items-center gap-2 text-slate-600 dark:text-slate-400 hover:text-orange-400 transition-colors text-sm font-medium"
|
||||||
|
>
|
||||||
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||||
|
</svg>
|
||||||
|
Zurück
|
||||||
|
</Link>
|
||||||
|
```
|
||||||
|
|
||||||
|
Die Funktion heißt `NextcloudPage` statt `PaketePage`:
|
||||||
|
```tsx
|
||||||
|
export default function NextcloudPage() {
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: TypeScript prüfen**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tsc --noEmit
|
||||||
|
```
|
||||||
|
|
||||||
|
Erwartet: keine Fehler
|
||||||
|
|
||||||
|
- [ ] **Step 3: Im Browser prüfen**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Öffne `http://localhost:3000/pakete/nextcloud` — Seite muss identisch mit dem alten `/pakete` aussehen. Zurück-Button führt zu `/pakete` (404 noch ok, kommt in Task 3).
|
||||||
|
|
||||||
|
- [ ] **Step 4: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add app/pakete/nextcloud/page.tsx
|
||||||
|
git commit -m "feat: move Nextcloud packages to /pakete/nextcloud"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 2: VPN-Unterseite anlegen
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `app/pakete/vpn/page.tsx`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Produces: Route `/pakete/vpn` — Zero-Trust-VPN Detailseite mit 3 Preiskarten
|
||||||
|
|
||||||
|
- [ ] **Step 1: Datei `app/pakete/vpn/page.tsx` erstellen**
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import type { Metadata } from "next";
|
||||||
|
import Link from "next/link";
|
||||||
|
import Logo from "@/components/Logo";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Zero-Trust-VPN | MBO-Tech-IT",
|
||||||
|
description:
|
||||||
|
"Managed Netbird VPN mit WireGuard für Ihr Unternehmen — sicherer Fernzugriff, DSGVO-konform, Server in Deutschland. Feste Monatspauschale ab 89 €.",
|
||||||
|
openGraph: {
|
||||||
|
title: "Zero-Trust-VPN | MBO-Tech-IT",
|
||||||
|
description:
|
||||||
|
"Managed Netbird VPN mit WireGuard — sicherer Fernzugriff, DSGVO-konform, Server in Deutschland. Ab 89 €/Monat.",
|
||||||
|
url: "https://mbo-tech-it.de/pakete/vpn",
|
||||||
|
},
|
||||||
|
alternates: {
|
||||||
|
canonical: "https://mbo-tech-it.de/pakete/vpn",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vpnPackages = [
|
||||||
|
{
|
||||||
|
name: "Starter",
|
||||||
|
users: "bis 5 Nutzer",
|
||||||
|
devices: "15 Geräte",
|
||||||
|
price: "89",
|
||||||
|
setup: "490",
|
||||||
|
highlight: false,
|
||||||
|
includes: [
|
||||||
|
"Einrichtung & Client-Rollout",
|
||||||
|
"Sicherer Fernzugriff (WireGuard)",
|
||||||
|
"Monitoring & Updates",
|
||||||
|
"E-Mail-Support",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Business",
|
||||||
|
users: "bis 20 Nutzer",
|
||||||
|
devices: "50 Geräte",
|
||||||
|
price: "149",
|
||||||
|
setup: "790",
|
||||||
|
highlight: true,
|
||||||
|
includes: [
|
||||||
|
"Alles aus Starter",
|
||||||
|
"Mehrere Standorte",
|
||||||
|
"Zugriffs-Protokollierung",
|
||||||
|
"Telefon-Support",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Professional",
|
||||||
|
users: "bis 50 Nutzer",
|
||||||
|
devices: "150 Geräte",
|
||||||
|
price: "249",
|
||||||
|
setup: "1.290",
|
||||||
|
highlight: false,
|
||||||
|
includes: [
|
||||||
|
"Alles aus Business",
|
||||||
|
"SLA 4h Reaktionszeit",
|
||||||
|
"NIS2-Dokumentation",
|
||||||
|
"Hochverfügbarkeit",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function VpnPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-[#f0f4f8] dark:bg-[#18212f]">
|
||||||
|
{/* Header */}
|
||||||
|
<header className="bg-white dark:bg-[#111925] border-b border-slate-200 dark:border-gray-800">
|
||||||
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between">
|
||||||
|
<Link href="/" className="flex items-center gap-3 group">
|
||||||
|
<Logo className="h-8 w-auto" />
|
||||||
|
<div className="flex flex-col leading-tight">
|
||||||
|
<span className="font-black text-slate-900 dark:text-white text-base tracking-wider uppercase">
|
||||||
|
MBO-<span className="bg-gradient-to-r from-blue-400 to-blue-600 bg-clip-text text-transparent">TECH-IT</span>
|
||||||
|
</span>
|
||||||
|
<span className="text-[9px] font-semibold tracking-[0.2em] text-orange-400/70 uppercase hidden sm:block">
|
||||||
|
Digital Denken. Lokal Handeln.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/pakete"
|
||||||
|
className="flex items-center gap-2 text-slate-600 dark:text-slate-400 hover:text-orange-400 transition-colors text-sm font-medium"
|
||||||
|
>
|
||||||
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||||
|
</svg>
|
||||||
|
Zurück
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||||
|
|
||||||
|
{/* Hero */}
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<span className="text-orange-400 font-mono text-xs font-bold tracking-[0.25em] uppercase">
|
||||||
|
NEU: Zero-Trust-VPN
|
||||||
|
</span>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-black text-slate-900 dark:text-white mt-3 mb-4">
|
||||||
|
Ihre Mitarbeiter. Überall.<br className="hidden sm:block" /> Sicher verbunden.
|
||||||
|
</h1>
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-lg max-w-2xl mx-auto">
|
||||||
|
Kein offener Port. Kein VPN-Konzentrator. Keine Fritzbox-Bastelei.
|
||||||
|
Von uns eingerichtet, betrieben und überwacht.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Was ist das? */}
|
||||||
|
<div className="grid md:grid-cols-2 gap-6 mb-16">
|
||||||
|
<div className="p-6 rounded-2xl bg-white dark:bg-gray-900 border border-slate-200 dark:border-gray-800">
|
||||||
|
<div className="w-12 h-12 rounded-xl bg-orange-500/10 text-orange-400 flex items-center justify-center mb-4">
|
||||||
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="text-slate-800 dark:text-white font-bold text-lg mb-2">Zero Trust</h3>
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-sm leading-relaxed">
|
||||||
|
Jeder Mitarbeiter sieht nur, was er darf — Buchhalter kommt nicht ans Lager,
|
||||||
|
Monteur nicht in die Buchhaltung. Granulare Rechteverwaltung statt
|
||||||
|
„einmal drin = alles sehen" wie beim klassischen VPN.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="p-6 rounded-2xl bg-white dark:bg-gray-900 border border-slate-200 dark:border-gray-800">
|
||||||
|
<div className="w-12 h-12 rounded-xl bg-blue-500/10 text-blue-400 flex items-center justify-center mb-4">
|
||||||
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="text-slate-800 dark:text-white font-bold text-lg mb-2">WireGuard</h3>
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-sm leading-relaxed">
|
||||||
|
Modernes VPN-Protokoll der nächsten Generation: schneller und sicherer als
|
||||||
|
klassisches IPSec oder OpenVPN. Militärgrade-Verschlüsselung,
|
||||||
|
kein Datenverkehr über fremde Server, DSGVO-konform mit
|
||||||
|
Server-Standort Deutschland.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Pakete */}
|
||||||
|
<h2 className="text-3xl font-black text-slate-900 dark:text-white mb-3 text-center">
|
||||||
|
Unsere Pakete
|
||||||
|
</h2>
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-center mb-10 max-w-xl mx-auto">
|
||||||
|
Monatliche Pauschale, keine versteckten Kosten — egal wie viele Mitarbeiter
|
||||||
|
sich einwählen.
|
||||||
|
</p>
|
||||||
|
<div className="grid lg:grid-cols-3 gap-6 mb-16">
|
||||||
|
{vpnPackages.map((pkg) => (
|
||||||
|
<div
|
||||||
|
key={pkg.name}
|
||||||
|
className={`relative rounded-2xl p-6 border transition-all duration-300 ${
|
||||||
|
pkg.highlight
|
||||||
|
? "bg-orange-500/5 border-orange-500/50 shadow-lg shadow-orange-500/10"
|
||||||
|
: "bg-white dark:bg-gray-900 border-slate-200 dark:border-gray-800"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{pkg.highlight && (
|
||||||
|
<div className="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-orange-500 rounded-full text-white text-xs font-black tracking-wider">
|
||||||
|
EMPFOHLEN
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="mb-5">
|
||||||
|
<span className="text-orange-400 text-xs font-bold tracking-widest uppercase">
|
||||||
|
{pkg.users} · {pkg.devices}
|
||||||
|
</span>
|
||||||
|
<h3 className="text-2xl font-black text-slate-900 dark:text-white mt-1">{pkg.name}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Preis */}
|
||||||
|
<div className="mb-6">
|
||||||
|
<div className="flex items-end gap-1">
|
||||||
|
<span className="text-4xl font-black text-orange-400">{pkg.price} €</span>
|
||||||
|
<span className="text-slate-500 text-sm mb-1">/Monat</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-slate-500 text-xs mt-1">
|
||||||
|
Einrichtung: {pkg.setup} € einmalig
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Leistungen */}
|
||||||
|
<ul className="space-y-2 mb-6">
|
||||||
|
{pkg.includes.map((item) => (
|
||||||
|
<li key={item} className="flex items-start gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||||
|
<span className="w-4 h-4 rounded-full bg-orange-500 flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||||
|
<svg className="w-2.5 h-2.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href="/#contact"
|
||||||
|
className={`block w-full py-3 rounded-xl text-center font-bold text-sm transition-colors ${
|
||||||
|
pkg.highlight
|
||||||
|
? "bg-orange-500 hover:bg-orange-600 text-white"
|
||||||
|
: "bg-slate-100 dark:bg-gray-800 hover:bg-slate-200 dark:hover:bg-gray-700 text-slate-800 dark:text-white border border-slate-300 dark:border-gray-700"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
Paket anfragen
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Hinweis + CTA */}
|
||||||
|
<div className="p-6 rounded-2xl border border-blue-500/20 bg-blue-500/5 text-center">
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-sm">
|
||||||
|
<strong className="text-slate-900 dark:text-white">Hinweis:</strong> Alle Preise zzgl.
|
||||||
|
gesetzl. MwSt. Individuelle Angebote auf Anfrage. Kostenlose Erstberatung vor Ort —
|
||||||
|
kein Risiko, kein Kleingedrucktes.
|
||||||
|
</p>
|
||||||
|
<Link
|
||||||
|
href="/#contact"
|
||||||
|
className="inline-block mt-4 px-6 py-3 bg-orange-500 hover:bg-orange-600 text-white font-bold rounded-xl text-sm transition-colors"
|
||||||
|
>
|
||||||
|
Kostenloses Erstgespräch anfragen
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: TypeScript prüfen**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tsc --noEmit
|
||||||
|
```
|
||||||
|
|
||||||
|
Erwartet: keine Fehler
|
||||||
|
|
||||||
|
- [ ] **Step 3: Im Browser prüfen**
|
||||||
|
|
||||||
|
Öffne `http://localhost:3000/pakete/vpn`
|
||||||
|
Erwartetes Ergebnis:
|
||||||
|
- Hero mit „Ihre Mitarbeiter. Überall. Sicher verbunden."
|
||||||
|
- 2 Info-Karten (Zero Trust / WireGuard)
|
||||||
|
- 3 Preiskarten: Starter 89 €, Business 149 € (EMPFOHLEN-Badge), Professional 249 €
|
||||||
|
- Hinweis-Box + CTA unten
|
||||||
|
- Zurück-Link führt zu `/pakete`
|
||||||
|
|
||||||
|
- [ ] **Step 4: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add app/pakete/vpn/page.tsx
|
||||||
|
git commit -m "feat: add Zero-Trust-VPN detail page at /pakete/vpn"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 3: Übersichtsseite `/pakete` umbauen
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `app/pakete/page.tsx` — vollständiger Ersatz durch Übersichtsseite
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes: `/pakete/nextcloud` (Task 1), `/pakete/vpn` (Task 2)
|
||||||
|
- Produces: `/pakete` — Übersichtsseite mit 2 Service-Kacheln
|
||||||
|
|
||||||
|
- [ ] **Step 1: `app/pakete/page.tsx` vollständig ersetzen**
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import type { Metadata } from "next";
|
||||||
|
import Link from "next/link";
|
||||||
|
import Logo from "@/components/Logo";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Pakete & Preise | MBO-Tech-IT",
|
||||||
|
description:
|
||||||
|
"Unsere IT-Dienstleistungen auf einen Blick: Nextcloud + Paperless-ngx Cloud-Lösungen und Zero-Trust-VPN für sicheren Fernzugriff. Individuelle Angebote aus Crailsheim.",
|
||||||
|
openGraph: {
|
||||||
|
title: "Pakete & Preise | MBO-Tech-IT",
|
||||||
|
description:
|
||||||
|
"Nextcloud, Paperless-ngx und Zero-Trust-VPN — IT-Lösungen aus Crailsheim.",
|
||||||
|
url: "https://mbo-tech-it.de/pakete",
|
||||||
|
},
|
||||||
|
alternates: {
|
||||||
|
canonical: "https://mbo-tech-it.de/pakete",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const services = [
|
||||||
|
{
|
||||||
|
href: "/pakete/nextcloud",
|
||||||
|
icon: (
|
||||||
|
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" />
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
iconBg: "bg-blue-500/10 text-blue-400",
|
||||||
|
label: "Nextcloud + Paperless-ngx",
|
||||||
|
description:
|
||||||
|
"Eigene Cloud & digitales Dokumentenarchiv auf Ihrem Server — DSGVO-konform, selbst gehostet auf Hetzner Cloud.",
|
||||||
|
tag: "Einmalige Installation ab Anfrage",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: "/pakete/vpn",
|
||||||
|
icon: (
|
||||||
|
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
iconBg: "bg-orange-500/10 text-orange-400",
|
||||||
|
label: "Zero-Trust-VPN",
|
||||||
|
description:
|
||||||
|
"Sicherer Fernzugriff für alle Mitarbeiter. Managed Netbird mit WireGuard — Server in Deutschland, feste Monatspauschale.",
|
||||||
|
tag: "NEU · ab 89 €/Monat",
|
||||||
|
isNew: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function PaketePage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-[#f0f4f8] dark:bg-[#18212f]">
|
||||||
|
{/* Header */}
|
||||||
|
<header className="bg-white dark:bg-[#111925] border-b border-slate-200 dark:border-gray-800">
|
||||||
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between">
|
||||||
|
<Link href="/" className="flex items-center gap-3 group">
|
||||||
|
<Logo className="h-8 w-auto" />
|
||||||
|
<div className="flex flex-col leading-tight">
|
||||||
|
<span className="font-black text-slate-900 dark:text-white text-base tracking-wider uppercase">
|
||||||
|
MBO-<span className="bg-gradient-to-r from-blue-400 to-blue-600 bg-clip-text text-transparent">TECH-IT</span>
|
||||||
|
</span>
|
||||||
|
<span className="text-[9px] font-semibold tracking-[0.2em] text-orange-400/70 uppercase hidden sm:block">
|
||||||
|
Digital Denken. Lokal Handeln.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className="flex items-center gap-2 text-slate-600 dark:text-slate-400 hover:text-orange-400 transition-colors text-sm font-medium"
|
||||||
|
>
|
||||||
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||||
|
</svg>
|
||||||
|
Zurück
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||||
|
|
||||||
|
{/* Hero */}
|
||||||
|
<div className="text-center mb-16">
|
||||||
|
<span className="text-orange-400 font-mono text-xs font-bold tracking-[0.25em] uppercase">
|
||||||
|
Unsere Leistungen
|
||||||
|
</span>
|
||||||
|
<h1 className="text-4xl sm:text-5xl font-black text-slate-900 dark:text-white mt-3 mb-4">
|
||||||
|
Pakete & Preise
|
||||||
|
</h1>
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-lg max-w-2xl mx-auto">
|
||||||
|
Wählen Sie Ihre Lösung — wir installieren, betreiben und warten.
|
||||||
|
Alles aus einer Hand, aus Crailsheim.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Service-Kacheln */}
|
||||||
|
<div className="grid sm:grid-cols-2 gap-6 max-w-3xl mx-auto mb-16">
|
||||||
|
{services.map((service) => (
|
||||||
|
<Link
|
||||||
|
key={service.href}
|
||||||
|
href={service.href}
|
||||||
|
className="group relative p-6 rounded-2xl bg-white dark:bg-gray-900 border border-slate-200 dark:border-gray-800 hover:border-orange-500/50 hover:shadow-lg hover:shadow-orange-500/5 transition-all duration-300 flex flex-col"
|
||||||
|
>
|
||||||
|
{service.isNew && (
|
||||||
|
<span className="absolute top-4 right-4 px-2 py-0.5 bg-orange-500 rounded-full text-white text-[10px] font-black tracking-wider">
|
||||||
|
NEU
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<div className={`w-12 h-12 rounded-xl flex items-center justify-center mb-4 ${service.iconBg}`}>
|
||||||
|
{service.icon}
|
||||||
|
</div>
|
||||||
|
<h2 className="text-lg font-black text-slate-900 dark:text-white mb-2">
|
||||||
|
{service.label}
|
||||||
|
</h2>
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-sm leading-relaxed flex-1">
|
||||||
|
{service.description}
|
||||||
|
</p>
|
||||||
|
<div className="mt-4 flex items-center justify-between">
|
||||||
|
<span className="text-orange-400 text-xs font-bold">{service.tag}</span>
|
||||||
|
<svg
|
||||||
|
className="w-4 h-4 text-slate-400 group-hover:text-orange-400 group-hover:translate-x-1 transition-all"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* CTA */}
|
||||||
|
<div className="p-6 rounded-2xl border border-blue-500/20 bg-blue-500/5 text-center">
|
||||||
|
<p className="text-slate-600 dark:text-slate-400 text-sm">
|
||||||
|
<strong className="text-slate-900 dark:text-white">Nicht sicher, was passt?</strong>{" "}
|
||||||
|
Kostenlose Erstberatung vor Ort — kein Risiko, kein Kleingedrucktes.
|
||||||
|
</p>
|
||||||
|
<Link
|
||||||
|
href="/#contact"
|
||||||
|
className="inline-block mt-4 px-6 py-3 bg-orange-500 hover:bg-orange-600 text-white font-bold rounded-xl text-sm transition-colors"
|
||||||
|
>
|
||||||
|
Kostenloses Erstgespräch anfragen
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: TypeScript prüfen**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tsc --noEmit
|
||||||
|
```
|
||||||
|
|
||||||
|
Erwartet: keine Fehler
|
||||||
|
|
||||||
|
- [ ] **Step 3: Im Browser prüfen**
|
||||||
|
|
||||||
|
Öffne `http://localhost:3000/pakete`
|
||||||
|
Erwartetes Ergebnis:
|
||||||
|
- Hero: „Pakete & Preise"
|
||||||
|
- 2 Kacheln: „Nextcloud + Paperless-ngx" (blau) und „Zero-Trust-VPN" (orange, NEU-Badge)
|
||||||
|
- Klick auf Nextcloud-Kachel → `/pakete/nextcloud` mit vollem Inhalt
|
||||||
|
- Klick auf VPN-Kachel → `/pakete/vpn` mit Preiskarten
|
||||||
|
- Zurück-Links auf den Unterseiten führen zurück zu `/pakete`
|
||||||
|
|
||||||
|
- [ ] **Step 4: Produktions-Build prüfen**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Erwartet: Build läuft fehlerfrei durch, alle 3 Routen erscheinen in der Route-Übersicht:
|
||||||
|
- `/pakete`
|
||||||
|
- `/pakete/nextcloud`
|
||||||
|
- `/pakete/vpn`
|
||||||
|
|
||||||
|
- [ ] **Step 5: Commit + Push**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add app/pakete/page.tsx
|
||||||
|
git commit -m "feat: rebuild /pakete as service overview with tiles"
|
||||||
|
git push
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue