'use client' /** * ProjectForm Component * * Client component for creating new Supabase projects. * Handles form validation, submission, and loading states. */ import { useState } from 'react' import { useRouter } from 'next/navigation' import { createProject, type CreateProjectInput } from '@/app/actions/projects' import CreatingProjectModal from './CreatingProjectModal' const REGIONS = [ { value: 'us-east-1', label: 'US East (N. Virginia)' }, { value: 'us-west-1', label: 'US West (N. California)' }, { value: 'us-west-2', label: 'US West (Oregon)' }, { value: 'eu-west-1', label: 'EU West (Ireland)' }, { value: 'eu-west-2', label: 'EU West (London)' }, { value: 'eu-central-1', label: 'EU Central (Frankfurt)' }, { value: 'ap-southeast-1', label: 'Asia Pacific (Singapore)' }, { value: 'ap-southeast-2', label: 'Asia Pacific (Sydney)' }, { value: 'ap-northeast-1', label: 'Asia Pacific (Tokyo)' }, { value: 'sa-east-1', label: 'South America (São Paulo)' }, ] interface ProjectFormProps { defaultOrganizationId?: string defaultRegion?: string } export default function ProjectForm({ defaultOrganizationId, defaultRegion }: ProjectFormProps) { const router = useRouter() const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState(null) const [errorDetails, setErrorDetails] = useState(null) const [showErrorDetails, setShowErrorDetails] = useState(false) const [formData, setFormData] = useState({ project_name: '', organization_id: defaultOrganizationId || '', region: defaultRegion || 'us-east-1', purpose: '', description: '', }) const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setError(null) setErrorDetails(null) setShowErrorDetails(false) setIsSubmitting(true) try { // Client-side validation if (formData.project_name.length < 3) { setError('Project name must be at least 3 characters') setIsSubmitting(false) return } if (!formData.organization_id) { setError('Organization ID is required') setIsSubmitting(false) return } console.log('[ProjectForm] Submitting project creation request:', { project_name: formData.project_name, organization_id: formData.organization_id, region: formData.region, timestamp: new Date().toISOString(), }) // Call server action const result = await createProject(formData) console.log('[ProjectForm] Received response from server action:', { success: result.success, hasError: !!result.error, hasErrorDetails: !!result.errorDetails, timestamp: new Date().toISOString(), }) if (!result.success) { const errorMessage = result.error || 'Failed to create project' setError(errorMessage) if (result.errorDetails && Object.keys(result.errorDetails).length > 0) { setErrorDetails(result.errorDetails) console.error('[ProjectForm] Error details:', result.errorDetails) } else { console.error('[ProjectForm] Error:', errorMessage) } setIsSubmitting(false) return } // Success - redirect to projects page console.log('[ProjectForm] Project created successfully, redirecting to projects page...') console.log('[ProjectForm] Project data:', result.data) // Keep spinner showing briefly then redirect setTimeout(() => { router.push('/projects') router.refresh() }, 2000) } catch (err) { console.error('[ProjectForm] Unexpected error during submission:', err) setError(err instanceof Error ? err.message : 'An unexpected error occurred') setErrorDetails({ unexpectedError: true, message: String(err) }) setIsSubmitting(false) } } const handleInputChange = ( e: React.ChangeEvent ) => { const { name, value } = e.target setFormData((prev) => ({ ...prev, [name]: value })) } return ( <> {/* Creating Project Modal */} {isSubmitting && }
{/* Error Display */} {error && (

Error

{error}

{/* Technical Details */} {errorDetails && (
{showErrorDetails && (
{errorDetails.statusCode && (
HTTP Status: {errorDetails.statusCode}{' '} {errorDetails.statusText}
)} {errorDetails.requestUrl && (
Request URL: {errorDetails.requestUrl}
)} {errorDetails.responseBody && (
Response:
                          {typeof errorDetails.responseBody === 'string'
                            ? errorDetails.responseBody
                            : JSON.stringify(errorDetails.responseBody, null, 2)}
                        
)}

Debugging Tips:

  • Check browser console (F12) for detailed logs
  • Check Supabase Edge Function logs in dashboard
  • Verify your authentication token is valid
  • {errorDetails.statusCode === 429 && (
  • Rate limit exceeded. Wait before creating more projects.
  • )} {errorDetails.statusCode === 401 && (
  • Authentication failed. Try logging out and back in.
  • )} {errorDetails.statusCode >= 500 && (
  • Server error. Check Edge Function logs for details.
  • )}
)}
)}
)} {/* Project Name */}

3-63 characters, lowercase letters, numbers, and hyphens

{/* Hidden fields - automatically set */} {/* Purpose */}

What will this project be used for?

{/* Description */}