"use client"; import { useState } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; // KOMPONENT 1: MultiSelect for samarbeidende klubber const MultiSelect = ({ label, options, selected, onChange }: { label: string, options: any[], selected: string[], onChange: (s: string[]) => void }) => { const toggle = (val: string) => { if (selected.includes(val)) onChange(selected.filter(x => x !== val)); else onChange([...selected, val]); }; return (
{options.map(opt => ( ))}
); }; // KOMPONENT 2: Viser flate JSON-objekter (som fasiliteter) som rader med Nøkkel og Verdi const KeyValueEditor = ({ label, value, onChange }: { label: string, value: any, onChange: (v: any) => void }) => { const entries = Object.entries(value || {}); const updateKey = (oldKey: string, newKey: string, val: any) => { const newObj: any = {}; for (const [k, v] of entries) { if (k === oldKey) { if (newKey.trim()) newObj[newKey] = val; } else { newObj[k] = v; } } onChange(newObj); }; const updateVal = (key: string, val: string) => { onChange({ ...value, [key]: val }); }; const removeKey = (key: string) => { const newObj = { ...value }; delete newObj[key]; onChange(newObj); }; const addRow = () => { const tempKey = `ny_rad_${Date.now()}`; onChange({ ...value, [tempKey]: "" }); }; return (
{entries.map(([k, v]) => (
updateKey(k, e.target.value, v)} /> updateVal(k, e.target.value)} />
))}
); }; // KOMPONENT 3: Viser Arrays med objekter (som Greenfee-lister) som små pene kort const ListObjectEditor = ({ label, value, templateKeys, onChange }: { label: string, value: any[], templateKeys: string[], onChange: (v: any[]) => void }) => { const items = Array.isArray(value) ? value : []; const updateField = (index: number, key: string, val: string | number) => { const newItems = [...items]; const parsedVal = (!isNaN(Number(val)) && val !== "") ? Number(val) : val; newItems[index] = { ...newItems[index], [key]: parsedVal }; onChange(newItems); }; const addRow = () => { const newItem: any = {}; templateKeys.forEach(k => newItem[k] = ""); onChange([...items, newItem]); }; const removeRow = (index: number) => { const newItems = items.filter((_, i) => i !== index); onChange(newItems); }; return (
{items.map((item, idx) => (
{templateKeys.map(key => (
updateField(idx, key, e.target.value)} />
))}
))}
); }; // KOMPONENT 4: DEN NYE SCOREKORT-BYGGEREN const ScorecardBuilder = ({ course, onChange }: { course: any, onChange: (c: any) => void }) => { const ALL_KEYS = ['lengst', 'lang', 'mellomlang', 'mellomkort', 'kort', 'kortest']; const [holes, setHoles] = useState(() => { const h = course.holes || []; if (h.length === 0) { return Array.from({length: 18}, (_, i) => ({ hole_number: i+1, par: '', hcp_index: '', lengths: {} })); } return h.sort((a: any, b: any) => a.hole_number - b.hole_number); }); const [activeKeys, setActiveKeys] = useState(() => { const keys = new Set(); holes.forEach(h => { if (h.lengths) Object.keys(h.lengths).forEach(k => keys.add(k)); }); return ALL_KEYS.filter(k => keys.has(k)); }); const [tees, setTees] = useState(() => { const herrer = course.tee_boxes?.herrer || []; const damer = course.tee_boxes?.damer || []; const initialTees = { herrer: {} as any, damer: {} as any }; activeKeys.forEach((key, idx) => { initialTees.herrer[key] = herrer[idx] || { navn_utslag: '', baneverdi: '', slopeverdi: '' }; initialTees.damer[key] = damer[idx] || { navn_utslag_damer: '', baneverdi_damer: '', slopeverdi_damer: '' }; }); return initialTees; }); const syncToParent = (newHoles: any[], newKeys: string[], newTees: any) => { const updatedTeeBoxes = { herrer: newKeys.map(k => newTees.herrer[k] || {}), damer: newKeys.map(k => newTees.damer[k] || {}) }; onChange({ ...course, holes: newHoles, tee_boxes: updatedTeeBoxes }); }; const toggleKey = (key: string) => { const newKeys = activeKeys.includes(key) ? activeKeys.filter(k => k !== key) : ALL_KEYS.filter(k => activeKeys.includes(k) || k === key); setActiveKeys(newKeys); const newTees = { ...tees }; if (!newTees.herrer[key]) newTees.herrer[key] = { navn_utslag: '', baneverdi: '', slopeverdi: '' }; if (!newTees.damer[key]) newTees.damer[key] = { navn_utslag_damer: '', baneverdi_damer: '', slopeverdi_damer: '' }; setTees(newTees); syncToParent(holes, newKeys, newTees); }; const updateTee = (gender: 'herrer'|'damer', key: string, field: string, value: string) => { const newTees = { ...tees }; newTees[gender][key] = { ...newTees[gender][key], [field]: value }; setTees(newTees); syncToParent(holes, activeKeys, newTees); }; const updateHole = (index: number, field: string, value: string, lengthKey: string | null = null) => { const newHoles = [...holes]; if (lengthKey) { newHoles[index].lengths = { ...newHoles[index].lengths, [lengthKey]: value === '' ? '' : Number(value) }; } else { newHoles[index][field] = value === '' ? '' : Number(value); } setHoles(newHoles); syncToParent(newHoles, activeKeys, tees); }; const addHole = () => { const newHoles = [...holes, { hole_number: holes.length + 1, par: '', hcp_index: '', lengths: {} }]; setHoles(newHoles); syncToParent(newHoles, activeKeys, tees); }; const removeLastHole = () => { const newHoles = holes.slice(0, -1); setHoles(newHoles); syncToParent(newHoles, activeKeys, tees); }; return (
Aktive Utslagskolonner: {ALL_KEYS.map(k => ( ))}
{activeKeys.map(k => )} {/* Herrer */} {activeKeys.map(k => ( ))} {/* Damer */} {activeKeys.map(k => ( ))} {holes.map((h, idx) => ( {activeKeys.map(k => ( ))} ))}
Hull Par HCP{k}
Herrer (Navn / CR / Slope)
updateTee('herrer', k, 'navn_utslag', e.target.value)} />
updateTee('herrer', k, 'baneverdi', e.target.value)} /> updateTee('herrer', k, 'slopeverdi', e.target.value)} />
Damer (Navn / CR / Slope)
updateTee('damer', k, 'navn_utslag_damer', e.target.value)} />
updateTee('damer', k, 'baneverdi_damer', e.target.value)} /> updateTee('damer', k, 'slopeverdi_damer', e.target.value)} />
{h.hole_number} updateHole(idx, 'par', e.target.value)} /> updateHole(idx, 'hcp_index', e.target.value)} /> updateHole(idx, 'lengths', e.target.value, k)} />
); }; export default function EditFacilityClient({ initialData, allFacilities }: { initialData: any, allFacilities: any[] }) { const router = useRouter(); const [formData, setFormData] = useState(initialData); const [activeTab, setActiveTab] = useState('generelt'); const [saving, setSaving] = useState(false); // Trekk ut unike arkitekter fra alle anlegg const uniqueArchitects = Array.from(new Set(allFacilities.map(f => f.architect).filter(Boolean))).sort(); // Sørg for at cooperating_clubs er et array const [coopClubs, setCoopClubs] = useState( Array.isArray(initialData.cooperating_clubs) ? initialData.cooperating_clubs : (typeof initialData.cooperating_clubs === 'string' ? JSON.parse(initialData.cooperating_clubs) : []) ); const handleChange = (field: string, value: any) => { setFormData((prev: any) => ({ ...prev, [field]: value })); }; const handleSave = async () => { setSaving(true); try { const res = await fetch(`/api/admin/facilities/${initialData.id}/full`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }); if (res.ok) { alert("Lagret suksessfullt!"); router.refresh(); } else { alert("Noe gikk galt under lagring."); } } catch (e) { alert("Nettverksfeil."); } setSaving(false); }; const tabs = [ { id: 'generelt', label: 'Generelt' }, { id: 'lokasjon', label: 'Lokasjon & Kontakt' }, { id: 'linker', label: 'Lenker & Media' }, { id: 'okonomi', label: 'Økonomi & Medlemskap' }, { id: 'baner', label: 'Baner & Scorekort' } ]; // Hjelpefunksjon for å hente ut verdi (spesielt formatert for dato) const getValue = (field: string, type: string) => { let val = formData[field] || ""; if (type === 'date' && val) { val = val.split('T')[0]; } return val; }; return (
← Tilbake til oversikten

Rediger: {initialData.name}

{/* SIDEBAR MENY */}
{tabs.map(tab => ( ))}
{/* SKJEMA OMRÅDE */}
{activeTab === 'generelt' && (
handleChange('name', e.target.value)} />