Files
LiquidCode_Frontend/src/views/home/groups/ModalInvite.tsx
Виталий Лавшонок dfc2985209 auth + groups invite
2025-11-15 17:37:47 +03:00

103 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { FC, useEffect, useMemo } from 'react';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { fetchGroupJoinLink } from '../../../redux/slices/groups';
import { Modal } from '../../../components/modal/Modal';
import { PrimaryButton } from '../../../components/button/PrimaryButton';
import { SecondaryButton } from '../../../components/button/SecondaryButton';
import { Input } from '../../../components/input/Input';
interface ModalInviteProps {
active: boolean;
setActive: (value: boolean) => void;
groupId: number;
groupName: string;
}
const ModalInvite: FC<ModalInviteProps> = ({
active,
setActive,
groupId,
groupName,
}) => {
const dispatch = useAppDispatch();
const baseUrl = window.location.origin;
// Получаем токен и дату из Redux
const { joinLink, status } = useAppSelector(
(state) => state.groups.fetchGroupJoinLink,
);
// При открытии модалки запрашиваем join link
useEffect(() => {
if (active) {
dispatch(fetchGroupJoinLink(groupId));
}
}, [active, groupId, dispatch]);
// Генерация полной ссылки с query параметрами
const inviteLink = useMemo(() => {
if (!joinLink) return '';
const params = new URLSearchParams({
token: joinLink.token,
expiresAt: joinLink.expiresAt,
groupName,
groupId: `${groupId}`,
});
return `${baseUrl}/home/group-invite?${params.toString()}`;
}, [joinLink, groupName, baseUrl, groupId]);
// Копирование и закрытие модалки
const handleCopy = async () => {
if (!inviteLink) return;
try {
await navigator.clipboard.writeText(inviteLink);
setActive(false);
} catch (err) {
console.error('Не удалось скопировать ссылку:', err);
}
};
return (
<Modal
className="bg-liquid-background border-liquid-lighter border-[2px] p-[25px] rounded-[20px] text-liquid-white"
onOpenChange={setActive}
open={active}
backdrop="blur"
>
<div className="w-[500px]">
<div className="font-bold text-[30px] mb-[20px]">
Приглашение в группу "{groupName}"
</div>
<div className="">
<div className="font-bold text-[18px] mb-[5px]">
Ссылка для приглашения
</div>
<div
className=" break-all break-words text-[#5d96ff] hover:underline cursor-pointer"
onClick={handleCopy}
>
{inviteLink}
</div>
</div>
<div className="flex flex-row w-full items-center justify-end mt-[30px] gap-[20px]">
<PrimaryButton
onClick={handleCopy}
text={
status === 'loading' ? 'Загрузка...' : 'Скопировать'
}
disabled={status === 'loading' || !inviteLink}
/>
<SecondaryButton
onClick={() => setActive(false)}
text="Отмена"
/>
</div>
</div>
</Modal>
);
};
export default ModalInvite;