Standardize `contentHalfWidth` prop for `PageSideAds` component across various pages to ensure consistent ad display width, aligning with the homepage's default. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 23852c00-4779-460a-9e0c-d09fee4b6c92 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: e51668b3-7420-47a3-aa94-692b13689b33 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/23852c00-4779-460a-9e0c-d09fee4b6c92/ee1CXlO Replit-Helium-Checkpoint-Created: true
231 lines
11 KiB
TypeScript
231 lines
11 KiB
TypeScript
import { useState } from "react";
|
||
import { Mail, Phone, Send, CheckCircle, AlertCircle } from "lucide-react";
|
||
import { SiFacebook, SiInstagram, SiYoutube, SiTiktok } from "react-icons/si";
|
||
import Header from "@/components/header";
|
||
import Footer from "@/components/footer";
|
||
import { usePageMeta } from "@/hooks/use-page-meta";
|
||
import { PageSideAds } from "@/components/adsense";
|
||
import { apiRequest } from "@/lib/queryClient";
|
||
|
||
export default function KontaktPage() {
|
||
usePageMeta("Kontakt - FOLX TV", "Kontaktieren Sie FOLX TV – Ihr Fernsehsender für Volksmusik und Schlager.");
|
||
|
||
const [formData, setFormData] = useState({ name: "", email: "", subject: "", message: "" });
|
||
const [status, setStatus] = useState<"idle" | "sending" | "success" | "error">("idle");
|
||
const [errorMsg, setErrorMsg] = useState("");
|
||
|
||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
|
||
setFormData((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
||
};
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
if (!formData.name || !formData.email || !formData.message) {
|
||
setErrorMsg("Bitte füllen Sie alle Pflichtfelder aus.");
|
||
setStatus("error");
|
||
return;
|
||
}
|
||
setStatus("sending");
|
||
setErrorMsg("");
|
||
try {
|
||
await apiRequest("POST", "/api/contact", formData);
|
||
setStatus("success");
|
||
setFormData({ name: "", email: "", subject: "", message: "" });
|
||
} catch (err: any) {
|
||
setErrorMsg(err.message || "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.");
|
||
setStatus("error");
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="min-h-screen bg-background">
|
||
<Header />
|
||
<PageSideAds />
|
||
<main className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||
<div className="flex items-center gap-3 mb-8">
|
||
<Mail className="w-7 h-7 text-primary" />
|
||
<h1 className="text-3xl font-bold text-foreground" data-testid="text-kontakt-title">
|
||
Kontakt
|
||
</h1>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-10">
|
||
<div className="space-y-6">
|
||
<p className="text-muted-foreground text-[15px] leading-relaxed">
|
||
Haben Sie Fragen, Anregungen oder möchten Sie mit uns in Kontakt treten? Wir freuen uns auf Ihre Nachricht!
|
||
</p>
|
||
|
||
<div className="space-y-4">
|
||
<a
|
||
href="tel:+491725675800"
|
||
className="flex items-start gap-3 group"
|
||
data-testid="link-kontakt-phone"
|
||
>
|
||
<div className="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0 group-hover:bg-primary/20 transition-colors">
|
||
<Phone className="w-5 h-5 text-primary" />
|
||
</div>
|
||
<div>
|
||
<p className="text-xs text-muted-foreground">Telefon</p>
|
||
<p className="text-foreground font-medium group-hover:text-primary transition-colors" data-testid="text-kontakt-phone">+49 172 567 58 00</p>
|
||
</div>
|
||
</a>
|
||
|
||
<a
|
||
href="mailto:office@folx.tv"
|
||
className="flex items-start gap-3 group"
|
||
data-testid="link-kontakt-email"
|
||
>
|
||
<div className="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0 group-hover:bg-primary/20 transition-colors">
|
||
<Mail className="w-5 h-5 text-primary" />
|
||
</div>
|
||
<div>
|
||
<p className="text-xs text-muted-foreground">E-Mail</p>
|
||
<p className="text-foreground font-medium group-hover:text-primary transition-colors" data-testid="text-kontakt-email">office@folx.tv</p>
|
||
</div>
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div className="pt-2">
|
||
<p className="text-xs text-muted-foreground mb-3">Folgen Sie uns</p>
|
||
<div className="flex gap-3">
|
||
{[
|
||
{ href: "https://www.facebook.com/folxtv/", icon: SiFacebook, label: "Facebook" },
|
||
{ href: "https://www.instagram.com/folxtv/", icon: SiInstagram, label: "Instagram" },
|
||
{ href: "https://www.youtube.com/@folxmtv", icon: SiYoutube, label: "YouTube" },
|
||
{ href: "https://www.tiktok.com/@folxtv", icon: SiTiktok, label: "TikTok" },
|
||
].map((s) => (
|
||
<a
|
||
key={s.label}
|
||
href={s.href}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="w-10 h-10 rounded-lg bg-card border border-card-border flex items-center justify-center text-muted-foreground hover:text-primary hover:border-primary/30 transition-colors"
|
||
aria-label={s.label}
|
||
data-testid={`link-kontakt-${s.label.toLowerCase()}`}
|
||
>
|
||
<s.icon className="w-4 h-4" />
|
||
</a>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="bg-card border border-card-border rounded-xl p-6" data-testid="section-kontakt-form">
|
||
<h2 className="text-lg font-semibold text-card-foreground mb-4">Nachricht senden</h2>
|
||
|
||
{status === "success" ? (
|
||
<div className="flex flex-col items-center justify-center py-8 text-center" data-testid="kontakt-success">
|
||
<CheckCircle className="w-12 h-12 text-green-500 mb-3" />
|
||
<h3 className="text-foreground font-semibold text-lg mb-1">Vielen Dank!</h3>
|
||
<p className="text-muted-foreground text-sm">Ihre Nachricht wurde erfolgreich gesendet. Wir melden uns so schnell wie möglich bei Ihnen.</p>
|
||
<button
|
||
onClick={() => setStatus("idle")}
|
||
className="mt-4 text-primary text-sm hover:underline"
|
||
data-testid="button-kontakt-another"
|
||
>
|
||
Weitere Nachricht senden
|
||
</button>
|
||
</div>
|
||
) : (
|
||
<form onSubmit={handleSubmit} className="space-y-4">
|
||
<div>
|
||
<label htmlFor="name" className="block text-sm font-medium text-card-foreground mb-1">
|
||
Name <span className="text-red-500">*</span>
|
||
</label>
|
||
<input
|
||
type="text"
|
||
id="name"
|
||
name="name"
|
||
value={formData.name}
|
||
onChange={handleChange}
|
||
className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary/50"
|
||
placeholder="Ihr Name"
|
||
data-testid="input-kontakt-name"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label htmlFor="email" className="block text-sm font-medium text-card-foreground mb-1">
|
||
E-Mail <span className="text-red-500">*</span>
|
||
</label>
|
||
<input
|
||
type="email"
|
||
id="email"
|
||
name="email"
|
||
value={formData.email}
|
||
onChange={handleChange}
|
||
className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary/50"
|
||
placeholder="ihre@email.com"
|
||
data-testid="input-kontakt-email"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label htmlFor="subject" className="block text-sm font-medium text-card-foreground mb-1">
|
||
Betreff
|
||
</label>
|
||
<select
|
||
id="subject"
|
||
name="subject"
|
||
value={formData.subject}
|
||
onChange={handleChange}
|
||
className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground text-sm focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary/50"
|
||
data-testid="select-kontakt-subject"
|
||
>
|
||
<option value="">Bitte wählen...</option>
|
||
<option value="Allgemeine Anfrage">Allgemeine Anfrage</option>
|
||
<option value="Programmvorschlag">Programmvorschlag</option>
|
||
<option value="Technischer Support">Technischer Support</option>
|
||
<option value="Werbung & Kooperationen">Werbung & Kooperationen</option>
|
||
<option value="Presse">Presse</option>
|
||
<option value="Sonstiges">Sonstiges</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<label htmlFor="message" className="block text-sm font-medium text-card-foreground mb-1">
|
||
Nachricht <span className="text-red-500">*</span>
|
||
</label>
|
||
<textarea
|
||
id="message"
|
||
name="message"
|
||
value={formData.message}
|
||
onChange={handleChange}
|
||
rows={5}
|
||
className="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary/50 resize-none"
|
||
placeholder="Ihre Nachricht..."
|
||
data-testid="input-kontakt-message"
|
||
/>
|
||
</div>
|
||
|
||
{status === "error" && (
|
||
<div className="flex items-center gap-2 text-red-500 text-sm" data-testid="kontakt-error">
|
||
<AlertCircle className="w-4 h-4 flex-shrink-0" />
|
||
<span>{errorMsg}</span>
|
||
</div>
|
||
)}
|
||
|
||
<button
|
||
type="submit"
|
||
disabled={status === "sending"}
|
||
className="w-full flex items-center justify-center gap-2 px-4 py-2.5 bg-primary hover:bg-primary/90 disabled:bg-primary/50 text-primary-foreground font-medium text-sm rounded-lg transition-colors"
|
||
data-testid="button-kontakt-submit"
|
||
>
|
||
{status === "sending" ? (
|
||
<div className="w-4 h-4 border-2 border-primary-foreground/50 border-t-primary-foreground rounded-full animate-spin" />
|
||
) : (
|
||
<Send className="w-4 h-4" />
|
||
)}
|
||
{status === "sending" ? "Wird gesendet..." : "Nachricht senden"}
|
||
</button>
|
||
</form>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</main>
|
||
<Footer />
|
||
</div>
|
||
);
|
||
}
|