diff --git a/client/src/scss/_modalForm.scss b/client/src/scss/_modalForm.scss
new file mode 100644
index 000000000..f6ee8c374
--- /dev/null
+++ b/client/src/scss/_modalForm.scss
@@ -0,0 +1,14 @@
+form {
+ input.form-control:invalid {
+ background-color: #fdd;
+ }
+ button.form-btn-full-width {
+ width: 91.2%;
+ }
+ div.form-floating-img-container {
+ top: -250%;
+ left: 30%;
+ max-width: 50%;
+ z-index: 5;
+ }
+}
diff --git a/client/src/scss/style.scss b/client/src/scss/style.scss
index 7221260ed..2f63eb394 100644
--- a/client/src/scss/style.scss
+++ b/client/src/scss/style.scss
@@ -23,3 +23,4 @@ $enable-rtl: true;
@import 'outLanding.scss';
@import 'register.scss';
@import 'auth-register.scss';
+@import 'modalForm.scss';
diff --git a/client/src/views/out/home/history/Editor.js b/client/src/views/out/home/history/Editor.js
index 9975fbc5b..351814a54 100644
--- a/client/src/views/out/home/history/Editor.js
+++ b/client/src/views/out/home/history/Editor.js
@@ -1,25 +1,29 @@
+import CIcon from '@coreui/icons-react'
import {
- CModal,
- CModalBody,
- CModalHeader,
- CModalFooter,
- CModalTitle,
CButton,
CForm,
+ CImage,
CInputGroup,
- CFormControl,
CInputGroupText,
- CImage,
+ CModal,
+ CModalBody,
+ CModalFooter,
+ CModalHeader,
+ CModalTitle,
} from '@coreui/react'
-import ReactTooltip from 'react-tooltip'
-import CIcon from '@coreui/icons-react'
-import React, { Fragment, useState } from 'react'
-import PropTypes from 'prop-types'
import axios from 'axios'
+import PropTypes from 'prop-types'
+import React, { Fragment, useRef, useState } from 'react'
+import ReactTooltip from 'react-tooltip'
const Editor = ({ visible, setVisible, add, dataForm, setDataForm, refetch }) => {
- const [imgPreview, setImgPreview] = useState(dataForm.people.slice().fill(false))
+ const [imgPreview, setImgPreview] = useState(new Array(dataForm.people.length).fill(false))
const [pending, setPending] = useState(false)
+ const formRef = useRef(null)
+ const preventDefaultAndFocus = (e) => {
+ e.preventDefault()
+ e.target.focus()
+ }
const handleEnterImgIcon = (index) => {
const result = imgPreview.slice()
result[index] = true
@@ -60,6 +64,9 @@ const Editor = ({ visible, setVisible, add, dataForm, setDataForm, refetch }) =>
reader.readAsDataURL(file)
}
const handleSubmit = async () => {
+ // prevent the form from submitting if the form is invalid
+ if (!formRef.current.reportValidity()) return
+
setPending(true)
const data = new FormData()
data.append('grade', dataForm.grade)
@@ -108,19 +115,24 @@ const Editor = ({ visible, setVisible, add, dataForm, setDataForm, refetch }) =>
{add ? 'Add a year' : 'Edit this year'}
-
+
-
@@ -128,14 +140,18 @@ const Editor = ({ visible, setVisible, add, dataForm, setDataForm, refetch }) =>
-
@@ -146,14 +162,17 @@ const Editor = ({ visible, setVisible, add, dataForm, setDataForm, refetch }) =>
- handlePeopleChange(e, index)}
disabled={pending}
+ onInvalid={preventDefaultAndFocus}
/>
onMouseLeave={() => handleLeaveImgIcon(index)}
/>
- handleChangeImage(e, index)}
onClick={(e) => (e.target.value = null)}
disabled={pending}
- >
+ className="form-control"
+ data-for="image"
+ data-tip="Put a picture"
+ accept="image/png, image/jpeg, image/jpg, image/webp, image/avif"
+ required={dataForm.people[index].img === null}
+ onInvalid={preventDefaultAndFocus}
+ />
@@ -206,9 +222,8 @@ const Editor = ({ visible, setVisible, add, dataForm, setDataForm, refetch }) =>
+