CoolFace
Apppublic

DataScope26/WEB

sourceHugging Faceupdated 7d agoView on Hugging Face
0likes
CreateInvitePopup.jsx252 linesDownload Raw Back to components
1import { useState, useEffect, useRef } from "react";2import { useNavigate } from "react-router-dom";3import { useAuth } from "../context/AuthContext.jsx";4import { getAreas, searchEmployees } from "../services/apiCompanySetup.js";5import { getCookie } from "../utils/cookieUtils.js";6import ButtonClose from "./ButtonClose.jsx";7import ButtonPrimary from "./ButtonPrimary.jsx";8import ButtonSecondary from "./ButtonSecondary.jsx";9import "./CreateInvitePopup.css";10 11export default function CreateInvitePopup({ onClose, onSubmit }) {12  const { user, selectedCompany } = useAuth();13  const navigate = useNavigate();14  const companies = user?.companies || [];15  const selectedCompanyId = selectedCompany?.id ?? selectedCompany?.companyId ?? localStorage.getItem("selectedCompanyId");16 17  const [form, setForm] = useState({18    companyId: selectedCompanyId || companies[0]?.id || "",19    email: "",20    areaId: "",21  });22  const [areas, setAreas] = useState([]);23  const [suggestions, setSuggestions] = useState([]);24  const [isLoadingAreas, setIsLoadingAreas] = useState(false);25  const [isLoading, setIsLoading] = useState(false);26  const [error, setError] = useState("");27 28  const token = () =>29    sessionStorage.getItem("token") || localStorage.getItem("token") || getCookie("datascope_token");30 31  const handleSelectChange = (fieldName, value) => {32    setForm((prev) => ({ ...prev, [fieldName]: value }));33  };34 35  const CustomSelect = ({ name, value, options, placeholder = "Seleccionar" }) => {36    const [isOpen, setIsOpen] = useState(false);37    const ref = useRef(null);38 39    useEffect(() => {40      const handleClickOutside = (event) => {41        if (ref.current && !ref.current.contains(event.target)) {42          setIsOpen(false);43        }44      };45 46      document.addEventListener("mousedown", handleClickOutside);47      return () => document.removeEventListener("mousedown", handleClickOutside);48    }, []);49 50    const selectedOption = options.find((option) => String(option.value) === String(value));51 52    return (53      <div className="invite-popup__select-wrap" ref={ref}>54        <ButtonPrimary55          type="button"56          className="invite-popup__select-button"57          onClick={() => setIsOpen((prev) => !prev)}58          aria-expanded={isOpen}59        >60          <span>{selectedOption?.label || placeholder}</span>61          <span className="invite-popup__select-caret" />62        </ButtonPrimary>63 64        {isOpen && (65          <ul className="invite-popup__select-menu" role="listbox">66            {options.map((option) => (67              <li68                key={option.value}69                role="option"70                aria-selected={String(option.value) === String(value)}71                className={String(option.value) === String(value) ? "active" : ""}72                onMouseDown={(e) => {73                  e.preventDefault();74                  handleSelectChange(name, option.value);75                  setIsOpen(false);76                }}77              >78                {option.label}79              </li>80            ))}81          </ul>82        )}83      </div>84    );85  };86 87  useEffect(() => {88    const companyId = selectedCompanyId || companies[0]?.id || "";89    if (!companyId) return;90    setForm((prev) => ({ ...prev, companyId }));91  }, [selectedCompanyId, companies]);92 93  useEffect(() => {94    if (!form.companyId) return;95    const fetchAreas = async () => {96      setIsLoadingAreas(true);97      try {98        const res = await getAreas(token(), form.companyId);99        const list = res.data || [];100        setAreas(list);101        if (list.length > 0 && !list.some((area) => String(area.id) === String(form.areaId))) {102          setForm((prev) => ({ ...prev, areaId: String(list[0].id) }));103        }104      } catch (err) {105        console.error("Error al obtener áreas:", err);106      } finally {107        setIsLoadingAreas(false);108      }109    };110 111    fetchAreas();112  }, [form.companyId]);113 114  useEffect(() => {115    const term = form.email.trim();116    if (!form.companyId || term.length < 2) {117      setSuggestions([]);118      return;119    }120 121    const timeout = setTimeout(async () => {122      try {123        const res = await searchEmployees(token(), form.companyId, term);124        const items = (res?.data || [])125          .map((user) => user.email)126          .filter(Boolean)127          .filter((email, index, arr) => arr.indexOf(email) === index)128          .slice(0, 8);129        setSuggestions(items);130      } catch (err) {131        setSuggestions([]);132      }133    }, 250);134 135    return () => clearTimeout(timeout);136  }, [form.companyId, form.email]);137 138  const handleChange = (e) => {139    setForm({ ...form, [e.target.name]: e.target.value });140  };141 142  const handleSubmit = async (e) => {143    e.preventDefault();144    if (!form.companyId || !form.email || !form.areaId) return;145 146    setIsLoading(true);147    setError("");148    try {149      await onSubmit(form.companyId, form.email, form.areaId);150      onClose();151    } catch (err) {152      const message = err?.response?.data?.error || err?.message || "No se pudo enviar la invitación";153      setError(message);154    } finally {155      setIsLoading(false);156    }157  };158 159  const handleGoToAreas = () => {160    onClose();161    navigate(`/company-setup/${form.companyId}?steps=area`);162  };163 164  return (165    <>166      <div className="invite-popup-backdrop" onClick={onClose} />167      <div className="invite-popup" onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(e); }}>168        <ButtonClose onClick={onClose} />169        <h1>Enviar invitación</h1>170 171        {areas.length === 0 && !isLoadingAreas ? (172          <div className="invite-popup__no-areas">173            <p>No podés enviar invitaciones porque todavía no creaste ninguna área para esta empresa.</p>174            <ButtonPrimary type="button" onClick={handleGoToAreas} className="invite-popup__cta-button">175              Crear área176            </ButtonPrimary>177            <ButtonSecondary type="button" onClick={onClose} className="invite-popup__secondary-button">178              Volver179            </ButtonSecondary>180          </div>181        ) : (182          <form className="invite-popup__form" onSubmit={handleSubmit}>183            {companies.length > 1 && (184              <div className="invite-popup__input-group">185                <label>EMPRESA</label>186                <CustomSelect187                  name="companyId"188                  value={form.companyId}189                  placeholder="Seleccionar empresa"190                  options={companies.map((c) => ({ value: String(c.id), label: c.name }))}191                />192              </div>193            )}194 195            <div className="invite-popup__input-group">196              <label>EMAIL</label>197              <input198                type="email"199                placeholder="maria@empresa.com"200                name="email"201                value={form.email}202                onChange={handleChange}203                maxLength={70}204                autoComplete="off"205                aria-autocomplete="list"206              />207              {suggestions.length > 0 && (208                <ul className="invite-popup__suggestions" role="listbox">209                  {suggestions.map((email) => (210                    <li211                      key={email}212                      role="option"213                      onMouseDown={(e) => {214                        e.preventDefault();215                        setForm((prev) => ({ ...prev, email }));216                        setSuggestions([]);217                      }}218                    >219                      {email}220                    </li>221                  ))}222                </ul>223              )}224            </div>225 226            <div className="invite-popup__input-group">227              <label>ÁREA</label>228              {isLoadingAreas ? (229                <p>Cargando áreas...</p>230              ) : (231                <CustomSelect232                  name="areaId"233                  value={form.areaId}234                  placeholder="Seleccionar área"235                  options={areas.map((a) => ({ value: String(a.id), label: a.name }))}236                />237              )}238            </div>239 240            {error && <p className="invite-popup__error">{error}</p>}241 242            {isLoading ? (243              <ButtonPrimary className="invite-popup__submit" type="button" disabled>Enviando...</ButtonPrimary>244            ) : (245              <ButtonPrimary className="invite-popup__submit" type="submit">Enviar invitación</ButtonPrimary>246            )}247          </form>248        )}249      </div>250    </>251  );252}