diff --git a/src/app/admin/contact/page.tsx b/src/app/admin/contact/page.tsx index dc3052a..4915722 100644 --- a/src/app/admin/contact/page.tsx +++ b/src/app/admin/contact/page.tsx @@ -1,54 +1,240 @@ "use client"; +import { useState } from "react"; +import { ChevronDown, Plus, X, AlertCircle, Check } from "lucide-react"; import { SectionEditor } from "../_components/SectionEditor"; -import { InputField, TextareaField } from "../_components/FormField"; -import { ArrayEditor } from "../_components/ArrayEditor"; +import { InputField } from "../_components/FormField"; import type { ContactInfo } from "@/types/content"; +// --- Phone input with mask --- +function PhoneField({ value, onChange }: { value: string; onChange: (v: string) => void }) { + function formatPhone(raw: string): string { + const digits = raw.replace(/\D/g, "").slice(0, 12); + if (digits.length === 0) return "+375 "; + let result = "+"; + for (let i = 0; i < digits.length; i++) { + if (i === 3) result += " ("; + if (i === 5) result += ") "; + if (i === 8) result += "-"; + if (i === 10) result += "-"; + result += digits[i]; + } + return result; + } + + function handleChange(e: React.ChangeEvent) { + const formatted = formatPhone(e.target.value); + onChange(formatted); + } + + const digits = value.replace(/\D/g, ""); + const isComplete = digits.length === 12; + + return ( +
+ +
+ + {isComplete && ( + + )} +
+ {value && !isComplete && ( +

Формат: +375 (XX) XXX-XX-XX

+ )} +
+ ); +} + +// --- Instagram field with validation --- +function InstagramField({ value, onChange }: { value: string; onChange: (v: string) => void }) { + function getError(): string | null { + if (!value) return null; + try { + const url = new URL(value); + const host = url.hostname.replace("www.", ""); + if (host !== "instagram.com" && host !== "instagr.am") { + return "Ссылка должна вести на instagram.com"; + } + return null; + } catch { + return "Некорректная ссылка"; + } + } + + const error = getError(); + + return ( +
+ +
+ onChange(e.target.value)} + placeholder="https://instagram.com/blackheartdancehouse" + className={`w-full rounded-lg border bg-neutral-800 px-4 py-2.5 text-white placeholder-neutral-500 outline-none transition-colors ${ + error ? "border-red-500/50" : "border-white/10 focus:border-gold" + }`} + /> + {value && !error && ( + + )} + {error && ( + + )} +
+ {error && ( +

{error}

+ )} +
+ ); +} + +// --- Compact address list --- +function AddressList({ items, onChange }: { items: string[]; onChange: (items: string[]) => void }) { + const [draft, setDraft] = useState(""); + + function add() { + const val = draft.trim(); + if (!val) return; + onChange([...items, val]); + setDraft(""); + } + + function remove(index: number) { + onChange(items.filter((_, i) => i !== index)); + } + + function update(index: number, value: string) { + onChange(items.map((item, i) => (i === index ? value : item))); + } + + return ( +
+ {items.map((addr, i) => ( +
+ update(i, e.target.value)} + className="flex-1 rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-sm text-white outline-none focus:border-gold transition-colors" + /> + +
+ ))} +
+ setDraft(e.target.value)} + onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); add(); } }} + onBlur={add} + placeholder="Добавить адрес..." + className="flex-1 rounded-lg border border-dashed border-white/15 bg-neutral-800/50 px-4 py-2.5 text-sm text-white placeholder-neutral-500 outline-none focus:border-gold/50 transition-colors" + /> + +
+
+ ); +} + +// --- Collapsible section --- +function CollapsibleSection({ + title, + defaultOpen = true, + children, +}: { + title: string; + defaultOpen?: boolean; + children: React.ReactNode; +}) { + const [open, setOpen] = useState(defaultOpen); + + return ( +
+ +
+
+
+ {children} +
+
+
+
+ ); +} + export default function ContactEditorPage() { return ( sectionKey="contact" title="Контакты"> {(data, update) => ( - <> +
update({ ...data, title: v })} /> - update({ ...data, phone: v })} - type="tel" - /> - update({ ...data, instagram: v })} - type="url" - /> + +
+ update({ ...data, phone: v })} + /> + update({ ...data, instagram: v })} + /> +
+ update({ ...data, workingHours: v })} /> - update({ ...data, addresses })} - renderItem={(addr, _i, updateItem) => ( - - )} - createItem={() => ""} - addLabel="Добавить адрес" - /> - update({ ...data, mapEmbedUrl: v })} - rows={2} - /> - + + + update({ ...data, addresses })} + /> + + +
)} );