DataScope26/WEB
0
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}