{
}));
setMissionIdInput('');
})
- .catch((err) => {});
+ .catch((err) => {
+ err;
+ });
};
const removeMission = (removeId: number) => {
diff --git a/src/redux/slices/groupChat.ts b/src/redux/slices/groupChat.ts
index e97db39..9233a9d 100644
--- a/src/redux/slices/groupChat.ts
+++ b/src/redux/slices/groupChat.ts
@@ -19,7 +19,8 @@ export interface ChatMessage {
interface FetchMessagesParams {
groupId: number;
limit?: number;
- afterMessageId?: number | null;
+ afterMessageId?: number;
+ timeoutSeconds?: number;
}
interface SendMessageParams {
@@ -33,8 +34,7 @@ interface SendMessageParams {
interface GroupChatState {
messages: Record; // по группам
- hasMore: Record; // есть ли ещё старые сообщения
- isInitialLoaded: Record; // загружена ли первая порция
+ lastMessage: Record;
fetchMessages: {
status: Status;
@@ -48,8 +48,7 @@ interface GroupChatState {
const initialState: GroupChatState = {
messages: {},
- hasMore: {},
- isInitialLoaded: {},
+ lastMessage: {},
fetchMessages: {
status: 'idle',
error: undefined,
@@ -73,13 +72,13 @@ export const fetchGroupMessages = createAsyncThunk(
params: {
limit: params.limit,
afterMessageId: params.afterMessageId,
+ timeoutSeconds: params.timeoutSeconds,
},
});
return {
groupId: params.groupId,
messages: response.data as ChatMessage[],
- afterMessageId: params.afterMessageId,
};
} catch (err: any) {
return rejectWithValue(
@@ -117,8 +116,18 @@ const groupChatSlice = createSlice({
reducers: {
clearChat(state, action: PayloadAction) {
delete state.messages[action.payload];
- delete state.hasMore[action.payload];
- delete state.isInitialLoaded[action.payload];
+ },
+ setGroupChatStatus: (
+ state,
+ action: PayloadAction<{
+ key: keyof GroupChatState;
+ status: Status;
+ }>,
+ ) => {
+ const { key, status } = action.payload;
+ if (state[key]) {
+ (state[key] as any).status = status;
+ }
},
},
extraReducers: (builder) => {
@@ -134,28 +143,22 @@ const groupChatSlice = createSlice({
action: PayloadAction<{
groupId: number;
messages: ChatMessage[];
- afterMessageId?: number | null;
}>,
) => {
- const { groupId, messages, afterMessageId } = action.payload;
+ const { groupId, messages } = action.payload;
const existing = state.messages[groupId] || [];
- // первичная загрузка
- if (!afterMessageId) {
- state.messages[groupId] = messages;
- state.isInitialLoaded[groupId] = true;
- state.hasMore[groupId] = messages.length > 0;
- }
- // догружаем старые (scroll up)
- else if (afterMessageId) {
- const ids = new Set(existing.map((m) => m.id));
- const filtered = messages.filter((m) => !ids.has(m.id));
- console.log('messages', messages);
- console.log('filtered', filtered);
- console.log('ids', ids);
- console.log('existing', existing);
- state.messages[groupId] = [...existing, ...filtered];
- state.hasMore[groupId] = filtered.length > 0;
+ const ids = new Set(existing.map((m) => m.id));
+ const filtered = messages.filter((m) => !ids.has(m.id));
+
+ state.messages[groupId] = [...existing, ...filtered].sort(
+ (a, b) => a.id - b.id,
+ );
+ if (state.messages[groupId].length) {
+ state.lastMessage[groupId] =
+ state.messages[groupId][
+ state.messages[groupId].length - 1
+ ].id;
}
state.fetchMessages.status = 'successful';
@@ -190,5 +193,5 @@ const groupChatSlice = createSlice({
},
});
-export const { clearChat } = groupChatSlice.actions;
+export const { clearChat, setGroupChatStatus } = groupChatSlice.actions;
export const groupChatReducer = groupChatSlice.reducer;
diff --git a/src/views/articleeditor/Editor.tsx b/src/views/articleeditor/Editor.tsx
index 8fd18ad..f109cef 100644
--- a/src/views/articleeditor/Editor.tsx
+++ b/src/views/articleeditor/Editor.tsx
@@ -68,14 +68,14 @@ function greet(user: User) {
return \`Привет, \${user.name}! 👋 Роль: \${user.role}\`;
}
-console.log(greet({ name: "Ты", role: "Разработчик" }));
+consol.log(greet({ name: "Ты", role: "Разработчик" }));
\`\`\`
Пример **JavaScript**:
\`\`\`js
const sum = (a, b) => a + b;
-console.log(sum(2, 3)); // 5
+consol.log(sum(2, 3)); // 5
\`\`\`
Пример **Python**:
@@ -256,9 +256,7 @@ const MarkdownEditor: FC = ({
markdown.slice(cursorPos);
setMarkdown(newText);
- } catch (err) {
- console.error('Ошибка загрузки изображения:', err);
- }
+ } catch (err) {}
}
}
};
diff --git a/src/views/home/articles/Filter.tsx b/src/views/home/articles/Filter.tsx
index 1d8a82f..d56a78b 100644
--- a/src/views/home/articles/Filter.tsx
+++ b/src/views/home/articles/Filter.tsx
@@ -36,13 +36,17 @@ const Filters = () => {
text: 'ID',
},
]}
- onChange={(v) => {}}
+ onChange={(v) => {
+ v;
+ }}
/>
{}}
+ onChange={(values) => {
+ values;
+ }}
/>
);
diff --git a/src/views/home/contest/Missions.tsx b/src/views/home/contest/Missions.tsx
index 1893df9..f4c90d6 100644
--- a/src/views/home/contest/Missions.tsx
+++ b/src/views/home/contest/Missions.tsx
@@ -1,124 +1,126 @@
-import { FC, useEffect } from "react";
-import MissionItem from "./MissionItem";
+import { FC, useEffect } from 'react';
+import MissionItem from './MissionItem';
import {
- Contest,
- fetchMySubmissions,
- setContestStatus,
-} from "../../../redux/slices/contests";
-import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
-import { PrimaryButton } from "../../../components/button/PrimaryButton";
-import { useNavigate } from "react-router-dom";
-import { arrowLeft } from "../../../assets/icons/header";
+ Contest,
+ fetchMySubmissions,
+ setContestStatus,
+} from '../../../redux/slices/contests';
+import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
+import { PrimaryButton } from '../../../components/button/PrimaryButton';
+import { useNavigate } from 'react-router-dom';
+import { arrowLeft } from '../../../assets/icons/header';
export interface Article {
- id: number;
- name: string;
- tags: string[];
+ id: number;
+ name: string;
+ tags: string[];
}
interface ContestMissionsProps {
- contest?: Contest;
+ contest?: Contest;
}
const ContestMissions: FC
= ({ contest }) => {
- const navigate = useNavigate();
- const dispatch = useAppDispatch();
- const { submissions, status } = useAppSelector(
- (state) => state.contests.fetchMySubmissions
- );
+ const navigate = useNavigate();
+ const dispatch = useAppDispatch();
+ const { submissions, status } = useAppSelector(
+ (state) => state.contests.fetchMySubmissions,
+ );
- useEffect(() => {
- if (contest) dispatch(fetchMySubmissions(contest.id));
- }, [contest]);
+ useEffect(() => {
+ if (contest) dispatch(fetchMySubmissions(contest.id));
+ }, [contest]);
- useEffect(() => {
- if (status == "successful") {
- dispatch(setContestStatus({ key: "fetchMySubmissions", status: "idle" }));
+ useEffect(() => {
+ if (status == 'successful') {
+ dispatch(
+ setContestStatus({ key: 'fetchMySubmissions', status: 'idle' }),
+ );
+ }
+ }, [status]);
+
+ if (!contest) {
+ return <>>;
}
- }, [status]);
- if (!contest) {
- return <>>;
- }
+ const solvedCount = (contest.missions ?? []).filter((mission) =>
+ submissions.some(
+ (s) =>
+ s.solution.missionId === mission.id &&
+ s.solution.status === 'Accepted: All tests passed',
+ ),
+ ).length;
- const solvedCount = (contest.missions ?? []).filter((mission) =>
- submissions.some(
- (s) =>
- s.solution.missionId === mission.id &&
- s.solution.status === "Accepted: All tests passed"
- )
- ).length;
+ const totalCount = contest.missions?.length ?? 0;
- const totalCount = contest.missions?.length ?? 0;
+ return (
+
+
+
+ {contest.name}
+
+
+
+

{
+ navigate(`/home/contests`);
+ }}
+ />
+
+ Контест #{contest.id}
+
+
+
{contest.attemptDurationMinutes ?? 0} минут
+
+
+
+
{`${solvedCount}/${totalCount} Решено`}
+
{
+ navigate(`/contest/${contest.id}/submissions`);
+ }}
+ text="Мои посылки"
+ />
+
- return (
-
-
-
- {contest.name}
+
+
+ {(contest.missions ?? []).map((v, i) => {
+ const missionSubmissions = submissions.filter(
+ (s) => s.solution.missionId === v.id,
+ );
+
+ const hasSuccess = missionSubmissions.some(
+ (s) =>
+ s.solution.status ==
+ 'Accepted: All tests passed',
+ );
+
+ const status = hasSuccess
+ ? 'success'
+ : missionSubmissions.length > 0
+ ? 'error'
+ : undefined;
+
+ return (
+
+ );
+ })}
+
+
-
-
-

{
- navigate(`/home/contests`);
- }}
- />
-
- Контест #{contest.id}
-
-
-
{contest.attemptDurationMinutes ?? 0} минут
-
-
-
-
{`${solvedCount}/${totalCount} Решено`}
-
{
- navigate(`/contest/${contest.id}/submissions`);
- }}
- text="Мои посылки"
- />
-
-
-
-
- {(contest.missions ?? []).map((v, i) => {
- const missionSubmissions = submissions.filter(
- (s) => s.solution.missionId === v.id
- );
-
- const hasSuccess = missionSubmissions.some(
- (s) => s.solution.status == "Accepted: All tests passed"
- );
-
- console.log(missionSubmissions);
-
- const status = hasSuccess
- ? "success"
- : missionSubmissions.length > 0
- ? "error"
- : undefined;
-
- return (
-
- );
- })}
-
-
-
- );
+ );
};
export default ContestMissions;
diff --git a/src/views/home/contests/Filter.tsx b/src/views/home/contests/Filter.tsx
index ca01a9d..d56a78b 100644
--- a/src/views/home/contests/Filter.tsx
+++ b/src/views/home/contests/Filter.tsx
@@ -36,13 +36,17 @@ const Filters = () => {
text: 'ID',
},
]}
- onChange={(v) => console.log(v)}
+ onChange={(v) => {
+ v;
+ }}
/>
console.log(values)}
+ onChange={(values) => {
+ values;
+ }}
/>
);
diff --git a/src/views/home/group/Group.tsx b/src/views/home/group/Group.tsx
index 1642452..a982ba2 100644
--- a/src/views/home/group/Group.tsx
+++ b/src/views/home/group/Group.tsx
@@ -5,7 +5,6 @@ import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { fetchGroupById } from '../../../redux/slices/groups';
import GroupMenu from './GroupMenu';
import { Posts } from './posts/Posts';
-import { SearchInput } from '../../../components/input/SearchInput';
import { Chat } from './chat/Chat';
import { Contests } from './contests/Contests';
diff --git a/src/views/home/group/chat/Chat.tsx b/src/views/home/group/chat/Chat.tsx
index dc7bd71..0b9c939 100644
--- a/src/views/home/group/chat/Chat.tsx
+++ b/src/views/home/group/chat/Chat.tsx
@@ -1,8 +1,14 @@
-import { FC, useEffect, useRef } from 'react';
+import { FC, useEffect, useRef, useState } from 'react';
import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
import { setMenuActiveGroupPage } from '../../../../redux/slices/store';
-import { fetchGroupMessages } from '../../../../redux/slices/groupChat';
+import {
+ fetchGroupMessages,
+ sendGroupMessage,
+ setGroupChatStatus,
+} from '../../../../redux/slices/groupChat';
import { SearchInput } from '../../../../components/input/SearchInput';
+import { MessageItem } from './MessageItem';
+import { Send } from '../../../../assets/icons/input';
interface GroupChatProps {
groupId: number;
@@ -13,22 +19,27 @@ const CHUNK_SIZE = 10;
export const Chat: FC = ({ groupId }) => {
const dispatch = useAppDispatch();
const messages = useAppSelector((s) => s.groupchat.messages[groupId] || []);
- const hasMore = useAppSelector((s) => s.groupchat.hasMore[groupId]);
- const isInitialLoaded = useAppSelector(
- (s) => s.groupchat.isInitialLoaded[groupId],
+ const messagesState = useAppSelector(
+ (state) => state.groupchat.fetchMessages.status,
);
+ const lastMessageId = useAppSelector(
+ (state) => state.groupchat.lastMessage[groupId] || 0,
+ );
+ const user = useAppSelector((state) => state.auth);
+
+ const [text, setText] = useState('');
+ const [firstMessagesFetch, setFirctMessagesFetch] = useState(true);
const scrollRef = useRef(null);
+ // добавлено: ref для хранения предыдущей высоты
+ const prevHeightRef = useRef(0);
+
// активируем таб
useEffect(() => {
dispatch(setMenuActiveGroupPage('chat'));
}, []);
- useEffect(() => {
- console.log(messages);
- }, [messages]);
-
// первичная загрузка
useEffect(() => {
dispatch(
@@ -39,23 +50,112 @@ export const Chat: FC = ({ groupId }) => {
);
}, [groupId]);
- // автоскролл вниз после начальной загрузки
+ // автоскролл вниз после начальной загрузки (но не при догрузке)
useEffect(() => {
- if (!isInitialLoaded || !scrollRef.current) return;
- scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
- }, [isInitialLoaded, messages.length]);
+ const div = scrollRef.current;
+ if (!div) return;
+
+ // если prevHeightRef == 0 — значит это не догрузка, а обычная загрузка
+ if (prevHeightRef.current === 0) {
+ div.scrollTop = div.scrollHeight;
+ }
+ }, [messages.length]);
+
+ // добавлено: компенсирование скролла при догрузке
+ useEffect(() => {
+ const div = scrollRef.current;
+ if (!div) return;
+
+ if (prevHeightRef.current > 0) {
+ const diff = div.scrollHeight - prevHeightRef.current;
+ div.scrollTop = diff; // компенсируем смещение
+
+ prevHeightRef.current = 0; // сбрасываем
+ }
+ }, [messages]);
+
+ useEffect(() => {
+ if (messagesState == 'successful') {
+ dispatch(
+ setGroupChatStatus({ key: 'fetchMessages', status: 'idle' }),
+ );
+ }
+ if (messagesState == 'failed') {
+ dispatch(
+ setGroupChatStatus({ key: 'fetchMessages', status: 'idle' }),
+ );
+ }
+ }, [messagesState]);
+
+ const lastMessageIdRef = useRef(null);
+
+ useEffect(() => {
+ lastMessageIdRef.current = lastMessageId;
+ if (firstMessagesFetch) {
+ setFirctMessagesFetch(false);
+ dispatch(
+ fetchGroupMessages({
+ groupId,
+ afterMessageId: lastMessageIdRef.current,
+ timeoutSeconds: 10,
+ }),
+ );
+ }
+ }, [messages]);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ if (lastMessageIdRef.current === null) return;
+
+ dispatch(
+ fetchGroupMessages({
+ groupId,
+ afterMessageId: lastMessageIdRef.current,
+ timeoutSeconds: 10,
+ }),
+ );
+ }, 10000);
+
+ return () => clearInterval(interval);
+ }, [groupId]);
+
+ const handleSend = () => {
+ if (!text.trim()) return;
+
+ dispatch(
+ sendGroupMessage({
+ groupId,
+ content: text.trim(),
+ }),
+ ).then(() => {
+ setText('');
+ setTimeout(() => {
+ const div = scrollRef.current;
+ if (div) div.scrollTop = div.scrollHeight;
+ }, 0);
+ });
+ };
+
+ const handleEnter = (e: React.KeyboardEvent) => {
+ if (e.key === 'Enter') {
+ e.preventDefault();
+ handleSend();
+ }
+ };
// догрузка старых сообщений при скролле вверх
const handleScroll = () => {
const div = scrollRef.current;
- if (!div || !hasMore) return;
+ if (!div) return;
+
+ // если скролл в верхней точке
+ if (div.scrollTop === 0) {
+ prevHeightRef.current = div.scrollHeight; // запоминаем высоту до загрузки
- if (div.scrollTop < 100) {
const first = messages[0];
- if (!first) return;
+ if (!first || first.id == 1) return;
const beforeId = first.id - CHUNK_SIZE;
- console.log(beforeId);
dispatch(
fetchGroupMessages({
@@ -69,7 +169,7 @@ export const Chat: FC = ({ groupId }) => {
return (
-
+
= ({ groupId }) => {
ref={scrollRef}
onScroll={handleScroll}
>
-
- {messages.map((msg) => (
-
-
- {msg.authorUsername} {msg.id}
-
-
{msg.content}
-
- {new Date(msg.createdAt).toLocaleString()}
-
-
+
+ {messages.map((msg, i) => (
+
))}
- footer / input bar
+
);
diff --git a/src/views/home/group/chat/MessageItem.tsx b/src/views/home/group/chat/MessageItem.tsx
new file mode 100644
index 0000000..d6932e5
--- /dev/null
+++ b/src/views/home/group/chat/MessageItem.tsx
@@ -0,0 +1,81 @@
+import { FC } from 'react';
+import { useAppSelector } from '../../../../redux/hooks';
+
+function convertDate(isoString: string) {
+ const date = new Date(isoString);
+
+ const dd = String(date.getUTCDate()).padStart(2, '0');
+ const mm = String(date.getUTCMonth() + 1).padStart(2, '0');
+ const yyyy = date.getUTCFullYear();
+
+ const hh = String(date.getUTCHours()).padStart(2, '0');
+ const min = String(date.getUTCMinutes()).padStart(2, '0');
+
+ return `${dd}.${mm}.${yyyy} ${hh}:${min}`;
+}
+
+interface MessageItemProps {
+ id: number;
+ groupId: number;
+ authorId: number;
+ authorUsername: string;
+ createdAt: string;
+ message: string;
+ myMessage: boolean;
+}
+
+export const MessageItem: FC
= ({
+ authorId,
+ authorUsername,
+ createdAt,
+ message,
+ myMessage,
+}) => {
+ const members = useAppSelector(
+ (state) => state.groups.fetchGroupById.group?.members,
+ );
+ const member = members?.find((m) => m.userId === authorId);
+
+ return myMessage ? (
+
+
+
+
+ {convertDate(createdAt)}
+
+
+
+
+
+
+ ) : (
+
+
+
+
+
+
{authorUsername}
+
+ {member ? member.role : 'роль не найдена'}
+
+
+
+
+ {convertDate(createdAt)}
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/views/home/group/posts/ModalCreate.tsx b/src/views/home/group/posts/ModalCreate.tsx
index 39882ae..859e5b5 100644
--- a/src/views/home/group/posts/ModalCreate.tsx
+++ b/src/views/home/group/posts/ModalCreate.tsx
@@ -2,9 +2,7 @@ import { FC, useEffect, useState } from 'react';
import { Modal } from '../../../../components/modal/Modal';
import { PrimaryButton } from '../../../../components/button/PrimaryButton';
import { SecondaryButton } from '../../../../components/button/SecondaryButton';
-import { Input } from '../../../../components/input/Input';
import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
-import { createGroup } from '../../../../redux/slices/groups';
import MarkdownEditor from '../../../articleeditor/Editor';
import {
createPost,
diff --git a/src/views/home/group/posts/ModalUpdate.tsx b/src/views/home/group/posts/ModalUpdate.tsx
index 55ada02..24bafad 100644
--- a/src/views/home/group/posts/ModalUpdate.tsx
+++ b/src/views/home/group/posts/ModalUpdate.tsx
@@ -2,12 +2,9 @@ import { FC, useEffect, useState } from 'react';
import { Modal } from '../../../../components/modal/Modal';
import { PrimaryButton } from '../../../../components/button/PrimaryButton';
import { SecondaryButton } from '../../../../components/button/SecondaryButton';
-import { Input } from '../../../../components/input/Input';
import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
-import { createGroup } from '../../../../redux/slices/groups';
import MarkdownEditor, { MarkDownPattern } from '../../../articleeditor/Editor';
import {
- createPost,
deletePost,
fetchPostById,
setGroupFeedStatus,
@@ -55,7 +52,7 @@ const ModalUpdate: FC = ({
}, [statusDelete]);
useEffect(() => {
- dispatch(fetchPostById({ groupId, postId }));
+ if (postId) dispatch(fetchPostById({ groupId, postId }));
}, [postId]);
return (
diff --git a/src/views/home/group/posts/PostItem.tsx b/src/views/home/group/posts/PostItem.tsx
index 98e34d9..3042524 100644
--- a/src/views/home/group/posts/PostItem.tsx
+++ b/src/views/home/group/posts/PostItem.tsx
@@ -32,13 +32,10 @@ interface PostItemProps {
export const PostItem: FC = ({
id,
- groupId,
authorId,
authorUsername,
- name,
content,
createdAt,
- updatedAt,
isAdmin,
setModalUpdateActive,
setUpdatePostId,
diff --git a/src/views/home/group/posts/Posts.tsx b/src/views/home/group/posts/Posts.tsx
index e5cc012..0bee7e0 100644
--- a/src/views/home/group/posts/Posts.tsx
+++ b/src/views/home/group/posts/Posts.tsx
@@ -58,7 +58,9 @@ export const Posts: FC = ({ groupId }) => {
{}}
+ onChange={(v) => {
+ v;
+ }}
placeholder="Поиск сообщений"
/>
{isAdmin && (
diff --git a/src/views/home/groups/Filter.tsx b/src/views/home/groups/Filter.tsx
index 1d8a82f..d56a78b 100644
--- a/src/views/home/groups/Filter.tsx
+++ b/src/views/home/groups/Filter.tsx
@@ -36,13 +36,17 @@ const Filters = () => {
text: 'ID',
},
]}
- onChange={(v) => {}}
+ onChange={(v) => {
+ v;
+ }}
/>
{}}
+ onChange={(values) => {
+ values;
+ }}
/>
);
diff --git a/src/views/home/groups/GroupItem.tsx b/src/views/home/groups/GroupItem.tsx
index 4a979b0..a0a0d0b 100644
--- a/src/views/home/groups/GroupItem.tsx
+++ b/src/views/home/groups/GroupItem.tsx
@@ -44,7 +44,6 @@ const GroupItem: React.FC = ({
id,
name,
visible,
- role,
description,
setUpdateGroup,
setUpdateActive,
diff --git a/src/views/home/groups/ModalInvite.tsx b/src/views/home/groups/ModalInvite.tsx
index 7983671..f4fc8e3 100644
--- a/src/views/home/groups/ModalInvite.tsx
+++ b/src/views/home/groups/ModalInvite.tsx
@@ -4,7 +4,6 @@ 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';
import { toastSuccess } from '../../../lib/toastNotification';
interface ModalInviteProps {
@@ -54,9 +53,7 @@ const ModalInvite: FC = ({
await navigator.clipboard.writeText(inviteLink);
toastSuccess('Приглашение скопировано в буфер обмена!');
setActive(false);
- } catch (err) {
- console.error('Не удалось скопировать ссылку:', err);
- }
+ } catch (err) {}
};
return (
diff --git a/src/views/home/missions/Filter.tsx b/src/views/home/missions/Filter.tsx
index ca01a9d..d56a78b 100644
--- a/src/views/home/missions/Filter.tsx
+++ b/src/views/home/missions/Filter.tsx
@@ -36,13 +36,17 @@ const Filters = () => {
text: 'ID',
},
]}
- onChange={(v) => console.log(v)}
+ onChange={(v) => {
+ v;
+ }}
/>
console.log(values)}
+ onChange={(values) => {
+ values;
+ }}
/>
);
diff --git a/src/views/home/rightpanel/Articles.tsx b/src/views/home/rightpanel/Articles.tsx
index 48a9511..5c2827e 100644
--- a/src/views/home/rightpanel/Articles.tsx
+++ b/src/views/home/rightpanel/Articles.tsx
@@ -1,4 +1,4 @@
-import { FC } from 'react';
+import { FC, Fragment } from 'react';
export const ArticlesRightPanel: FC = () => {
const items = [
@@ -23,7 +23,7 @@ export const ArticlesRightPanel: FC = () => {
{items.map((v, i) => {
return (
- <>
+
{
{v.name}
@@ -32,7 +32,7 @@ export const ArticlesRightPanel: FC = () => {
{i + 1 != items.length && (
)}
- >
+
);
})}
diff --git a/src/views/home/rightpanel/Missions.tsx b/src/views/home/rightpanel/Missions.tsx
index 2d2abe8..fc94021 100644
--- a/src/views/home/rightpanel/Missions.tsx
+++ b/src/views/home/rightpanel/Missions.tsx
@@ -1,4 +1,4 @@
-import { FC } from 'react';
+import { FC, Fragment } from 'react';
import { cn } from '../../../lib/cn';
export const MissionsRightPanel: FC = () => {
@@ -32,7 +32,7 @@ export const MissionsRightPanel: FC = () => {
{items.map((v, i) => {
return (
- <>
+
{
{v.name}
@@ -60,7 +60,7 @@ export const MissionsRightPanel: FC = () => {
{i + 1 != items.length && (
)}
- >
+
);
})}
diff --git a/src/views/home/rightpanel/group/Group.tsx b/src/views/home/rightpanel/group/Group.tsx
index f1f9d7f..5c86644 100644
--- a/src/views/home/rightpanel/group/Group.tsx
+++ b/src/views/home/rightpanel/group/Group.tsx
@@ -1,4 +1,4 @@
-import { FC, useEffect, useState } from 'react';
+import { FC, Fragment, useEffect, useState } from 'react';
import { Navigate, useParams } from 'react-router-dom';
import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
import { fetchGroupById, GroupMember } from '../../../../redux/slices/groups';
@@ -54,7 +54,7 @@ export const GroupRightPanel: FC = () => {
{group?.members.map((v, i) => {
return (
- <>
+
{
@@ -101,7 +101,7 @@ export const GroupRightPanel: FC = () => {
{i + 1 != group?.members.length && (
)}
- >
+
);
})}
diff --git a/src/views/home/rightpanel/group/ModalLeave.tsx b/src/views/home/rightpanel/group/ModalLeave.tsx
index 5427b2f..c9339c3 100644
--- a/src/views/home/rightpanel/group/ModalLeave.tsx
+++ b/src/views/home/rightpanel/group/ModalLeave.tsx
@@ -2,13 +2,10 @@ import { FC, useEffect, useState } from 'react';
import { Modal } from '../../../../components/modal/Modal';
import { PrimaryButton } from '../../../../components/button/PrimaryButton';
import { SecondaryButton } from '../../../../components/button/SecondaryButton';
-import { Input } from '../../../../components/input/Input';
import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
import {
- deleteGroup,
removeGroupMember,
setGroupsStatus,
- updateGroup,
} from '../../../../redux/slices/groups';
import ConfirmModal from '../../../../components/modal/ConfirmModal';
import { useNavigate } from 'react-router-dom';
diff --git a/src/views/home/rightpanel/group/ModalUpdate.tsx b/src/views/home/rightpanel/group/ModalUpdate.tsx
index 3062cd2..c4223e9 100644
--- a/src/views/home/rightpanel/group/ModalUpdate.tsx
+++ b/src/views/home/rightpanel/group/ModalUpdate.tsx
@@ -2,16 +2,13 @@ import { FC, useEffect, useState } from 'react';
import { Modal } from '../../../../components/modal/Modal';
import { PrimaryButton } from '../../../../components/button/PrimaryButton';
import { SecondaryButton } from '../../../../components/button/SecondaryButton';
-import { Input } from '../../../../components/input/Input';
import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
import {
addGroupMember,
- deleteGroup,
fetchGroupById,
GroupMember,
removeGroupMember,
setGroupsStatus,
- updateGroup,
} from '../../../../redux/slices/groups';
import ConfirmModal from '../../../../components/modal/ConfirmModal';
import { DropDownList } from '../../../../components/drop-down-list/DropDownList';
@@ -31,7 +28,6 @@ const ModalUpdate: FC
= ({
active,
setActive,
groupId,
- userId,
user,
adminUser,
groupName,
@@ -76,7 +72,6 @@ const ModalUpdate: FC = ({
}, [statusUpdate]);
useEffect(() => {
- console.log(user);
if (user) {
setUserRole(
user?.role.includes('Creator') ? 'Creator' : user?.role,
diff --git a/src/views/mission/statement/Statement.tsx b/src/views/mission/statement/Statement.tsx
index e313c62..608db35 100644
--- a/src/views/mission/statement/Statement.tsx
+++ b/src/views/mission/statement/Statement.tsx
@@ -17,9 +17,7 @@ const CopyableDiv: FC = ({ content }) => {
try {
await navigator.clipboard.writeText(content);
alert('Скопировано!');
- } catch (err) {
- console.error('Ошибка копирования:', err);
- }
+ } catch (err) {}
};
return (
diff --git a/tsconfig.app.tsbuildinfo b/tsconfig.app.tsbuildinfo
deleted file mode 100644
index 22d984f..0000000
--- a/tsconfig.app.tsbuildinfo
+++ /dev/null
@@ -1 +0,0 @@
-{"root":["./src/app.tsx","./src/axios.ts","./src/main.tsx","./src/vite-env.d.ts","./src/assets/icons/account/index.ts","./src/assets/icons/auth/index.ts","./src/assets/icons/filters/index.ts","./src/assets/icons/group/index.ts","./src/assets/icons/groups/index.ts","./src/assets/icons/header/index.ts","./src/assets/icons/input/index.ts","./src/assets/icons/menu/index.ts","./src/assets/icons/missions/index.ts","./src/assets/logos/index.ts","./src/components/button/primarybutton.tsx","./src/components/button/reversebutton.tsx","./src/components/button/secondarybutton.tsx","./src/components/checkbox/checkbox.tsx","./src/components/drop-down-list/dropdownlist.tsx","./src/components/drop-down-list/filter.tsx","./src/components/drop-down-list/sorter.tsx","./src/components/input/daterangeinput.tsx","./src/components/input/input.tsx","./src/components/input/searchinput.tsx","./src/components/modal/confirmmodal.tsx","./src/components/modal/modal.tsx","./src/components/router/protectedroute.tsx","./src/components/switch/switch.tsx","./src/config/colors.ts","./src/hooks/useclickoutside.ts","./src/hooks/usequery.ts","./src/lib/cn.ts","./src/lib/toastnotification.ts","./src/pages/article.tsx","./src/pages/articleeditor.tsx","./src/pages/contesteditor.tsx","./src/pages/home.tsx","./src/pages/mission.tsx","./src/redux/hooks.ts","./src/redux/store.ts","./src/redux/slices/articles.ts","./src/redux/slices/auth.ts","./src/redux/slices/contests.ts","./src/redux/slices/groupfeed.ts","./src/redux/slices/groups.ts","./src/redux/slices/missions.ts","./src/redux/slices/store.ts","./src/redux/slices/submit.ts","./src/views/article/header.tsx","./src/views/articleeditor/editor.tsx","./src/views/articleeditor/header.tsx","./src/views/articleeditor/marckdownpreview.tsx","./src/views/home/account/account.tsx","./src/views/home/account/accoutmenu.tsx","./src/views/home/account/rightpanel.tsx","./src/views/home/account/articles/articlesblock.tsx","./src/views/home/account/contests/contests.tsx","./src/views/home/account/contests/contestsblock.tsx","./src/views/home/account/contests/mycontestitem.tsx","./src/views/home/account/contests/registercontestitem.tsx","./src/views/home/account/missions/missions.tsx","./src/views/home/account/missions/missionsblock.tsx","./src/views/home/account/missions/mymissionitem.tsx","./src/views/home/articles/articleitem.tsx","./src/views/home/articles/articles.tsx","./src/views/home/articles/filter.tsx","./src/views/home/auth/login.tsx","./src/views/home/auth/register.tsx","./src/views/home/contest/contest.tsx","./src/views/home/contest/missionitem.tsx","./src/views/home/contest/missions.tsx","./src/views/home/contest/submissionitem.tsx","./src/views/home/contest/submissions.tsx","./src/views/home/contests/contestitem.tsx","./src/views/home/contests/contests.tsx","./src/views/home/contests/contestsblock.tsx","./src/views/home/contests/filter.tsx","./src/views/home/contests/modalcreate.tsx","./src/views/home/group/group.tsx","./src/views/home/group/groupmenu.tsx","./src/views/home/group/chat/chat.tsx","./src/views/home/group/contests/contests.tsx","./src/views/home/group/posts/modalcreate.tsx","./src/views/home/group/posts/modalupdate.tsx","./src/views/home/group/posts/postitem.tsx","./src/views/home/group/posts/posts.tsx","./src/views/home/groupinviter/groupinvite.tsx","./src/views/home/groups/filter.tsx","./src/views/home/groups/groupitem.tsx","./src/views/home/groups/groups.tsx","./src/views/home/groups/groupsblock.tsx","./src/views/home/groups/modalcreate.tsx","./src/views/home/groups/modalinvite.tsx","./src/views/home/groups/modalupdate.tsx","./src/views/home/menu/menu.tsx","./src/views/home/menu/menuitem.tsx","./src/views/home/missions/filter.tsx","./src/views/home/missions/missionitem.tsx","./src/views/home/missions/missions.tsx","./src/views/home/missions/modalcreate.tsx","./src/views/home/rightpanel/articles.tsx","./src/views/home/rightpanel/missions.tsx","./src/views/home/rightpanel/group/group.tsx","./src/views/home/rightpanel/group/modalleave.tsx","./src/views/home/rightpanel/group/modalupdate.tsx","./src/views/mission/codeeditor/codeeditor.tsx","./src/views/mission/statement/header.tsx","./src/views/mission/statement/latextcontainer.tsx","./src/views/mission/statement/missionsubmissions.tsx","./src/views/mission/statement/statement.tsx","./src/views/mission/statement/submissionitem.tsx","./src/views/mission/submission/submission.tsx"],"errors":true,"version":"5.6.2"}
\ No newline at end of file