diff --git a/public/locale/en.json b/public/locale/en.json index 5d33733b15c..eb59daa7444 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -364,6 +364,7 @@ "allow_transfer": "Allow Transfer", "allowed_formats_are": "Allowed formats are", "already_a_member": "Already a member?", + "alternate_phone_number": "Alternate Phone Number", "ambulance_driver_name": "Name of ambulance driver", "ambulance_number": "Ambulance No", "ambulance_phone_number": "Phone number of Ambulance", @@ -503,6 +504,7 @@ "check_policy_eligibility": "Check Policy Eligibility", "check_status": "Check Status", "checked_in": "Checked-In", + "checking_availability": "Checking Availability", "checking_consent_status": "Consent request status is being checked!", "checking_eligibility": "Checking Eligibility", "checking_for_update": "Checking for update", @@ -647,6 +649,7 @@ "create_position_preset_description": "Creates a new position preset in Care from the current position of the camera for the given name", "create_preset_prerequisite": "To create presets for this bed, you'll need to link the camera to the bed first.", "create_resource_request": "Create Request", + "create_user": "Create User", "created": "Created", "created_by": "Created By", "created_date": "Created Date", @@ -728,6 +731,7 @@ "dob": "DOB", "dob_format": "Please enter date in DD/MM/YYYY format", "doc_will_visit_patient": "will visit the patient at the scheduled time.", + "doctor": "Doctor", "doctor_experience_error": "Please enter a valid number between 0 and 100.", "doctor_experience_required": "Years of experience is required", "doctor_not_found": "Doctor not found", @@ -772,7 +776,7 @@ "eg_mail_example_com": "Eg. mail@example.com", "eg_xyz": "Eg. XYZ", "eligible": "Eligible", - "email": "Email Address", + "email": "Email", "email_address": "Email Address", "email_discharge_summary_description": "Enter your valid email address to receive the discharge summary", "email_success": "We will be sending an email shortly. Please check your inbox.", @@ -1305,6 +1309,7 @@ "number_of_beds_out_of_range_error": "Number of beds cannot be greater than 100", "number_of_chronic_diseased_dependents": "Number Of Chronic Diseased Dependents", "number_of_covid_vaccine_doses": "Number of Covid vaccine doses", + "nurse": "Nurse", "nursing_care": "Nursing Care", "nursing_information": "Nursing Information", "nutrition": "Nutrition", @@ -1707,6 +1712,7 @@ "source": "Source", "spokes": "Spoke Facilities", "srf_id": "SRF ID", + "staff": "Staff", "staff_list": "Staff List", "start_consultation": "Start Consultation", "start_datetime": "Start Date/Time", @@ -1912,6 +1918,7 @@ "vitals_monitor": "Vitals Monitor", "vitals_present": "Vitals Monitor present", "voice_autofill": "Voice Autofill", + "volunteer": "Volunteer", "volunteer_assigned": "Volunteer assigned successfully", "volunteer_contact": "Volunteer Contact", "volunteer_contact_detail": "Provide the name and contact details of a volunteer who can assist the patient in emergencies. This should be someone outside the family.", @@ -1924,6 +1931,7 @@ "weekly_working_hours_error": "Average weekly working hours must be a number between 0 and 168", "what_facility_assign_the_patient_to": "What facility would you like to assign the patient to", "whatsapp_number": "Whatsapp Number", + "whatsapp_number_same_as_phone_number": "WhatsApp number is same as phone number", "why_the_asset_is_not_working": "Why the asset is not working?", "width": "Width ({{unit}})", "with": "with", diff --git a/src/components/Users/CreateUserForm.tsx b/src/components/Users/CreateUserForm.tsx index beafb4be950..6c1e9483b50 100644 --- a/src/components/Users/CreateUserForm.tsx +++ b/src/components/Users/CreateUserForm.tsx @@ -1,9 +1,12 @@ import { zodResolver } from "@hookform/resolvers/zod"; +import { useQuery } from "@tanstack/react-query"; import { useEffect } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import * as z from "zod"; +import CareIcon from "@/CAREUI/icons/CareIcon"; + import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { @@ -23,13 +26,17 @@ import { SelectValue, } from "@/components/ui/select"; +import { validateRule } from "@/components/Users/UserFormValidations"; + import { GENDER_TYPES } from "@/common/constants"; import * as Notification from "@/Utils/Notifications"; +import query from "@/Utils/request/query"; import request from "@/Utils/request/request"; import OrganizationSelector from "@/pages/Organization/components/OrganizationSelector"; import { UserBase } from "@/types/user/user"; import UserApi from "@/types/user/userApi"; +import userApi from "@/types/user/userApi"; const userFormSchema = z .object({ @@ -107,6 +114,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { }); const userType = form.watch("user_type"); + const usernameInput = form.watch("username"); const phoneNumber = form.watch("phone_number"); const isWhatsApp = form.watch("phone_number_is_whatsapp"); @@ -114,7 +122,44 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { if (isWhatsApp) { form.setValue("alt_phone_number", phoneNumber); } - }, [phoneNumber, isWhatsApp, form]); + if (usernameInput && usernameInput.length > 0) { + form.trigger("username"); + } + }, [phoneNumber, isWhatsApp, form, usernameInput]); + + const { error, isLoading } = useQuery({ + queryKey: ["checkUsername", usernameInput], + queryFn: query(userApi.checkUsername, { + pathParams: { username: usernameInput }, + silent: true, + }), + enabled: !form.formState.errors.username, + }); + + const renderUsernameFeedback = (usernameInput: string) => { + const { + errors: { username }, + } = form.formState; + if (username?.message) { + return validateRule(false, username.message); + } else if (isLoading) { + return ( +
+ + + {t("checking_availability")} + +
+ ); + } else if (error) { + return validateRule(false, t("username_not_available")); + } else if (usernameInput) { + return validateRule(true, t("username_available")); + } + }; const onSubmit = async (data: UserFormValues) => { try { @@ -155,7 +200,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="user_type" render={({ field }) => ( - User Type + {t("user_type")} @@ -180,9 +225,9 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="first_name" render={({ field }) => ( - First Name + {t("first_name")} - + @@ -194,26 +239,27 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="last_name" render={({ field }) => ( - Last Name + {t("last_name")} - + )} /> - ( - Username + {t("username")} - +
+ +
- + {renderUsernameFeedback(usernameInput)}
)} /> @@ -224,9 +270,13 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="password" render={({ field }) => ( - Password + {t("password")} - + @@ -238,11 +288,11 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="c_password" render={({ field }) => ( - Confirm Password + {t("confirm_password")} @@ -257,9 +307,9 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="email" render={({ field }) => ( - Email + {t("email")} - + @@ -272,7 +322,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="phone_number" render={({ field }) => ( - Phone Number + {t("phone_number")} @@ -286,7 +336,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="alt_phone_number" render={({ field }) => ( - Alternative Phone Number + {t("alternate_phone_number")}
- WhatsApp number is same as phone number + + {t("whatsapp_number_same_as_phone_number")} +
)} @@ -325,7 +377,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="date_of_birth" render={({ field }) => ( - Date of Birth + {t("date_of_birth")} @@ -339,7 +391,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="gender" render={({ field }) => ( - Gender + {t("gender")} + @@ -387,11 +439,11 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="doctor_experience_commenced_on" render={({ field }) => ( - Years of Experience + {t("years_of_experience")} @@ -405,10 +457,10 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { name="doctor_medical_council_registration" render={({ field }) => ( - Medical Council Registration + {t("medical_council_registration")} @@ -419,7 +471,6 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) { )} - diff --git a/src/components/Users/UserFormValidations.tsx b/src/components/Users/UserFormValidations.tsx index f6173024873..9b6e90b92a4 100644 --- a/src/components/Users/UserFormValidations.tsx +++ b/src/components/Users/UserFormValidations.tsx @@ -57,13 +57,13 @@ export const validateRule = ( isInitialState: boolean = false, ) => { return ( -
+
{isInitialState ? ( - + ) : condition ? ( - + ) : ( - + )}{" "} (), }, + checkUsername: { + path: "/api/v1/users/{username}/check_availability/", + method: HttpMethod.GET, + TRes: Type, + }, };