Skip to content

Commit

Permalink
Username validation added in Create user form (#9835)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rishith25 authored Jan 9, 2025
1 parent 0592e63 commit 12e0938
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 38 deletions.
10 changes: 9 additions & 1 deletion public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -772,7 +776,7 @@
"eg_mail_example_com": "Eg. [email protected]",
"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.",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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.",
Expand All @@ -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",
Expand Down
117 changes: 84 additions & 33 deletions src/components/Users/CreateUserForm.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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({
Expand Down Expand Up @@ -107,14 +114,52 @@ 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");

useEffect(() => {
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 (
<div className="flex items-center gap-1">
<CareIcon
icon="l-spinner"
className="text-sm text-gray-500 animate-spin"
/>
<span className="text-gray-500 text-sm">
{t("checking_availability")}
</span>
</div>
);
} 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 {
Expand Down Expand Up @@ -155,18 +200,18 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="user_type"
render={({ field }) => (
<FormItem>
<FormLabel>User Type</FormLabel>
<FormLabel>{t("user_type")}</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select user type" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="doctor">Doctor</SelectItem>
<SelectItem value="nurse">Nurse</SelectItem>
<SelectItem value="staff">Staff</SelectItem>
<SelectItem value="volunteer">Volunteer</SelectItem>
<SelectItem value="doctor">{t("doctor")}</SelectItem>
<SelectItem value="nurse">{t("nurse")}</SelectItem>
<SelectItem value="staff">{t("staff")}</SelectItem>
<SelectItem value="volunteer">{t("volunteer")}</SelectItem>
</SelectContent>
</Select>
<FormMessage />
Expand All @@ -180,9 +225,9 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="first_name"
render={({ field }) => (
<FormItem>
<FormLabel>First Name</FormLabel>
<FormLabel>{t("first_name")}</FormLabel>
<FormControl>
<Input placeholder="First name" {...field} />
<Input placeholder={t("first_name")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -194,26 +239,27 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="last_name"
render={({ field }) => (
<FormItem>
<FormLabel>Last Name</FormLabel>
<FormLabel>{t("last_name")}</FormLabel>
<FormControl>
<Input placeholder="Last name" {...field} />
<Input placeholder={t("last_name")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>

<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormLabel>{t("username")}</FormLabel>
<FormControl>
<Input placeholder="Username" {...field} />
<div className="relative">
<Input placeholder={t("username")} {...field} />
</div>
</FormControl>
<FormMessage />
{renderUsernameFeedback(usernameInput)}
</FormItem>
)}
/>
Expand All @@ -224,9 +270,13 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormLabel>{t("password")}</FormLabel>
<FormControl>
<Input type="password" placeholder="Password" {...field} />
<Input
type="password"
placeholder={t("password")}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -238,11 +288,11 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="c_password"
render={({ field }) => (
<FormItem>
<FormLabel>Confirm Password</FormLabel>
<FormLabel>{t("confirm_password")}</FormLabel>
<FormControl>
<Input
type="password"
placeholder="Confirm password"
placeholder={t("confirm_password")}
{...field}
/>
</FormControl>
Expand All @@ -257,9 +307,9 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormLabel>{t("email")}</FormLabel>
<FormControl>
<Input type="email" placeholder="Email" {...field} />
<Input type="email" placeholder={t("email")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -272,7 +322,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="phone_number"
render={({ field }) => (
<FormItem>
<FormLabel>Phone Number</FormLabel>
<FormLabel>{t("phone_number")}</FormLabel>
<FormControl>
<Input type="tel" placeholder="+91XXXXXXXXXX" {...field} />
</FormControl>
Expand All @@ -286,7 +336,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="alt_phone_number"
render={({ field }) => (
<FormItem>
<FormLabel>Alternative Phone Number</FormLabel>
<FormLabel>{t("alternate_phone_number")}</FormLabel>
<FormControl>
<Input
placeholder="+91XXXXXXXXXX"
Expand All @@ -313,7 +363,9 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
/>
</FormControl>
<div className="space-y-1 leading-none">
<FormLabel>WhatsApp number is same as phone number</FormLabel>
<FormLabel>
{t("whatsapp_number_same_as_phone_number")}
</FormLabel>
</div>
</FormItem>
)}
Expand All @@ -325,7 +377,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="date_of_birth"
render={({ field }) => (
<FormItem>
<FormLabel>Date of Birth</FormLabel>
<FormLabel>{t("date_of_birth")}</FormLabel>
<FormControl>
<Input type="date" {...field} />
</FormControl>
Expand All @@ -339,7 +391,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="gender"
render={({ field }) => (
<FormItem>
<FormLabel>Gender</FormLabel>
<FormLabel>{t("gender")}</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
Expand Down Expand Up @@ -369,9 +421,9 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="qualification"
render={({ field }) => (
<FormItem>
<FormLabel>Qualification</FormLabel>
<FormLabel>{t("qualification")}</FormLabel>
<FormControl>
<Input placeholder="Qualification" {...field} />
<Input placeholder={t("qualification")} {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -387,11 +439,11 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="doctor_experience_commenced_on"
render={({ field }) => (
<FormItem>
<FormLabel>Years of Experience</FormLabel>
<FormLabel>{t("years_of_experience")}</FormLabel>
<FormControl>
<Input
type="number"
placeholder="Years of experience"
placeholder={t("years_of_experience")}
{...field}
/>
</FormControl>
Expand All @@ -405,10 +457,10 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
name="doctor_medical_council_registration"
render={({ field }) => (
<FormItem>
<FormLabel>Medical Council Registration</FormLabel>
<FormLabel>{t("medical_council_registration")}</FormLabel>
<FormControl>
<Input
placeholder="Medical council registration"
placeholder={t("medical_council_registration")}
{...field}
/>
</FormControl>
Expand All @@ -419,7 +471,6 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
</div>
</>
)}

<FormField
control={form.control}
name="geo_organization"
Expand All @@ -438,7 +489,7 @@ export default function CreateUserForm({ onSubmitSuccess }: Props) {
/>

<Button type="submit" className="w-full">
Create User
{t("create_user")}
</Button>
</form>
</Form>
Expand Down
8 changes: 4 additions & 4 deletions src/components/Users/UserFormValidations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ export const validateRule = (
isInitialState: boolean = false,
) => {
return (
<div>
<div className="text-sm">
{isInitialState ? (
<CareIcon icon="l-circle" className="text-xl text-gray-500" />
<CareIcon icon="l-circle" className="text-gray-500" />
) : condition ? (
<CareIcon icon="l-check-circle" className="text-xl text-green-500" />
<CareIcon icon="l-check-circle" className="text-green-500" />
) : (
<CareIcon icon="l-times-circle" className="text-xl text-red-500" />
<CareIcon icon="l-times-circle" className="text-red-500" />
)}{" "}
<span
className={classNames(
Expand Down
Loading

0 comments on commit 12e0938

Please sign in to comment.