diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index df90597..9df700a 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { useState } from 'react'
import { QueryClient, QueryClientProvider } from 'react-query'
import { Navigate, Route, Routes } from 'react-router-dom'
import './App.css'
@@ -28,6 +28,9 @@ import GradeCard from './views/GradeCard'
import Group from './views/coordinator/Group'
import dayjs from 'dayjs'
import WorkloadStatistics from './views/coordinator/WorkloadStatistics'
+import { MainContext } from './context/MainContext'
+import WithAxios from './context/WithAxios'
+import BaseModal from './components/BaseModal'
require('dayjs/locale/pl')
dayjs.locale('pl')
@@ -41,53 +44,60 @@ const queryClient = new QueryClient({
})
function App() {
+ const [isModalOpen, setIsModalOpen] = useState(false)
+
return (
-
-
- } />
- }>
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- }
- />
- } />
- }
- />
- }
- />
-
- }>
- } />
- } />
- } />
- } />
-
- }>
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
-
-
+
+
+
+
+ } />
+ }>
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ }
+ />
+ } />
+ }
+ />
+ }
+ />
+
+ }>
+ } />
+ } />
+ } />
+ } />
+
+ }>
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+
+
+
)
}
diff --git a/frontend/src/assets/svg/icon-error.svg b/frontend/src/assets/svg/icon-error.svg
new file mode 100644
index 0000000..0ddb22d
--- /dev/null
+++ b/frontend/src/assets/svg/icon-error.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/src/components/BaseModal.tsx b/frontend/src/components/BaseModal.tsx
new file mode 100644
index 0000000..fd1a7ac
--- /dev/null
+++ b/frontend/src/components/BaseModal.tsx
@@ -0,0 +1,72 @@
+import { ReactElement, useContext } from 'react'
+import Modal from 'react-modal'
+import { MainContext } from '../context/MainContext'
+import { ReactComponent as IconRemove } from '../assets/svg/icon-remove.svg'
+import { ReactComponent as IconError } from '../assets/svg/icon-error.svg'
+
+export interface ModalData {
+ title: string
+ message: string
+ icon?: ReactElement
+}
+
+export interface BaseModalProps {
+ isOpen: boolean
+ modalData?: ModalData | null
+}
+
+const customStyles = {
+ overlay: {
+ backgroundColor: 'rgba(125,125,125, 0.55)',
+ zIndex: 100,
+ },
+ content: {
+ top: '50%',
+ left: '50%',
+ right: 'auto',
+ bottom: 'auto',
+ marginRight: '-50%',
+ transform: 'translate(-50%, -50%)',
+ padding: '15px',
+ width: '460px',
+ height: '250px',
+ borderRadius: '25px',
+ backgroundColor: '#f7f7f7',
+ },
+}
+
+const BaseModal = ({ isOpen, modalData }: BaseModalProps) => {
+ Modal.setAppElement('#root')
+ const { setIsModalOpen } = useContext(MainContext)
+ const { icon, message, title } = modalData ?? {}
+ return (
+ <>
+ setIsModalOpen(false)}
+ >
+
+
+
+
+
+
+ Przepraszamy, wystąpił błąd.
Spróbuj ponownie.
+
+
+
+
+ >
+ )
+}
+
+export default BaseModal
diff --git a/frontend/src/context/MainContext.tsx b/frontend/src/context/MainContext.tsx
new file mode 100644
index 0000000..ad334df
--- /dev/null
+++ b/frontend/src/context/MainContext.tsx
@@ -0,0 +1,8 @@
+import React, { Dispatch, SetStateAction } from 'react'
+
+type ContextProps = {
+ isModalOpen: boolean
+ setIsModalOpen: Dispatch>
+}
+
+export const MainContext = React.createContext({} as ContextProps)
diff --git a/frontend/src/context/WithAxios.tsx b/frontend/src/context/WithAxios.tsx
new file mode 100644
index 0000000..26b10d7
--- /dev/null
+++ b/frontend/src/context/WithAxios.tsx
@@ -0,0 +1,29 @@
+import { FunctionComponent, useContext, useMemo } from 'react'
+import axiosInstance from '../api/axiosInstance'
+import { MainContext } from './MainContext'
+
+const WithAxios: FunctionComponent<{ children: React.ReactNode }> = ({
+ children,
+}) => {
+ const { setIsModalOpen } = useContext(MainContext)
+ useMemo(() => {
+ axiosInstance.interceptors.request.use(async (request) => {
+ return request
+ })
+ axiosInstance.interceptors.response.use(
+ (response) => {
+ return response
+ },
+ (error) => {
+ setIsModalOpen(false)
+ if (error.response?.status) {
+ setIsModalOpen(true)
+ }
+ return Promise.reject(error)
+ },
+ )
+ }, [setIsModalOpen])
+ return <>{children}>
+}
+
+export default WithAxios