auth + groups invite

This commit is contained in:
Виталий Лавшонок
2025-11-15 17:37:47 +03:00
parent ded41ba7f0
commit dfc2985209
16 changed files with 673 additions and 225 deletions

View File

@@ -0,0 +1,111 @@
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { setMenuActivePage } from '../../../redux/slices/store';
import { useQuery } from '../../../hooks/useQuery';
import { PrimaryButton } from '../../../components/button/PrimaryButton';
import { SecondaryButton } from '../../../components/button/SecondaryButton';
import {
joinGroupByToken,
setGroupsStatus,
} from '../../../redux/slices/groups';
const GroupInvite = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const query = useQuery();
const token = query.get('token') ?? undefined;
const expiresAt = query.get('expiresAt') ?? undefined;
const groupName = query.get('groupName') ?? undefined;
const groupId = Number(query.get('groupId') ?? undefined);
const username = useAppSelector((state) => state.auth.username);
const joinStatus = useAppSelector(
(state) => state.groups.joinGroupByToken.status,
);
const joinError = useAppSelector(
(state) => state.groups.joinGroupByToken.error,
);
useEffect(() => {
dispatch(setMenuActivePage('groups'));
}, []);
useEffect(() => {
if (joinStatus == 'successful') {
dispatch(
setGroupsStatus({ key: 'joinGroupByToken', status: 'idle' }),
);
navigate(`/group/${groupId}`);
}
}, [joinStatus]);
if (!token || !expiresAt || !groupName || !groupId) {
return (
<div className="h-full w-full box-border p-[20px] pt-[20p] flex items-center justify-center text-bold text-[36px]">
Приглашение признано недействительным.
</div>
);
}
const isExpired = new Date(expiresAt) < new Date();
if (isExpired) {
return (
<div className="h-full w-full box-border p-[20px] pt-[20px] flex items-center justify-center text-bold text-[36px]">
Период действия приглашения истек.
</div>
);
}
const handleJoin = async () => {
if (!token) return;
try {
await dispatch(joinGroupByToken(token)).unwrap();
} catch (err) {
console.error('Failed to join group', err);
}
};
const handleCancel = () => {
navigate('/home/account');
};
return (
<div className="h-full w-full box-border flex">
<div className="p-[25px] text-liquid-white w-full">
<div className="font-bold text-[30px] mb-2">
Привет, {username}!
</div>
<div className="font-bold text-[25px]">
Вы действительно хотите присоединиться к группе:
</div>
<div className="font-bold text-[25px] mb-[20px]">
"{groupName}"
</div>
{joinError && (
<div className="text-red-500 mb-[10px]">
Ошибка присоединения: {joinError}
</div>
)}
<div className="flex flex-row w-full items-center justify-center mt-[30px] gap-[20px]">
<PrimaryButton
onClick={handleJoin}
text={
joinStatus === 'loading'
? 'Присоединяемся...'
: 'Присоединиться'
}
disabled={joinStatus === 'loading'}
/>
<SecondaryButton onClick={handleCancel} text="Отмена" />
</div>
</div>
</div>
);
};
export default GroupInvite;