'use client' import { useState } from 'react' import { Copy } from 'lucide-react' import { updateSpaceSettings, updateSpaceVisibility } from '@/lib/actions' import { financialVisibilities, directoryVisibilities } from '@/lib/validations' import type { SaveStatus, Space, SpaceExt } from '../types' interface Props extends SaveStatus { space: Space isAdmin: boolean } export function SpacePanel({ space, isAdmin, saving, setSaving, setMessage }: Props) { const spaceExt = space as SpaceExt // Space form (basic + mission statement) const [spaceForm, setSpaceForm] = useState({ name: space.name || '', slug: space.slug || '', city: space.city || '', require_approval: space.require_approval ?? true, public_member_directory: space.public_member_directory ?? false, mission_statement: spaceExt.mission_statement || '', }) // Visibility form (governance) — separate server action, separate save. const [visibilityForm, setVisibilityForm] = useState({ financial_visibility: (spaceExt.financial_visibility as string | undefined) || 'board_visible', member_directory_visibility: (spaceExt.member_directory_visibility as string | undefined) || 'members_visible', }) async function handleSaveSpace(e: React.FormEvent) { e.preventDefault() if (!isAdmin) return setSaving(true) setMessage(null) const result = await updateSpaceSettings(spaceForm) if (result.error) { setMessage({ type: 'error', text: result.error }) } else { setMessage({ type: 'success', text: 'Settings saved!' }) } setSaving(false) } async function handleSaveVisibility(e: React.FormEvent) { e.preventDefault() if (!isAdmin) return setSaving(true) setMessage(null) const result = await updateSpaceVisibility(visibilityForm) if ('error' in result && result.error) { setMessage({ type: 'error', text: result.error }) } else { setMessage({ type: 'success', text: 'Visibility updated.' }) } setSaving(false) } return ( <> {/* Space Settings */}

Space Settings

setSpaceForm(f => ({ ...f, name: e.target.value }))} disabled={!isAdmin} className="w-full bg-background border border-border rounded px-3 py-2 font-sans text-sm text-foreground disabled:opacity-50 focus:outline-none focus:border-primary" />
hackerspace.sh/ setSpaceForm(f => ({ ...f, slug: e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, '') }))} disabled={!isAdmin} className="flex-1 bg-background border border-border rounded px-3 py-2 font-mono text-sm text-foreground disabled:opacity-50 focus:outline-none focus:border-primary" />
setSpaceForm(f => ({ ...f, city: e.target.value }))} placeholder="Mesa, AZ" disabled={!isAdmin} className="w-full max-w-md bg-background border border-border rounded px-3 py-2 font-sans text-sm text-foreground placeholder:text-muted-foreground disabled:opacity-50 focus:outline-none focus:border-primary" />

Require approval to join

New members must be approved by an admin

Public member directory

Anyone can see member list (names only)