Add project name not empty validation and error

This commit is contained in:
Chris Veleris 2025-07-04 14:19:11 +03:00
parent 0f882adef2
commit 1e63cb2ff2
7 changed files with 41 additions and 8 deletions

View file

@ -54,8 +54,9 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
const fileInputRef = useRef<HTMLInputElement>(null);
const [isClosing, setIsClosing] = useState(false);
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
const [error, setError] = useState<string | null>(null);
const { showSuccessToast } = useToast();
const { showSuccessToast, showErrorToast } = useToast();
const { t } = useTranslation();
useEffect(() => {
@ -83,6 +84,7 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
setImagePreview("");
}
setImageFile(null);
setError(null);
}, [project]);
useEffect(() => {
@ -125,6 +127,11 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
const target = e.target;
const { name, type, value } = target;
// Clear error when user starts typing in the name field
if (name === 'name' && error) {
setError(null);
}
if (type === "checkbox") {
if (target instanceof HTMLInputElement) {
const checked = target.checked;
@ -204,6 +211,12 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
};
const handleSubmit = async () => {
// Validate required fields
if (!formData.name.trim()) {
setError(t('errors.projectNameRequired', 'Project name is required'));
return;
}
try {
let imageUrl = formData.image_url;
@ -233,6 +246,7 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
handleClose();
} catch (error) {
console.error('Error saving project:', error);
setError(t('errors.projectSaveFailed', 'Failed to save project'));
}
};
@ -295,9 +309,16 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
value={formData.name}
onChange={handleChange}
required
className="block w-full text-xl font-semibold dark:bg-gray-800 text-black dark:text-white border-b-2 border-gray-200 dark:border-gray-900 focus:outline-none shadow-sm py-2"
className={`block w-full text-xl font-semibold dark:bg-gray-800 text-black dark:text-white border-b-2 ${
error ? 'border-red-500' : 'border-gray-200 dark:border-gray-900'
} focus:outline-none shadow-sm py-2`}
placeholder={t('project.name', 'Enter project name')}
/>
{error && (
<div className="mt-2 text-red-500 text-sm font-medium">
{error}
</div>
)}
</div>
<div className="pb-3">

View file

@ -126,7 +126,9 @@
"noteTitleRequired": "Notiz-Titel ist erforderlich.",
"failedToLoadTags": "Fehler beim Laden der verfügbaren Tags.",
"failedToSaveNote": "Fehler beim Speichern der Notiz.",
"projectCreationFailed": "Projekt konnte nicht erstellt werden."
"projectCreationFailed": "Projekt konnte nicht erstellt werden.",
"projectNameRequired": "Projektname ist erforderlich.",
"projectSaveFailed": "Projekt konnte nicht gespeichert werden."
},
"success": {
"noteUpdated": "Notiz erfolgreich aktualisiert!",

View file

@ -197,7 +197,9 @@
"failedToSaveTag": "Αποτυχία αποθήκευσης ετικέτας.",
"areaNameRequired": "Το όνομα περιοχής είναι υποχρεωτικό.",
"failedToSaveArea": "Αποτυχία αποθήκευσης περιοχής.",
"projectCreationFailed": "Αποτυχία δημιουργίας έργου."
"projectCreationFailed": "Αποτυχία δημιουργίας έργου.",
"projectNameRequired": "Το όνομα έργου είναι υποχρεωτικό.",
"projectSaveFailed": "Αποτυχία αποθήκευσης έργου."
},
"dropdown": {
"createNew": "Δημιουργία Νέου",

View file

@ -444,7 +444,9 @@
"areaNameRequired": "Area name is required.",
"failedToSaveArea": "Failed to save area.",
"tagNameRequired": "Tag name is required.",
"failedToSaveTag": "Failed to save tag."
"failedToSaveTag": "Failed to save tag.",
"projectNameRequired": "Project name is required.",
"projectSaveFailed": "Failed to save project."
},
"inbox": {
"title": "Inbox",

View file

@ -158,7 +158,9 @@
"noteTitleRequired": "El título de la nota es obligatorio.",
"failedToLoadTags": "Error al cargar las etiquetas disponibles.",
"failedToSaveNote": "Error al guardar la nota.",
"projectCreationFailed": "Error al crear el proyecto."
"projectCreationFailed": "Error al crear el proyecto.",
"projectNameRequired": "El nombre del proyecto es obligatorio.",
"projectSaveFailed": "Error al guardar el proyecto."
},
"dropdown": {
"createNew": "Crear Nuevo",

View file

@ -227,7 +227,9 @@
"noteTitleRequired": "ノートのタイトルは必須です。",
"failedToLoadTags": "利用可能なタグの読み込みに失敗しました。",
"failedToSaveNote": "ノートの保存に失敗しました。",
"projectCreationFailed": "プロジェクトの作成に失敗しました。"
"projectCreationFailed": "プロジェクトの作成に失敗しました。",
"projectNameRequired": "プロジェクト名は必須です。",
"projectSaveFailed": "プロジェクトの保存に失敗しました。"
},
"success": {
"noteUpdated": "ノートが正常に更新されました!",

View file

@ -173,7 +173,9 @@
"noteTitleRequired": "Заголовок нотатки обов'язковий.",
"failedToLoadTags": "Не вдалося завантажити доступні теги.",
"failedToSaveNote": "Не вдалося зберегти нотатку.",
"projectCreationFailed": "Не вдалося створити проект."
"projectCreationFailed": "Не вдалося створити проект.",
"projectNameRequired": "Назва проекту обов'язкова.",
"projectSaveFailed": "Не вдалося зберегти проект."
},
"success": {