auth + groups invite
This commit is contained in:
102
src/views/home/groups/ModalInvite.tsx
Normal file
102
src/views/home/groups/ModalInvite.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user