import { useState, useEffect, useCallback } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Project } from '../types'; import { getProject, updateProject, deleteProject, getMyProjectAccess, UnauthorizedError, ForbiddenError, } from '../api'; import { Breadcrumb } from '../components/Breadcrumb'; import { AccessManagement } from '../components/AccessManagement'; import { useAuth } from '../contexts/AuthContext'; import './ProjectSettingsPage.css'; function ProjectSettingsPage() { const { projectName } = useParams<{ projectName: string }>(); const navigate = useNavigate(); const { user } = useAuth(); const [project, setProject] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [success, setSuccess] = useState(null); const [accessDenied, setAccessDenied] = useState(false); const [canAdmin, setCanAdmin] = useState(false); // General settings form state const [description, setDescription] = useState(''); const [isPublic, setIsPublic] = useState(false); const [saving, setSaving] = useState(false); // Delete confirmation state const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [deleteConfirmText, setDeleteConfirmText] = useState(''); const [deleting, setDeleting] = useState(false); const loadData = useCallback(async () => { if (!projectName) return; try { setLoading(true); setAccessDenied(false); const [projectData, accessResult] = await Promise.all([ getProject(projectName), getMyProjectAccess(projectName), ]); setProject(projectData); setDescription(projectData.description || ''); setIsPublic(projectData.is_public); const hasAdminAccess = accessResult.access_level === 'admin'; setCanAdmin(hasAdminAccess); if (!hasAdminAccess) { setAccessDenied(true); } setError(null); } catch (err) { if (err instanceof UnauthorizedError) { navigate('/login', { state: { from: `/project/${projectName}/settings` } }); return; } if (err instanceof ForbiddenError) { setAccessDenied(true); setLoading(false); return; } setError(err instanceof Error ? err.message : 'Failed to load project'); } finally { setLoading(false); } }, [projectName, navigate]); useEffect(() => { loadData(); }, [loadData]); const handleSaveSettings = async (e: React.FormEvent) => { e.preventDefault(); if (!projectName) return; try { setSaving(true); setError(null); const updatedProject = await updateProject(projectName, { description: description || undefined, is_public: isPublic, }); setProject(updatedProject); setSuccess('Settings saved successfully'); setTimeout(() => setSuccess(null), 3000); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to save settings'); } finally { setSaving(false); } }; const handleDeleteProject = async () => { if (!projectName || deleteConfirmText !== projectName) return; try { setDeleting(true); setError(null); await deleteProject(projectName); navigate('/'); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to delete project'); setDeleting(false); } }; const handleCancelDelete = () => { setShowDeleteConfirm(false); setDeleteConfirmText(''); }; if (loading) { return (
Loading...
); } if (accessDenied || !canAdmin) { return (

Access Denied

You must be a project admin to access settings.

{!user && (

Sign in

)}
); } if (!project) { return (
Project not found
); } return (

Project Settings

Manage settings for {project.name}

{error &&
{error}
} {success &&
{success}
} {/* General Settings Section */}

General