143 lines
4.1 KiB
TypeScript
143 lines
4.1 KiB
TypeScript
import React, { useState } from "react";
|
|
import { useParams } from "react-router-dom";
|
|
|
|
import { getSearchUsers } from "../../../services/factoryBuilder/collab/getSearchUsers";
|
|
import { shareProject } from "../../../services/factoryBuilder/collab/shareProject";
|
|
import { getUserData } from "../../../functions/getUserData";
|
|
|
|
interface UserData {
|
|
_id: string;
|
|
Email: string;
|
|
userName: string;
|
|
}
|
|
|
|
interface MultiEmailProps {
|
|
users: Array<any>;
|
|
getData: () => void;
|
|
}
|
|
|
|
const MultiEmailInvite: React.FC<MultiEmailProps> = ({ users, getData }) => {
|
|
const [selectedUsers, setSelectedUsers] = useState<UserData[]>([]);
|
|
const [searchResults, setSearchResults] = useState<UserData[]>([]);
|
|
const [inputValue, setInputValue] = useState("");
|
|
const [isFocused, setIsFocused] = useState(false);
|
|
|
|
const { projectId } = useParams();
|
|
const { userId } = getUserData();
|
|
|
|
|
|
const handleSearchInput = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const value = e.target.value.trim();
|
|
setInputValue(value);
|
|
|
|
if (value.length < 3) return;
|
|
|
|
try {
|
|
const result = await getSearchUsers(value);
|
|
const filtered = result?.sharchMail?.filtered || [];
|
|
setSearchResults(filtered);
|
|
} catch (err) {
|
|
console.error("Search failed:", err);
|
|
}
|
|
};
|
|
|
|
const handleAddUser = (user: UserData) => {
|
|
if (!user || user._id === userId) return;
|
|
|
|
const isAlreadySelected = selectedUsers.some(u => u._id === user._id);
|
|
const isAlreadyShared = users.some(u => u.userId === user._id);
|
|
|
|
if (!isAlreadySelected && !isAlreadyShared) {
|
|
setSelectedUsers(prev => [...prev, user]);
|
|
}
|
|
|
|
setInputValue("");
|
|
};
|
|
|
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
if ((e.key === "Enter" || e.key === ",") && searchResults.length > 0) {
|
|
e.preventDefault();
|
|
handleAddUser(searchResults[0]);
|
|
}
|
|
};
|
|
|
|
const handleRemoveUser = (userIdToRemove: string) => {
|
|
setSelectedUsers(prev => prev.filter(user => user._id !== userIdToRemove));
|
|
};
|
|
|
|
const handleRemoveEmail = (idToRemove: string) => {
|
|
setSelectedUsers((prev: any) => prev.filter((email: any) => email._id !== idToRemove));
|
|
};
|
|
|
|
|
|
const validateEmail = (email: string) => {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
return emailRegex.test(email);
|
|
};
|
|
|
|
const handleAddEmail = async () => {
|
|
if (!projectId) return;
|
|
|
|
try {
|
|
await Promise.all(
|
|
selectedUsers.map(user =>
|
|
shareProject(user._id, projectId)
|
|
.then(res => console.log("Shared:", res))
|
|
.catch(err => console.error("Share error:", err))
|
|
)
|
|
);
|
|
|
|
setSelectedUsers([]);
|
|
setInputValue("");
|
|
setTimeout(getData, 1000);
|
|
} catch (error) {
|
|
console.error("Invite error:", error);
|
|
}
|
|
};
|
|
|
|
|
|
return (
|
|
<div className="multi-email-invite-input-container">
|
|
<div className={`multi-email-invite-input${isFocused ? " active" : ""}`}>
|
|
{selectedUsers.map(user => (
|
|
<div key={user._id} className="entered-emails">
|
|
{user.Email}
|
|
<span onClick={() => handleRemoveUser(user._id)}>×</span>
|
|
</div>
|
|
))}
|
|
|
|
<input
|
|
type="text"
|
|
value={inputValue}
|
|
onChange={handleSearchInput}
|
|
onFocus={() => setIsFocused(true)}
|
|
onKeyDown={handleKeyDown}
|
|
placeholder="Enter email and press Enter or comma"
|
|
/>
|
|
</div>
|
|
|
|
<div onClick={handleAddEmail} className="invite-button">
|
|
Add
|
|
</div>
|
|
|
|
{isFocused && inputValue.length > 2 && searchResults.length > 0 && (
|
|
<div className="users-list-container">
|
|
{searchResults.map(user => (
|
|
<div
|
|
key={user._id}
|
|
onClick={() => {
|
|
handleAddUser(user);
|
|
setIsFocused(false);
|
|
}}
|
|
>
|
|
{user.Email}
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
|
|
export default MultiEmailInvite; |