feat: apply Funktechnik Schubert branding

This commit is contained in:
Schubert Ferenc 2026-07-03 21:08:04 +02:00
parent 9a648e2ec8
commit 99e8201745
17 changed files with 335 additions and 104 deletions

View file

@ -1,3 +1,4 @@
import Image from "next/image";
import Link from "next/link";
export default function Footer() {
@ -5,20 +6,27 @@ export default function Footer() {
<footer className="footer">
<div className="container footer-grid">
<div>
<h3>Funktechnik Schubert</h3>
<p>Service, Reparatur und technische Unterstützung für Funkgeräte und Kommunikationstechnik.</p>
<Image
src="/funktechnik_schubert_logo.jpg"
alt="Funktechnik Schubert"
width={1672}
height={941}
className="footer-logo"
/>
<p>Funktechnik Schubert Service und technische Unterstützung für Funkgeräte, Messtechnik und Kommunikationstechnik.</p>
<p className="copyright">© Funktechnik Schubert</p>
</div>
<div>
<h3>Service</h3>
<h3>Website</h3>
<p><Link href="/leistungen">Leistungen</Link></p>
<p><Link href="/funkgeraete-service">Funkgeräte-Service</Link></p>
<p><Link href="/reparatur">Reparaturannahme</Link></p>
<p><Link href="/reparatur">Reparatur</Link></p>
<p><Link href="/kontakt">Kontakt</Link></p>
</div>
<div>
<h3>Rechtliches</h3>
<p><Link href="/impressum">Impressum</Link></p>
<p><Link href="/datenschutz">Datenschutz</Link></p>
<p><Link href="/kontakt">Kontakt</Link></p>
</div>
</div>
</footer>

View file

@ -1,6 +1,12 @@
"use client";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";
const navigation = [
["Start", "/"],
["Leistungen", "/leistungen"],
["Funkgeräte-Service", "/funkgeraete-service"],
["Reparatur", "/reparatur"],
@ -9,18 +15,39 @@ const navigation = [
] as const;
export default function Header() {
const pathname = usePathname();
const [menuOpen, setMenuOpen] = useState(false);
return (
<header className="site-header">
<div className="container header-inner">
<Link href="/" className="brand" aria-label="Funktechnik Schubert Startseite">
<span className="brand-mark" aria-hidden="true" />
<span>Funktechnik Schubert</span>
<Link href="/" className="brand" aria-label="Funktechnik Schubert Startseite" onClick={() => setMenuOpen(false)}>
<Image
src="/funktechnik_schubert_logo.jpg"
alt="Funktechnik Schubert"
width={1672}
height={941}
priority
className="brand-logo"
/>
</Link>
<nav className="nav" aria-label="Hauptnavigation">
<button
className="menu-toggle"
type="button"
aria-expanded={menuOpen}
aria-controls="site-navigation"
onClick={() => setMenuOpen((open) => !open)}
>
Menü
</button>
<nav id="site-navigation" className={menuOpen ? "nav is-open" : "nav"} aria-label="Hauptnavigation">
{navigation.map(([label, href]) => (
<Link key={href} href={href}>{label}</Link>
<Link key={href} href={href} aria-current={pathname === href ? "page" : undefined} onClick={() => setMenuOpen(false)}>
{label}
</Link>
))}
</nav>
<Link className="header-cta" href="/reparatur">Reparatur anfragen</Link>
</div>
</header>
);

View file

@ -2,7 +2,8 @@
import { useState, type FormEvent } from "react";
type Errors = Partial<Record<"name" | "email" | "manufacturer" | "model" | "description" | "privacy", string>>;
type ErrorField = "name" | "email" | "manufacturer" | "model" | "deviceType" | "description" | "privacy";
type Errors = Partial<Record<ErrorField, string>>;
export default function RepairForm() {
const [errors, setErrors] = useState<Errors>({});
@ -19,6 +20,7 @@ export default function RepairForm() {
if (!String(form.get("email") ?? "").includes("@")) nextErrors.email = "Bitte geben Sie eine gültige E-Mail-Adresse ein.";
if (!String(form.get("manufacturer") ?? "").trim()) nextErrors.manufacturer = "Bitte nennen Sie den Hersteller.";
if (!String(form.get("model") ?? "").trim()) nextErrors.model = "Bitte nennen Sie das Modell.";
if (!String(form.get("deviceType") ?? "").trim()) nextErrors.deviceType = "Bitte wählen Sie die Geräteart aus.";
if (String(form.get("description") ?? "").trim().length < 20) nextErrors.description = "Bitte beschreiben Sie den Fehler mit mindestens 20 Zeichen.";
if (form.get("privacy") !== "on") nextErrors.privacy = "Bitte stimmen Sie der Verarbeitung Ihrer Angaben zu.";
@ -52,6 +54,23 @@ export default function RepairForm() {
<Field label="Modell" name="model" error={errors.model} />
<Field label="Seriennummer optional" name="serialNumber" />
</div>
<div className="field">
<label htmlFor="deviceType">Geräteart</label>
<select id="deviceType" name="deviceType" defaultValue="">
<option value="">Bitte auswählen</option>
<option value="cb-radio">CB-Funkgerät</option>
<option value="amateur-radio">Amateurfunkgerät</option>
<option value="business-radio">Betriebsfunkgerät</option>
<option value="receiver">Empfänger / Scanner</option>
<option value="measurement">Messtechnik</option>
<option value="other">Sonstige Kommunikationstechnik</option>
</select>
{errors.deviceType && <span className="error">{errors.deviceType}</span>}
</div>
<div className="field">
<label htmlFor="accessories">Zubehör vorhanden</label>
<textarea id="accessories" name="accessories" placeholder="z. B. Netzteil, Mikrofon, Kabel, Adapter, Antenne oder Bediengerät" />
</div>
<div className="field">
<label htmlFor="opened">Wurde das Gerät bereits geöffnet?</label>
<select id="opened" name="opened" defaultValue="unknown">
@ -62,14 +81,14 @@ export default function RepairForm() {
</div>
<div className="field">
<label htmlFor="previousWork">Gibt es Vorarbeiten?</label>
<textarea id="previousWork" name="previousWork" placeholder="z. B. Bauteile getauscht, Abgleich versucht, Fremdwerkstatt" />
<textarea id="previousWork" name="previousWork" placeholder="z. B. Bauteile getauscht, Abgleich versucht, Reinigung, Messung, Fremdwerkstatt" />
</div>
<div className="field">
<label htmlFor="description">Fehlerbeschreibung</label>
<textarea id="description" name="description" placeholder="Bitte Gerät, Fehlerbild und bisherige Beobachtungen beschreiben." />
<textarea id="description" name="description" placeholder="Bitte Fehlerbild möglichst konkret beschreiben: tritt der Fehler beim Empfang, Senden, bei Modulation, Frequenz, Anzeige oder Stromversorgung auf?" />
{errors.description && <span className="error">{errors.description}</span>}
</div>
<p className="notice">Datei- und Bild-Upload ist für eine spätere Ausbaustufe vorbereitet. Bitte senden Sie Bilder aktuell erst nach Rückmeldung.</p>
<p className="notice">Fotos vom Gerät, Typenschild oder Innenleben können später nach Rückmeldung ergänzt werden. Bitte senden Sie aktuell noch keine Dateien unaufgefordert.</p>
<label className="checkbox">
<input type="checkbox" name="privacy" />
<span>Ich stimme zu, dass meine Angaben zur Bearbeitung der Reparaturanfrage verarbeitet werden.</span>