diff --git a/src/views/Modals/Inputs/ProjectModal.jsx b/src/views/Modals/Inputs/ProjectModal.jsx new file mode 100644 index 0000000..ffbb562 --- /dev/null +++ b/src/views/Modals/Inputs/ProjectModal.jsx @@ -0,0 +1,367 @@ +import { + Avatar, + Box, + Button, + FormControl, + FormLabel, + Grid, + Input, + Stack, + Textarea, + Typography, +} from '@mui/joy' +import { useEffect, useState } from 'react' +import { useResponsiveModal } from '../../../hooks/useResponsiveModal' +import LABEL_COLORS, { + getTextColorFromBackgroundColor, +} from '../../../utils/Colors' +import { CreateProject, UpdateProject } from '../../../utils/Fetcher' +import PROJECT_ICONS, { getIconComponent } from '../../../utils/ProjectIcons' + +const ProjectModal = ({ isOpen, onClose, onSave, project }) => { + const { ResponsiveModal } = useResponsiveModal() + const [projectName, setProjectName] = useState('') + const [projectDescription, setProjectDescription] = useState('') + const [projectColor, setProjectColor] = useState(LABEL_COLORS[0].value) + const [projectIcon, setProjectIcon] = useState(PROJECT_ICONS[0].value) + const [isSubmitting, setIsSubmitting] = useState(false) + const [error, setError] = useState('') + + // Initialize form when modal opens or project changes + useEffect(() => { + if (isOpen) { + if (project) { + // Editing existing project + setProjectName(project.name || '') + setProjectDescription(project.description || '') + setProjectColor(project.color || LABEL_COLORS[0].value) + setProjectIcon(project.icon || PROJECT_ICONS[0].value) + } else { + // Creating new project + setProjectName('') + setProjectDescription('') + setProjectColor(LABEL_COLORS[0].value) + setProjectIcon(PROJECT_ICONS[0].value) + } + setError('') + setIsSubmitting(false) + } + }, [isOpen, project]) + + const handleSubmit = async e => { + e.preventDefault() + + if (!projectName.trim()) { + setError('Project name is required') + return + } + + setIsSubmitting(true) + setError('') + + try { + const projectData = { + name: projectName.trim(), + description: projectDescription.trim(), + color: projectColor, + icon: projectIcon, + } + + let response + if (project) { + // Update existing project + response = await UpdateProject(project.id, projectData) + } else { + // Create new project + response = await CreateProject(projectData) + } + + if (response.ok) { + const savedProject = await response.json() + onSave(savedProject.res || savedProject) + onClose() + } else { + const errorData = await response.json() + setError(errorData.message || 'Failed to save project') + } + } catch (error) { + console.error('Error saving project:', error) + setError('An unexpected error occurred') + } finally { + setIsSubmitting(false) + } + } + + const handleClose = () => { + if (!isSubmitting) { + onClose() + } + } + + return ( + + + {project ? 'Edit Project' : 'Create New Project'} + + +
+ + {/* Project Name */} + + Project Name + setProjectName(e.target.value)} + placeholder='Enter project name...' + autoFocus + disabled={isSubmitting} + /> + + + {/* Project Description */} + + Description +