Source

components/forms/UserForm.jsx

import React, { useEffect, useState } from 'react';
import FormField from '../ui/FormField';
import { useForm } from '../../hooks/useForm';
import {useAuth} from '../../hooks/useAuth';
import ApiService from '../../services/api';
  
/**
 * A form component for creating or updating a user.
 * It includes fields for institution ID, role, and phone number.
 * Roles are fetched from the API based on the authenticated user's hospital.
 *
 * @param {object} props - The component props.
 * @param {object} [props.initialData] - Initial data to populate the form (for updates).
 * @param {function} props.onSubmit - Function to call when the form is submitted and valid.
 * @param {function} props.onCancel - Function to call when the cancel button is clicked.
 * @param {boolean} props.loading - Indicates whether the form is currently submitting.
 * @returns {JSX.Element} The UserForm component.
 */
const UserForm = ({ initialData, onSubmit, onCancel, loading }) => {
  const [roles, setRoles] = useState([]);
  const [rolesLoading, setRolesLoading] = useState(false);
  // Get the authenticated user's hospital information
  const { hospital } = useAuth();
  const hospitalId = hospital?.id;
  const service = new ApiService();
  useEffect(() => {
    if (!hospitalId) return;
    let isMounted = true;
    setRolesLoading(true);
    service.getRoles(hospitalId)
      .then(data => { if (isMounted) setRoles(data);console.log(data) })
      .catch(() => { if (isMounted) setRoles([]); })
      .finally(() => { if (isMounted) setRolesLoading(false); });
    return () => { isMounted = false; };
  }, [hospitalId]);

  const { values, errors, handleChange, handleBlur, validate, setValues } = useForm(
    initialData || {
      institution_id: '',
      role: roles[0]?.id,
      phone_number: ''
    },
    {
      institution_id: { required: true, minLength: 3 },
      role: { required: true },
      phone_number: { phone: true },
    }
  );

  const handleSubmit = (e) => {
    e.preventDefault();
    if (validate()) {
      onSubmit(values);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <FormField
        label="Institution ID"
        name="institution_id"
        value={values.institution_id}
        onChange={handleChange}
        onBlur={handleBlur}
        error={errors.institution_id}
        required
      />

      <FormField
        label="Role"
        name="role"
        type="select"
        value={values.role}
        onChange={handleChange}
        onBlur={handleBlur}
        error={errors.role}
        required
        options={roles.map(role => ({ value: role.id, label: role.name }))}
        loading={rolesLoading}
      />

      <FormField
        label="Phone Number"
        name="phone_number"
        type="tel"
        value={values.phone_number}
        onChange={handleChange}
        onBlur={handleBlur}
        error={errors.phone_number}
      />

      <div className="flex justify-end space-x-2 pt-4">
        <button
          type="button"
          onClick={onCancel}
          className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300"
          disabled={loading}
        >
          Cancel
        </button>
        <button
          type="submit"
          className="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50"
          disabled={loading}
        >
          {loading ? 'Saving...' : initialData ? 'Update' : 'Create'}
        </button>
      </div>
    </form>
  );
};

export default UserForm;