diff --git a/src/assets/icons/group/index.ts b/src/assets/icons/group/index.ts index 1faa753..0ee02d8 100644 --- a/src/assets/icons/group/index.ts +++ b/src/assets/icons/group/index.ts @@ -1,5 +1,6 @@ import Cup from './cup.svg'; import Home from './home.svg'; import MessageChat from './message-chat.svg'; +import Logout from './logout.svg'; -export { Cup, MessageChat, Home }; +export { Cup, MessageChat, Home, Logout }; diff --git a/src/assets/icons/group/logout.svg b/src/assets/icons/group/logout.svg new file mode 100644 index 0000000..1a4fb3a --- /dev/null +++ b/src/assets/icons/group/logout.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/input/receipt.png b/src/assets/icons/input/receipt.png deleted file mode 100644 index 0f7c554..0000000 Binary files a/src/assets/icons/input/receipt.png and /dev/null differ diff --git a/src/components/drop-down-list/DropDownList.tsx b/src/components/drop-down-list/DropDownList.tsx index 38f994e..d088bfb 100644 --- a/src/components/drop-down-list/DropDownList.tsx +++ b/src/components/drop-down-list/DropDownList.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { cn } from '../../lib/cn'; import { checkMark, chevroneDropDownList } from '../../assets/icons/input'; import { useClickOutside } from '../../hooks/useClickOutside'; @@ -14,6 +14,7 @@ interface DropDownListProps { onChange: (state: string) => void; defaultState?: DropDownListItem; items: DropDownListItem[]; + weight?: string; } export const DropDownList: React.FC = ({ @@ -22,6 +23,7 @@ export const DropDownList: React.FC = ({ onChange, defaultState, items = [{ text: '', value: '' }], + weight = 'w-[180px]', }) => { if (items.length == 0) items.push({ text: '', value: '' }); @@ -38,13 +40,19 @@ export const DropDownList: React.FC = ({ setActive(false); }); + useEffect(() => { + setValue(defaultState != undefined ? defaultState : items[0]); + }, [defaultState]); + + console.log(defaultState, items); return (
{ setActive(!active); @@ -63,8 +71,9 @@ export const DropDownList: React.FC = ({
void; + onConfirmClick: () => void; + title?: string; + message?: string; + confirmColor?: 'primary' | 'secondary' | 'error' | 'warning' | 'success'; + confirmText?: string; +} + +const ConfirmModal: FC = ({ + active, + setActive, + onConfirmClick, + title, + message, + confirmColor = 'secondary', + confirmText = 'Ок', +}) => { + return ( + +
+
{title}
+
{message}
+
+ { + onConfirmClick(); + setActive(false); + }} + text={confirmText} + color={confirmColor} + /> + { + setActive(false); + }} + text="Отмена" + /> +
+
+
+ ); +}; + +export default ConfirmModal; diff --git a/src/components/modal/Modal.tsx b/src/components/modal/Modal.tsx index a70eaf9..58e46d4 100644 --- a/src/components/modal/Modal.tsx +++ b/src/components/modal/Modal.tsx @@ -47,7 +47,7 @@ export const Modal: React.FC = ({ exit={modalbgVariants.closed} transition={{ duration: 0.15 }} className={cn( - ' fixed top-0 left-0 h-svh w-svw backdrop-filter transition-all z-50', + ' fixed top-0 left-0 h-svh w-svw backdrop-filter transition-[background-color,backdrop-filter,opacity] z-50', backdrop == 'blur' && open && 'backdrop-blur-sm', backdrop == 'opaque' && open && diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index aa588ae..364a38c 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -17,7 +17,7 @@ import Account from '../views/home/account/Account'; import ProtectedRoute from '../components/router/ProtectedRoute'; import { MissionsRightPanel } from '../views/home/rightpanel/Missions'; import { ArticlesRightPanel } from '../views/home/rightpanel/Articles'; -import { GroupRightPanel } from '../views/home/rightpanel/Group'; +import { GroupRightPanel } from '../views/home/rightpanel/group/Group'; import GroupInvite from '../views/home/groupinviter/GroupInvite'; import { toastError, diff --git a/src/views/home/group/Group.tsx b/src/views/home/group/Group.tsx index ef34d56..db7adcc 100644 --- a/src/views/home/group/Group.tsx +++ b/src/views/home/group/Group.tsx @@ -24,8 +24,6 @@ const Group: FC = () => { dispatch(fetchGroupById(groupId)); }, [groupId]); - console.log(group); - return (
{ useEffect(() => { dispatch(setMenuActiveGroupPage('chat')); }, []); - return <>; + return ( +
+ {' '} + Пока пусто :( +
+ ); }; diff --git a/src/views/home/group/contests/Contests.tsx b/src/views/home/group/contests/Contests.tsx index 39faea4..5df4e25 100644 --- a/src/views/home/group/contests/Contests.tsx +++ b/src/views/home/group/contests/Contests.tsx @@ -8,5 +8,10 @@ export const Contests = () => { useEffect(() => { dispatch(setMenuActiveGroupPage('contests')); }, []); - return <>; + return ( +
+ {' '} + Пока пусто :( +
+ ); }; diff --git a/src/views/home/groups/ModalInvite.tsx b/src/views/home/groups/ModalInvite.tsx index a00cfec..7983671 100644 --- a/src/views/home/groups/ModalInvite.tsx +++ b/src/views/home/groups/ModalInvite.tsx @@ -5,6 +5,7 @@ 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 { active: boolean; @@ -51,6 +52,7 @@ const ModalInvite: FC = ({ if (!inviteLink) return; try { await navigator.clipboard.writeText(inviteLink); + toastSuccess('Приглашение скопировано в буфер обмена!'); setActive(false); } catch (err) { console.error('Не удалось скопировать ссылку:', err); diff --git a/src/views/home/rightpanel/Group.tsx b/src/views/home/rightpanel/Group.tsx deleted file mode 100644 index 28b26fb..0000000 --- a/src/views/home/rightpanel/Group.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { FC } from 'react'; - -export const GroupRightPanel: FC = () => { - const items = [ - { - name: 'Игнат Герасименко', - role: 'Администратор', - }, - { - name: 'Алиса Макаренко', - role: 'Модератор', - }, - { - name: 'Федор Картман', - role: 'Модератор', - }, - { - name: 'Карина Механаджанович', - role: 'Участник', - }, - { - name: 'Михаил Ангрский', - role: 'Участник', - }, - { - name: 'newuser', - role: 'Участник (Вы)', - }, - ]; - return ( -
-
- Пользователи -
- - {items.map((v, i) => { - return ( - <> - { -
-
-
-
- {v.name} -
-
- {v.role} -
-
-
- } - {i + 1 != items.length && ( -
- )} - - ); - })} -
- ); -}; diff --git a/src/views/home/rightpanel/group/Group.tsx b/src/views/home/rightpanel/group/Group.tsx new file mode 100644 index 0000000..f1f9d7f --- /dev/null +++ b/src/views/home/rightpanel/group/Group.tsx @@ -0,0 +1,126 @@ +import { FC, useEffect, useState } from 'react'; +import { Navigate, useParams } from 'react-router-dom'; +import { useAppDispatch, useAppSelector } from '../../../../redux/hooks'; +import { fetchGroupById, GroupMember } from '../../../../redux/slices/groups'; +import { Edit } from '../../../../assets/icons/input'; +import { Logout } from '../../../../assets/icons/group'; +import ModalLeave from './ModalLeave'; +import ModalUpdate from './ModalUpdate'; + +export const GroupRightPanel: FC = () => { + const groupId = Number(useParams<{ groupId: string }>().groupId); + if (!groupId) { + return ; + } + + const dispatch = useAppDispatch(); + + const [user, setUser] = useState(); + const [myUser, setMyUser] = useState(); + const [isAdmin, setIsAdmin] = useState(false); + const [modalLeaveActive, setModalLeaveActive] = useState(false); + const [modalUpdateActive, setModalUpdateActive] = useState(false); + const { id: userId } = useAppSelector((state) => state.auth); + + const { group } = useAppSelector((state) => state.groups.fetchGroupById); + useEffect(() => { + dispatch(fetchGroupById(groupId)); + }, [groupId]); + + useEffect(() => { + if (!group) return; + + const isUserAdmin = + group.members?.some( + (m) => + Number(m.userId) === Number(userId) && + m.role.includes('Administrator'), + ) || false; + + setIsAdmin(isUserAdmin); + + const member = group.members?.find( + (m) => Number(m.userId) === Number(userId), + ); + + setMyUser(member); + }, [group, userId]); + + return ( +
+
+ Пользователи +
+ + {group?.members.map((v, i) => { + return ( + <> + { +
+
+
+
+ {v.username} +
+
+ {v.role + + (Number(userId) == v.userId + ? ' (Вы)' + : '')} +
+
+ {(isAdmin || Number(userId) == v.userId) && + !v.role.includes('Creator') && ( +
{ + if ( + Number(userId) == v.userId + ) { + setModalLeaveActive(true); + return; + } + if (isAdmin) { + setUser(v); + setModalUpdateActive(true); + return; + } + }} + > + {Number(userId) == v.userId ? ( + + ) : isAdmin ? ( + + ) : ( + <> + )} +
+ )} +
+ } + {i + 1 != group?.members.length && ( +
+ )} + + ); + })} + + + +
+ ); +}; diff --git a/src/views/home/rightpanel/group/ModalLeave.tsx b/src/views/home/rightpanel/group/ModalLeave.tsx new file mode 100644 index 0000000..5427b2f --- /dev/null +++ b/src/views/home/rightpanel/group/ModalLeave.tsx @@ -0,0 +1,107 @@ +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'; + +interface ModalLeaveProps { + active: boolean; + setActive: (value: boolean) => void; + groupId: number; + groupName?: string; + userId: number; +} + +const ModalLeave: FC = ({ + active, + setActive, + groupName, + groupId, + userId, +}) => { + const statusLeave = useAppSelector( + (state) => state.groups.removeGroupMember.status, + ); + const dispatch = useAppDispatch(); + const navigate = useNavigate(); + + const [modalConfirmActive, setModalConfirmActive] = + useState(false); + + useEffect(() => { + if (statusLeave == 'successful') { + dispatch( + setGroupsStatus({ key: 'removeGroupMember', status: 'idle' }), + ); + setActive(false); + navigate('/home/groups'); + } + }, [statusLeave]); + + return ( + <> + +
+
+ Вы действительно хотите покинуть группу: +
+
+ "{groupName}" #{groupId}? +
+
+ { + setModalConfirmActive(true); + }} + text={ + statusLeave == 'loading' + ? 'Покинуть...' + : 'Покинуть' + } + disabled={statusLeave == 'loading'} + color="error" + /> + { + setActive(false); + }} + text="Отмена" + /> +
+
+ { + dispatch( + removeGroupMember({ + groupId, + memberId: userId, + }), + ); + }} + /> +
+ + ); +}; + +export default ModalLeave; diff --git a/src/views/home/rightpanel/group/ModalUpdate.tsx b/src/views/home/rightpanel/group/ModalUpdate.tsx new file mode 100644 index 0000000..3062cd2 --- /dev/null +++ b/src/views/home/rightpanel/group/ModalUpdate.tsx @@ -0,0 +1,208 @@ +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'; +import { ReverseButton } from '../../../../components/button/ReverseButton'; + +interface ModalUpdateProps { + active: boolean; + setActive: (value: boolean) => void; + groupId: number; + userId: number; + user?: GroupMember; + adminUser?: GroupMember; + groupName?: string; +} + +const ModalUpdate: FC = ({ + active, + setActive, + groupId, + userId, + user, + adminUser, + groupName, +}) => { + const statusLeave = useAppSelector( + (state) => state.groups.removeGroupMember.status, + ); + const statusUpdate = useAppSelector( + (state) => state.groups.addGroupMember.status, + ); + const dispatch = useAppDispatch(); + + const [modalConfirmDeleteUser, setModalConfirmDeleteUser] = + useState(false); + const [modalConfirmRoleActive, setModalConfirmRoleActive] = + useState(false); + const [userRole, setUserRole] = useState(''); + + useEffect(() => { + if (active) { + } + }, [active]); + + useEffect(() => { + if (statusLeave == 'successful') { + dispatch( + setGroupsStatus({ key: 'removeGroupMember', status: 'idle' }), + ); + dispatch(fetchGroupById(groupId)); + setActive(false); + } + }, [statusLeave]); + + useEffect(() => { + if (statusUpdate == 'successful') { + dispatch( + setGroupsStatus({ key: 'addGroupMember', status: 'idle' }), + ); + dispatch(fetchGroupById(groupId)); + setActive(false); + } + }, [statusUpdate]); + + useEffect(() => { + console.log(user); + if (user) { + setUserRole( + user?.role.includes('Creator') ? 'Creator' : user?.role, + ); + } + }, [user]); + + const roles = [ + 'Member', + 'Administrator', + ...(adminUser?.role.includes('Creator') ? ['Creator'] : []), + ]; + + return ( + +
+
+ Управление участниками группы: +
+
+ "{groupName}" #{groupId} +
+
Пользователь: {user?.username}
+
Текущая роль: {user?.role}
+
+
+ { + return { text: v, value: v }; + })} + onChange={(v) => { + setUserRole(v); + }} + /> +
+ { + setModalConfirmRoleActive(true); + }} + text={ + statusUpdate == 'loading' + ? 'Назначить...' + : 'Назначить' + } + disabled={statusUpdate == 'loading'} + color="secondary" + /> +
+ +
+
+ Исключить пользователя? +
+ { + setModalConfirmDeleteUser(true); + }} + text={ + statusLeave == 'loading' + ? 'Исключить...' + : 'Исключить' + } + disabled={statusLeave == 'loading'} + color="error" + /> +
+ +
+ { + setActive(false); + }} + text="Отмена" + /> +
+
+ + { + if (user) { + dispatch( + removeGroupMember({ + groupId, + memberId: user.userId, + }), + ); + } + }} + /> + + { + if (user) { + dispatch( + addGroupMember({ + groupId, + userId: user.userId, + role: + userRole == 'Creator' + ? 'Administrator, Creator' + : userRole, + }), + ); + } + }} + /> +
+ ); +}; + +export default ModalUpdate; diff --git a/tsconfig.app.tsbuildinfo b/tsconfig.app.tsbuildinfo index f725851..22d984f 100644 --- a/tsconfig.app.tsbuildinfo +++ b/tsconfig.app.tsbuildinfo @@ -1 +1 @@ -{"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/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/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/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/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/groups/filter.tsx","./src/views/home/groups/group.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/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/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"],"version":"5.6.2"} \ No newline at end of file +{"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