feat:update

This commit is contained in:
TuanVT 2026-06-11 11:25:47 +07:00
parent b4568e1c8c
commit 42cb08f0d0
14 changed files with 361 additions and 89 deletions

View File

@ -108,6 +108,45 @@ export function getTextAddress(detailAddress: any, address?: string): string {
return parts.length ? parts.join(", ") : "---";
}
export const formatDateOfBirth = (value: string) => {
const digits = value.replace(/\D/g, "").slice(0, 8);
if (digits.length <= 2) return digits;
if (digits.length <= 4) return `${digits.slice(0, 2)}/${digits.slice(2)}`;
return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/${digits.slice(4)}`;
};
export const parseDateOfBirth = (value: string) => {
const match = value.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
if (!match) return null;
const day = Number(match[1]);
const month = Number(match[2]);
const year = Number(match[3]);
const parsedDate = new Date(year, month - 1, day);
if (
parsedDate.getFullYear() !== year ||
parsedDate.getMonth() !== month - 1 ||
parsedDate.getDate() !== day
) {
return null;
}
return parsedDate;
};
export const formatToISODate = (date: Date | null): string => {
if (!date) return "";
const year = date.getFullYear();
// Đảm bảo tháng và ngày luôn có 2 chữ số (VD: 02, 12)
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`; // Kết quả: "2001-02-12"
};
export function numberToWords(number: number) {
if (typeof number !== "number" || isNaN(number)) {
return "Không hợp lệ";

View File

@ -78,6 +78,11 @@ export default function MainLogin() {
// Kiểm tra nhanh điều kiện dữ liệu trước khi trigger API
if (!form.username || !form.password) return;
// if (form.password.length < 6) {
// alert("Mật khẩu phải có ít nhất 6 ký tự");
// return;
// }
if (isRememberPassword) {
store.dispatch(
setDataLoginStorage({
@ -136,6 +141,7 @@ export default function MainLogin() {
onClean
isRequired
isBlur
min={6}
showDone
icon={<ShieldPlus size={22} />}
/>

View File

@ -154,6 +154,7 @@ export default function MainRegister() {
onClean
isRequired
isBlur
min={6}
showDone
icon={<ShieldPlus size={22} />}
/>

View File

@ -1,26 +1,16 @@
"use client";
import React, { useMemo, useState } from "react";
import { X } from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import FormCustom from "@/components/utils/FormCustom/FormCustom";
import SelectForm from "@/components/utils/FormCustom/components/SelectForm";
import { httpRequest } from "@/services";
import consultationServices from "@/services/consultationServices";
import patientServices, {
PatientItem,
PatientResponse,
} from "@/services/patientServices";
import { QUERY_KEY } from "@/constant/config/enum";
import CustomButton from "@/components/customs/custom-button";
import { useRouter, useSearchParams } from "next/navigation";
import InputForm from "@/components/utils/FormCustom/components/InputForm";
@ -137,6 +127,9 @@ const CreateConsultation = () => {
if (!form?.patientId) {
return toastWarn({ msg: "Vui lòng chọn bệnh nhân" });
}
if (!form?.specialtyIds) {
return toastWarn({ msg: "Vui lòng chọn chuyên khoa" });
}
createConsultationMutation.mutate();
};
@ -174,7 +167,7 @@ const CreateConsultation = () => {
<div className="space-y-5 mb-2">
<SelectForm
label={
<span className="text-[14px] font-medium text-[#374151]">
<span>
Bệnh nhân
<span className="text-red-500">*</span>
</span>
@ -205,7 +198,11 @@ const CreateConsultation = () => {
<div className="space-y-5 mb-2">
<GridColumn col={3}>
<InputForm
label="Lý do khám"
label={
<span>
do khám <span className="text-red-500">*</span>
</span>
}
name="chiefComplaint"
type="text"
value={form.chiefComplaint}
@ -217,7 +214,11 @@ const CreateConsultation = () => {
/>
<InputForm
type="text"
label="Triệu chứng"
label={
<span>
Triệu chứng <span className="text-red-500">*</span>
</span>
}
name="symptomsText"
placeholder="Nhập triệu chứng"
isRequired
@ -229,7 +230,12 @@ const CreateConsultation = () => {
<InputForm
type="text"
label="Chỉ số huyết áp, chỉ số mạch"
label={
<span>
Chỉ số huyết áp, chỉ số mạch{" "}
<span className="text-red-500">*</span>
</span>
}
name="vitalSigns"
placeholder="Nhập chỉ số huyết áp, chỉ số mạch"
value={form.vitalSigns}
@ -242,7 +248,12 @@ const CreateConsultation = () => {
</div>
<div className="space-y-5 mb2">
<SelectMany<SpecialtyItem>
label="Chuyên khoa"
label={
<span>
Chuyên khoa
<span className="text-red-500">*</span>
</span>
}
text="chuyên khoa"
title="Chọn chuyên khoa"
placeholder="Chọn nhiều chuyên khoa..."

View File

@ -575,26 +575,34 @@ const DetailConsultation = () => {
<GridColumn col={3}>
<div>
<p className="text-sm text-[#697586]">CHUYÊN KHOA</p>
<p>{selectedSpecialty.specialtyName || "---"}</p>
{/* Thêm class để bọc text */}
<p className="break-words overflow-hidden">
{selectedSpecialty.specialtyName || "---"}
</p>
</div>
<div>
<p className="text-sm text-[#697586]">CHẨN ĐOÁN</p>
<p>{selectedSpecialty.diagnosis || "---"}</p>
{/* Thêm class để bọc text */}
<p className="break-words overflow-hidden">
{selectedSpecialty.diagnosis || "---"}
</p>
</div>
<div>
<p className="text-sm text-[#697586]">GHI CHÚ KHÁM</p>
<p>{selectedSpecialty.specialtyNotes || "---"}</p>
{/* Thêm class để bọc text */}
<p className="break-words overflow-hidden">
{selectedSpecialty.specialtyNotes || "---"}
</p>
</div>
<div>
<p className="text-sm text-[#697586]">THỦ THUẬT</p>
<p>{selectedSpecialty.procedureNotes || "---"}</p>
{/* Thêm class để bọc text */}
<p className="break-words overflow-hidden">
{selectedSpecialty.procedureNotes || "---"}
</p>
</div>
<div className="space-y-1">

View File

@ -352,7 +352,7 @@ const MainPageConsultation = () => {
},
{
uuid: TYPE_STATUS.PendingPrescription,
name: "Chờ nhận thuốc/kính",
name: "Chờ nhận thuốc",
},
{
uuid: TYPE_STATUS.Completed,

View File

@ -18,6 +18,7 @@ import consultationServices, {
import uploadServices from "@/services/uploadServices";
import UploadMultipleFile from "@/components/utils/UploadMultipleFile";
import TextArea from "@/components/utils/FormCustom/components/TextArea";
import { toastWarn } from "@/common/funcs/toast";
/* =========================
TYPES
@ -247,7 +248,11 @@ const UpdateConsultation = () => {
{/* GENERAL INFO (PATIENT) */}
<InputForm
label="Bệnh nhân"
label={
<span>
Bệnh nhân <span className="text-red-500">*</span>
</span>
}
name="patientInfo"
type="text"
// Hiển thị Tên bệnh nhân - SĐT hoặc CCCD dựa trên API detail trả về
@ -268,7 +273,11 @@ const UpdateConsultation = () => {
<GridColumn col={3}>
<InputForm
label="Lý do khám"
label={
<span>
do khám <span className="text-red-500">*</span>
</span>
}
name="chiefComplaint"
type="text"
value={form.chiefComplaint}
@ -280,7 +289,11 @@ const UpdateConsultation = () => {
/>
<InputForm
type="text"
label="Triệu chứng"
label={
<span>
Triệu chứng <span className="text-red-500">*</span>
</span>
}
name="symptomsText"
placeholder="Nhập triệu chứng"
isRequired
@ -292,7 +305,12 @@ const UpdateConsultation = () => {
<InputForm
type="text"
label="Chỉ số huyết áp, chỉ số mạch"
label={
<span>
Chỉ số huyết áp, chỉ số mạch{" "}
<span className="text-red-500">*</span>
</span>
}
name="vitalSigns"
placeholder="Nhập chỉ số huyết áp, chỉ số mạch"
value={form.vitalSigns}
@ -304,7 +322,11 @@ const UpdateConsultation = () => {
<InputForm
type="text"
label="Chẩn đoán"
label={
<span>
Chẩn đoán <span className="text-red-500">*</span>
</span>
}
name="diagnosis"
placeholder="Nhập chẩn đoán"
value={form.diagnosis}
@ -316,7 +338,11 @@ const UpdateConsultation = () => {
<InputForm
type="text"
label="Kế hoạch điều trị"
label={
<span>
Kế hoạch điều trị <span className="text-red-500">*</span>
</span>
}
name="treatmentPlan"
placeholder="Nhập kế hoạch điều trị"
value={form.treatmentPlan}
@ -328,7 +354,11 @@ const UpdateConsultation = () => {
<InputForm
type="text"
label="Ghi chú bác sĩ"
label={
<span>
Ghi chú bác <span className="text-red-500">*</span>
</span>
}
name="doctorNotes"
placeholder="Nhập ghi chú"
value={form.doctorNotes}
@ -372,7 +402,12 @@ const UpdateConsultation = () => {
<TextArea
name="glassType"
placeholder="Nhập thông số chi tiết loại kính được chỉ định"
label="Thông số / Loại kính chỉ định"
label={
<span>
Thông số / loại kính chỉ đnh
<span className="text-red-500">*</span>
</span>
}
value={form.glassType}
isRequired
readOnly
@ -408,10 +443,18 @@ const UpdateConsultation = () => {
Hủy bỏ
</CustomButton>
<CustomButton
type="submit"
onClick={handleSubmit}
variant="midnightBlue"
rounded="md"
disabled={isLoading || !id || id === "undefined"}
disabled={
!form.chiefComplaint ||
!form.symptomsText ||
!form.vitalSigns ||
!form.diagnosis ||
!form.treatmentPlan ||
!form.doctorNotes ||
updateConsultationMutation.isPending
}
className="min-w-[140px]"
>
{updateConsultationMutation.isPending

View File

@ -1,5 +1,6 @@
"use client";
import { toastWarn } from "@/common/funcs/toast";
import CustomButton from "@/components/customs/custom-button";
import GridColumn from "@/components/layouts/GridColumn";
import FormCustom from "@/components/utils/FormCustom";
@ -170,6 +171,16 @@ const UpdateSpecialtyClinicId = () => {
});
const handleSubmit = async () => {
if (!form.specialtyNotes || !form.diagnosis || !form.procedureNotes) {
return toastWarn({ msg: "Vui lòng nhập đầy đủ các trường!" });
}
if (isEyeClinic && form.glassRequired === true && !form.glassType) {
return toastWarn({
msg: "Vui lòng nhập thông số / Loại kính chỉ định!",
});
}
try {
const currentImage = images
.filter((item) => !!item.img)
@ -277,7 +288,12 @@ const UpdateSpecialtyClinicId = () => {
<GridColumn col={isEyeClinic ? 4 : 3}>
<InputForm
label="Ghi chú chuyên khoa"
label={
<span>
Ghi chú chuyên khoa
<span className="text-red-500">*</span>
</span>
}
name="specialtyNotes"
type="text"
value={form.specialtyNotes}
@ -289,7 +305,12 @@ const UpdateSpecialtyClinicId = () => {
/>
<InputForm
type="text"
label="Chẩn đoán chuyên khoa"
label={
<span>
Chẩn đoán chuyên khoa
<span className="text-red-500">*</span>
</span>
}
name="diagnosis"
placeholder="Nhập chẩn đoán chuyên khoa"
isRequired
@ -300,7 +321,12 @@ const UpdateSpecialtyClinicId = () => {
/>
<InputForm
type="text"
label="Ghi chú thủ thuật / can thiệp"
label={
<span>
Ghi chú thủ thuật / can thiệp
<span className="text-red-500">*</span>
</span>
}
name="procedureNotes"
placeholder="Nhập ghi chú thủ thuật / can thiệp"
value={form.procedureNotes}
@ -359,7 +385,12 @@ const UpdateSpecialtyClinicId = () => {
<TextArea
name="glassType"
placeholder="Nhập thông số chi tiết loại kính được chỉ định (Cận, viễn, loạn, độ kính...)"
label="Thông số / Loại kính chỉ định"
label={
<span>
Thông số / Loại kính chỉ đnh
<span className="text-red-500">*</span>
</span>
}
value={form.glassType}
isRequired
isBlur
@ -432,10 +463,10 @@ const UpdateSpecialtyClinicId = () => {
Hủy bỏ
</CustomButton>
<CustomButton
type="submit"
onClick={handleSubmit}
variant="midnightBlue"
rounded="md"
disabled={isLoading || !consultationId}
disabled={specialtyResultsMutation.isPending}
className="min-w-[140px]"
>
{specialtyResultsMutation.isPending

View File

@ -225,7 +225,7 @@ const MainPagePatient = () => {
<Search
keyword={_keyword ?? ""}
setKeyword={(value) => updateQuery("_keyword", value)}
placeholder="Tìm kiếm theo tên người dùng, ID"
placeholder="Tìm kiếm theo tên bệnh nhân, ID"
/>
</div>
</div>

View File

@ -15,7 +15,11 @@ import { httpRequest } from "@/services";
import patientServices from "@/services/patientServices";
import { toastWarn } from "@/common/funcs/toast";
import { timeSubmit } from "@/common/funcs/optionConvert";
import {
formatDateOfBirth,
parseDateOfBirth,
formatToISODate,
} from "@/common/funcs/optionConvert";
export interface ICreatePatient {
identificationNumber: string;
@ -31,11 +35,6 @@ export interface PropsPopupCreatePatient {
onClose: () => void;
}
/* QUERY KEY */
// export const QUERY_KEY = {
// table_list_patient: "table_list_patient",
// };
const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
const queryClient = useQueryClient();
@ -59,7 +58,8 @@ const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
http: patientServices.createPatient({
identificationNumber: form.identificationNumber,
fullName: form.fullName,
dateOfBirth: form.dateOfBirth,
dateOfBirth:
formatToISODate(parseDateOfBirth(form.dateOfBirth)) || "",
gender: form.gender,
phone: form.phone,
email: form.email,
@ -68,6 +68,14 @@ const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
});
},
onError(error: any) {
// Lấy message lỗi từ backend trả về
const message = error?.response?.data?.error?.message || error?.message;
// Bật thông báo Toast dạng cảnh báo
toastWarn({ msg: message });
},
onSuccess() {
/* REFRESH LIST */
queryClient.invalidateQueries({
@ -79,15 +87,30 @@ const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
});
const handleSubmit = () => {
if (!form.dateOfBirth) {
return toastWarn({ msg: "Vui lòng nhập ngày sinh!" });
}
const today = new Date();
today.setHours(0, 0, 0, 0);
const birthDay = parseDateOfBirth(form.dateOfBirth);
if (!birthDay) {
return toastWarn({
msg: "Ngày sinh phải theo định dạng ngày/tháng/năm!",
});
}
birthDay.setHours(0, 0, 0, 0);
if (birthDay.getTime() > today.getTime()) {
return toastWarn({ msg: "Ngày sinh không hợp lệ!" });
}
if (!form.gender) {
return toastWarn({ msg: "Vui lòng chọn giới tính!" });
}
const today = new Date(timeSubmit(new Date())!);
const birthDay = new Date(form.dateOfBirth);
if (today < birthDay) {
return toastWarn({ msg: "Ngày sinh không hợp lệ!" });
}
createPatientMutation.mutate();
};
@ -116,7 +139,7 @@ const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
absolute
right-5
top-5
z-10
z-30
text-gray-400
transition
hover:text-gray-600
@ -161,6 +184,8 @@ const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
name="identificationNumber"
type="number"
isNumber
min={12}
max={12}
value={form.identificationNumber}
isRequired
/>
@ -238,11 +263,16 @@ const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
<span className="text-red-500"> *</span>
</span>
}
placeholder="Ngày sinh"
placeholder="DD/MM/YYYY"
name="dateOfBirth"
type="Date"
type="text"
value={form.dateOfBirth}
isRequired
onChangeValue={(value) =>
setForm((prev) => ({
...prev,
dateOfBirth: formatDateOfBirth(String(value)),
}))
}
/>
<InputForm
@ -254,8 +284,10 @@ const PopupCreatePatient = ({ onClose }: PropsPopupCreatePatient) => {
}
placeholder="Số điện thoại"
name="phone"
type="phone"
isPhone
type="number"
isNumber
min={8}
max={11}
value={form.phone}
isRequired
/>

View File

@ -238,7 +238,9 @@ const PopupUpdatePatient = ({ onClose, id }: PopupUpdatePatientProps) => {
{/* GENDER */}
<div>
<label className="text-base font-medium">Giới tính</label>
<label className="text-base font-medium">
Giới tính <span className="text-red-500">*</span>
</label>
<div className="mt-2 flex items-center gap-6">
{/* NAM */}
@ -293,7 +295,11 @@ const PopupUpdatePatient = ({ onClose, id }: PopupUpdatePatientProps) => {
/>
<InputForm
label={<span>Email</span>}
label={
<span>
Email<span className="text-red-500"> *</span>
</span>
}
placeholder="Email"
name="email"
type="email"
@ -304,7 +310,12 @@ const PopupUpdatePatient = ({ onClose, id }: PopupUpdatePatientProps) => {
<TextArea
name="address"
placeholder="Địa chỉ"
label="Địa chỉ"
label={
<span>
Đa chỉ
<span className="text-red-500"> *</span>
</span>
}
value={form.address}
isRequired
isBlur
@ -313,7 +324,12 @@ const PopupUpdatePatient = ({ onClose, id }: PopupUpdatePatientProps) => {
<InputForm
isRequired
label="Người liên hệ khẩn cấp"
label={
<span>
Người liên hệ khẩn cấp
<span className="text-red-500"> *</span>
</span>
}
placeholder="Người liên hệ khẩn cấp"
name="emergencyContactName"
type="text"
@ -321,19 +337,32 @@ const PopupUpdatePatient = ({ onClose, id }: PopupUpdatePatientProps) => {
/>
<InputForm
label="SĐT khẩn cấp"
label={
<span>
SĐT khẩn cấp
<span className="text-red-500"> *</span>
</span>
}
placeholder="SĐT khẩn cấp"
name="emergencyContactPhone"
type="phone"
type="number"
min={8}
max={11}
isRequired
isPhone
// isPhone
value={form.emergencyContactPhone}
/>
<TextArea
name="allergyNotes"
label={
<span>
Dị ng
<span className="text-red-500"> *</span>
</span>
}
isRequired
placeholder="Dị ứng"
label="Dị ứng"
value={form.allergyNotes}
isBlur
max={5000}
@ -342,14 +371,25 @@ const PopupUpdatePatient = ({ onClose, id }: PopupUpdatePatientProps) => {
<TextArea
name="chronicDiseaseNotes"
placeholder="Bệnh nền"
label="Bệnh nền"
label={
<span>
Bệnh nền
<span className="text-red-500"> *</span>
</span>
}
isRequired
value={form.chronicDiseaseNotes}
isBlur
max={5000}
/>
<InputForm
label="Số bảo hiểm"
label={
<span>
Số bảo hiểm
<span className="text-red-500"> *</span>
</span>
}
placeholder="Số bảo hiểm"
name="insuranceNumber"
type="text"
@ -359,8 +399,8 @@ const PopupUpdatePatient = ({ onClose, id }: PopupUpdatePatientProps) => {
<TextArea
name="notes"
label={<span>Ghi chú</span>}
placeholder="Ghi chú"
label="Ghi chú"
value={form.notes}
isBlur
max={5000}

View File

@ -57,7 +57,6 @@ const CreatePrescription = () => {
const [loading, setLoading] = useState<boolean>(false);
const queryKeys = [QUERY_KEY.table_list_consultation];
const [file, setFile] = useState<File | null>(null);
const [folderName, setFolderName] = useState("prescriptions");
const [form, setForm] = useState<PrescriptionForm>({
examinationSessionSpecialtyId: "",
@ -393,11 +392,16 @@ const CreatePrescription = () => {
{/* NOTES */}
<TextArea
label="Ghi chú"
label={
<span>
Ghi chú<span style={{ color: "red" }}>*</span>
</span>
}
name="notes"
placeholder="Nhập ghi chú"
value={form.notes}
isBlur
isRequired
max={5000}
onChangeValue={(value) =>
setForm((prev) => ({
@ -455,10 +459,15 @@ const CreatePrescription = () => {
{/* INPUTS */}
<div className="grid grid-cols-2 gap-5">
<InputForm
label="Tên thuốc"
label={
<span>
Tên thuốc<span style={{ color: "red" }}>*</span>
</span>
}
name={`items.${index}.medicineName`}
placeholder="Nhập tên thuốc"
value={medicine.medicineName}
isRequired
type="text"
onChangeValue={(value) =>
handleChangeMedicine(index, "medicineName", String(value))
@ -466,18 +475,28 @@ const CreatePrescription = () => {
/>
<InputForm
label="Liều lượng"
label={
<span>
Liều lượng<span style={{ color: "red" }}>*</span>
</span>
}
name={`items.${index}.dosage`}
placeholder="Ví dụ: 500mg"
value={medicine.dosage}
type="text"
isRequired
onChangeValue={(value) =>
handleChangeMedicine(index, "dosage", String(value))
}
/>
<InputForm
label="Tần suất"
label={
<span>
Tần xuất<span style={{ color: "red" }}>*</span>
</span>
}
isRequired
name={`items.${index}.frequency`}
placeholder="Ví dụ: 2 lần/ngày"
value={medicine.frequency}
@ -488,7 +507,12 @@ const CreatePrescription = () => {
/>
<InputForm
label="Thời gian dùng"
label={
<span>
Thời gian dùng<span style={{ color: "red" }}>*</span>
</span>
}
isRequired
name={`items.${index}.duration`}
placeholder="Ví dụ: 7 ngày"
value={medicine.duration}
@ -502,7 +526,12 @@ const CreatePrescription = () => {
{/* INSTRUCTION */}
<div className="mt-5">
<TextArea
label="Hướng dẫn sử dụng"
label={
<span>
Hướng dẫn sử dụng<span style={{ color: "red" }}>*</span>
</span>
}
isRequired
name={`items.${index}.instructions`}
placeholder="Nhập hướng dẫn sử dụng thuốc"
value={medicine.instructions}

View File

@ -25,7 +25,12 @@ import { ContextFormCustom } from "@/components/utils/FormCustom/contexts";
import InputForm from "@/components/utils/FormCustom/components/InputForm";
import FormCustom from "@/components/utils/FormCustom/FormCustom";
import moment from "moment";
import { timeSubmit } from "@/common/funcs/optionConvert";
import {
formatDateOfBirth,
formatToISODate,
parseDateOfBirth,
timeSubmit,
} from "@/common/funcs/optionConvert";
import CustomButton from "@/components/customs/custom-button";
function MainUpdateProfile() {
@ -91,7 +96,7 @@ function MainUpdateProfile() {
phone: currentUserProfile.phone || "",
// Định dạng input date HTML yêu cầu format YYYY-MM-DD
birthDate: currentUserProfile.birthDate
? moment(currentUserProfile.birthDate).format("YYYY-MM-DD")
? moment(currentUserProfile.birthDate).format("DD/MM/YYYY")
: "",
avatarUrl: currentUserProfile.avatarUrl || "",
});
@ -112,7 +117,7 @@ function MainUpdateProfile() {
fullName: form.fullName,
email: form.email,
phone: form.phone,
birthDate: form.birthDate,
birthDate: formatToISODate(parseDateOfBirth(form.birthDate)),
avatarUrl: body.path || form.avatarUrl,
}), // Lưu ý: Hãy cập nhật đúng service update của user profile tại đây
}),
@ -243,7 +248,12 @@ function MainUpdateProfile() {
placeholder="Nhập họ và tên"
name="fullName"
value={form.fullName}
label="Họ và tên"
label={
<span>
Họ Tên
<span className="text-red-500">*</span>
</span>
}
isRequired
onChangeValue={(v) =>
setForm((prev) => ({ ...prev, fullName: String(v) }))
@ -251,13 +261,22 @@ function MainUpdateProfile() {
/>
<InputForm
type="date"
type="text"
placeholder="Nhập ngày sinh"
name="birthDate"
label="Ngày sinh"
isRequired
label={
<span>
Ngày sinh
<span className="text-red-500">*</span>
</span>
}
value={form.birthDate}
onChangeValue={(v) =>
setForm((prev) => ({ ...prev, birthDate: String(v) }))
setForm((prev) => ({
...prev,
birthDate: formatDateOfBirth(String(v)),
}))
}
/>
</div>
@ -268,8 +287,14 @@ function MainUpdateProfile() {
placeholder="Nhập email"
name="email"
type="email"
isEmail
value={form.email}
label="Email"
label={
<span>
Email
<span className="text-red-500">*</span>
</span>
}
isRequired
onChangeValue={(v) =>
setForm((prev) => ({ ...prev, email: String(v) }))
@ -280,9 +305,16 @@ function MainUpdateProfile() {
placeholder="Nhập số điện thoại"
name="phone"
type="number"
isNumber
value={form.phone}
label="Số điện thoại"
isRequired
min={8}
max={11}
label={
<span>
Số điện thoại
<span className="text-red-500">*</span>
</span>
}
onChangeValue={(v) =>
setForm((prev) => ({ ...prev, phone: String(v) }))
}

View File

@ -38,7 +38,7 @@ export default function Providers({ children }: Props) {
<SplashScreen />
<ToastContainer autoClose={3000} />
<ToastContainer autoClose={3000} style={{ zIndex: 10002 }} />
{children}
</QueryClientProvider>