'use client' import { useState, useEffect, useRef, useCallback } from 'react' import { useRouter } from 'next/navigation' import { Input, Button, toast } from '@ciphera-net/ui' import { Spinner } from '@ciphera-net/ui' import { useAuth } from '@/lib/auth/context' import { getOrganization, updateOrganization, deleteOrganization } from '@/lib/api/organization' import { getAuthErrorMessage } from '@ciphera-net/ui' import { useUnifiedSettings } from '@/lib/unified-settings-context' export default function WorkspaceGeneralTab({ onDirtyChange, onRegisterSave }: { onDirtyChange?: (dirty: boolean) => void; onRegisterSave?: (fn: () => Promise) => void }) { const { user } = useAuth() const router = useRouter() const { closeUnifiedSettings } = useUnifiedSettings() const [name, setName] = useState('') const [slug, setSlug] = useState('') const [loading, setLoading] = useState(true) const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) const [deleteText, setDeleteText] = useState('') const [deleting, setDeleting] = useState(false) const initialRef = useRef('') const hasInitialized = useRef(false) useEffect(() => { if (!user?.org_id) return setLoading(true) getOrganization(user.org_id) .then(org => { setName(org.name || '') setSlug(org.slug || '') if (!hasInitialized.current) { initialRef.current = JSON.stringify({ name: org.name || '', slug: org.slug || '' }) hasInitialized.current = true } }) .catch(() => {}) .finally(() => setLoading(false)) }, [user?.org_id]) // Track dirty state useEffect(() => { if (!initialRef.current) return onDirtyChange?.(JSON.stringify({ name, slug }) !== initialRef.current) }, [name, slug, onDirtyChange]) const handleSave = useCallback(async () => { if (!user?.org_id) return try { await updateOrganization(user.org_id, name, slug) initialRef.current = JSON.stringify({ name, slug }) onDirtyChange?.(false) toast.success('Organization updated') } catch (err) { toast.error(getAuthErrorMessage(err as Error) || 'Failed to update organization') } }, [user?.org_id, name, slug, onDirtyChange]) useEffect(() => { onRegisterSave?.(handleSave) }, [handleSave, onRegisterSave]) const handleDelete = async () => { if (!user?.org_id || deleteText !== 'DELETE') return setDeleting(true) try { await deleteOrganization(user.org_id) localStorage.clear() closeUnifiedSettings() router.push('/') } catch (err) { toast.error(getAuthErrorMessage(err as Error) || 'Failed to delete organization') setDeleting(false) } } if (loading) { return (
) } return (

General Information

Basic details about your organization.

setName(e.target.value)} placeholder="Acme Corp" />
pulse.ciphera.net/ setSlug(e.target.value)} placeholder="acme-corp" />

Changing the slug will change your organization's URL.

{/* Danger Zone */}

Danger Zone

Delete Organization

Permanently delete this organization and all its data.

{showDeleteConfirm && (

This will permanently delete:

  • All sites and their analytics data
  • All team members and pending invitations
  • Active subscription will be cancelled
  • All notifications and settings
setDeleteText(e.target.value)} className="w-full px-3 py-2 border border-neutral-700 rounded-lg bg-neutral-900 text-white text-sm" placeholder="DELETE" />
)}
) }