mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
Refactor backend API calls and add toasts
This commit is contained in:
parent
eb045905d8
commit
484b1a9ea1
|
@ -12,12 +12,19 @@ import RegisterPage from './pages/RegisterPage';
|
|||
import ManualsPage from './pages/ManualsPage';
|
||||
import Footer from './components/Footer';
|
||||
import RSFormCreatePage from './pages/RSFormCreatePage';
|
||||
import ToasterThemed from './components/ToasterThemed';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className='antialiased bg-gray-50 dark:bg-gray-800'>
|
||||
<Navigation />
|
||||
<main className='min-h-[calc(100vh-107px)] px-2 h-fit'>
|
||||
<ToasterThemed
|
||||
className='mt-[4rem]'
|
||||
autoClose={3000}
|
||||
draggable={false}
|
||||
limit={5}
|
||||
/>
|
||||
<Routes>
|
||||
<Route path='/' element={ <HomePage/>} />
|
||||
|
||||
|
|
179
rsconcept/frontend/src/backendAPI.ts
Normal file
179
rsconcept/frontend/src/backendAPI.ts
Normal file
|
@ -0,0 +1,179 @@
|
|||
import axios, { AxiosResponse } from 'axios'
|
||||
import { config } from './constants'
|
||||
import { ErrorInfo } from './components/BackendError'
|
||||
import { toast } from 'react-toastify'
|
||||
import { ICurrentUser, IRSForm, IUserInfo, IUserProfile } from './models'
|
||||
|
||||
export type BackendCallback = (response: AxiosResponse) => void;
|
||||
|
||||
export interface IFrontRequest {
|
||||
onSucccess?: BackendCallback
|
||||
onError?: (error: ErrorInfo) => void
|
||||
setLoading?: (loading: boolean) => void
|
||||
showError?: boolean
|
||||
data?: any
|
||||
}
|
||||
|
||||
interface IAxiosRequest {
|
||||
endpoint: string
|
||||
request?: IFrontRequest
|
||||
title?: string
|
||||
}
|
||||
|
||||
// ================= Export API ==============
|
||||
export async function postLogin(request?: IFrontRequest) {
|
||||
AxiosPost({
|
||||
title: 'Login',
|
||||
endpoint: `${config.url.AUTH}login`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function getAuth(request?: IFrontRequest) {
|
||||
AxiosGet<ICurrentUser>({
|
||||
title: 'Current user',
|
||||
endpoint: `${config.url.AUTH}auth`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function getProfile(request?: IFrontRequest) {
|
||||
AxiosGet<IUserProfile>({
|
||||
title: 'Current user profile',
|
||||
endpoint: `${config.url.AUTH}profile`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function postLogout(request?: IFrontRequest) {
|
||||
AxiosPost({
|
||||
title: 'Logout',
|
||||
endpoint: `${config.url.AUTH}logout`,
|
||||
request: request
|
||||
});
|
||||
};
|
||||
|
||||
export async function postSignup(request?: IFrontRequest) {
|
||||
AxiosPost({
|
||||
title: 'Register user',
|
||||
endpoint: `${config.url.AUTH}signup`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function getActiveUsers(request?: IFrontRequest) {
|
||||
AxiosGet<IUserInfo>({
|
||||
title: 'Active users list',
|
||||
endpoint: `${config.url.AUTH}active-users`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function getRSForms(request?: IFrontRequest) {
|
||||
AxiosGet<IRSForm[]>({
|
||||
title: `RSForms list`,
|
||||
endpoint: `${config.url.BASE}rsforms/`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function postNewRSForm(request?: IFrontRequest) {
|
||||
AxiosPost({
|
||||
title: `New RSForm`,
|
||||
endpoint: `${config.url.BASE}rsforms/create-detailed/`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function getRSFormDetails(target: string, request?: IFrontRequest) {
|
||||
AxiosGet<IRSForm>({
|
||||
title: `RSForm details for id=${target}`,
|
||||
endpoint: `${config.url.BASE}rsforms/${target}/details/`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function patchRSForm(target: string, request?: IFrontRequest) {
|
||||
AxiosPatch({
|
||||
title: `RSForm id=${target}`,
|
||||
endpoint: `${config.url.BASE}rsforms/${target}/`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteRSForm(target: string, request?: IFrontRequest) {
|
||||
AxiosDelete({
|
||||
title: `RSForm id=${target}`,
|
||||
endpoint: `${config.url.BASE}rsforms/${target}/`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export async function postClaimRSForm(target: string, request?: IFrontRequest) {
|
||||
AxiosPost({
|
||||
title: `Claim on RSForm id=${target}`,
|
||||
endpoint: `${config.url.BASE}rsforms/${target}/claim/`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
// ====== Helper functions ===========
|
||||
function AxiosGet<ReturnType>({endpoint, request, title}: IAxiosRequest) {
|
||||
if (title) console.log(`[[${title}]] requested`);
|
||||
if (request?.setLoading) request?.setLoading(true);
|
||||
axios.get<ReturnType>(endpoint)
|
||||
.then(function (response) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.onSucccess) request.onSucccess(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.showError) toast.error(error.message);
|
||||
if (request?.onError) request.onError(error);
|
||||
});
|
||||
}
|
||||
|
||||
function AxiosPost({endpoint, request, title}: IAxiosRequest) {
|
||||
if (title) console.log(`[[${title}]] posted`);
|
||||
if (request?.setLoading) request?.setLoading(true);
|
||||
axios.post(endpoint, request?.data)
|
||||
.then(function (response) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.onSucccess) request.onSucccess(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.showError) toast.error(error.message);
|
||||
if (request?.onError) request.onError(error);
|
||||
});
|
||||
}
|
||||
|
||||
function AxiosDelete({endpoint, request, title}: IAxiosRequest) {
|
||||
if (title) console.log(`[[${title}]] is being deleted`);
|
||||
if (request?.setLoading) request?.setLoading(true);
|
||||
axios.delete(endpoint)
|
||||
.then(function (response) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.onSucccess) request.onSucccess(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.showError) toast.error(error.message);
|
||||
if (request?.onError) request.onError(error);
|
||||
});
|
||||
}
|
||||
|
||||
function AxiosPatch({endpoint, request, title}: IAxiosRequest) {
|
||||
if (title) console.log(`[[${title}]] is being patrially updated`);
|
||||
if (request?.setLoading) request?.setLoading(true);
|
||||
axios.patch(endpoint, request?.data)
|
||||
.then(function (response) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.onSucccess) request.onSucccess(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (request?.setLoading) request?.setLoading(false);
|
||||
if (request?.showError) toast.error(error.message);
|
||||
if (request?.onError) request.onError(error);
|
||||
});
|
||||
}
|
14
rsconcept/frontend/src/components/ToasterThemed.tsx
Normal file
14
rsconcept/frontend/src/components/ToasterThemed.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { ToastContainer, ToastContainerProps } from 'react-toastify';
|
||||
import { useTheme } from '../context/ThemeContext';
|
||||
|
||||
function ToasterThemed({theme, ...props}: ToastContainerProps) {
|
||||
const { darkMode } = useTheme();
|
||||
|
||||
return (
|
||||
<ToastContainer
|
||||
theme={ darkMode ? 'dark' : 'light'}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export default ToasterThemed;
|
|
@ -1,17 +1,15 @@
|
|||
import axios from 'axios';
|
||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { config } from '../constants';
|
||||
import { ICurrentUser, IUserSignupData } from '../models';
|
||||
import { ErrorInfo } from '../components/BackendError';
|
||||
import useLocalStorage from '../hooks/useLocalStorage';
|
||||
import { getAuth, postLogin, postLogout, postSignup } from '../backendAPI';
|
||||
|
||||
|
||||
interface IAuthContext {
|
||||
user: ICurrentUser | undefined
|
||||
login: (username: string, password: string, onSuccess?: Function) => void
|
||||
logout: (onSuccess?: Function) => void
|
||||
signup: (data: IUserSignupData, onSuccess?: Function) => void
|
||||
login: (username: string, password: string, onSuccess?: () => void) => void
|
||||
logout: (onSuccess?: () => void) => void
|
||||
signup: (data: IUserSignupData, onSuccess?: () => void) => void
|
||||
loading: boolean
|
||||
error: ErrorInfo
|
||||
setError: (error: ErrorInfo) => void
|
||||
|
@ -38,74 +36,55 @@ export const AuthState = ({ children }: AuthStateProps) => {
|
|||
|
||||
const loadCurrentUser = useCallback(
|
||||
async () => {
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
console.log('Current user requested');
|
||||
axios.get<ICurrentUser>(`${config.url.AUTH}auth`)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
getAuth({
|
||||
onError: error => setUser(undefined),
|
||||
onSucccess: response => {
|
||||
if (response.data.id) {
|
||||
setUser(response.data);
|
||||
} else {
|
||||
setUser(undefined)
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setUser(undefined);
|
||||
setError(error);
|
||||
}
|
||||
});
|
||||
}, [setUser]
|
||||
);
|
||||
|
||||
async function login(uname: string, pw: string, onSuccess?: Function) {
|
||||
setLoading(true);
|
||||
async function login(uname: string, pw: string, onSuccess?: () => void) {
|
||||
setError(undefined);
|
||||
axios.post(`${config.url.AUTH}login`, {username: uname, password: pw})
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
postLogin({
|
||||
data: {username: uname, password: pw},
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => setError(error),
|
||||
onSucccess: response => {
|
||||
loadCurrentUser();
|
||||
if(onSuccess) {
|
||||
onSuccess();
|
||||
if(onSuccess) onSuccess();
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setError(error);
|
||||
});
|
||||
}
|
||||
|
||||
async function logout(onSuccess?: Function) {
|
||||
setLoading(true);
|
||||
async function logout(onSuccess?: () => void) {
|
||||
setError(undefined);
|
||||
axios.post(`${config.url.AUTH}logout`)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
postLogout({
|
||||
showError: true,
|
||||
onSucccess: response => {
|
||||
loadCurrentUser();
|
||||
if(onSuccess) {
|
||||
onSuccess();
|
||||
if(onSuccess) onSuccess();
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setError(error);
|
||||
});
|
||||
}
|
||||
|
||||
async function signup(data: IUserSignupData, onSuccess?: Function) {
|
||||
setLoading(true);
|
||||
async function signup(data: IUserSignupData, onSuccess?: () => void) {
|
||||
setError(undefined);
|
||||
axios.post(`${config.url.AUTH}signup`, data)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
postSignup({
|
||||
data: data,
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => setError(error),
|
||||
onSucccess: response => {
|
||||
loadCurrentUser();
|
||||
if(onSuccess) {
|
||||
onSuccess();
|
||||
if(onSuccess) onSuccess();
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@ import { IConstituenta, IRSForm } from '../models';
|
|||
import { useRSFormDetails } from '../hooks/useRSFormDetails';
|
||||
import { ErrorInfo } from '../components/BackendError';
|
||||
import { useAuth } from './AuthContext';
|
||||
import axios from 'axios';
|
||||
import { config } from '../constants';
|
||||
import { BackendCallback, deleteRSForm, patchRSForm, postClaimRSForm } from '../backendAPI';
|
||||
|
||||
interface IRSFormContext {
|
||||
schema?: IRSForm
|
||||
|
@ -17,9 +16,9 @@ interface IRSFormContext {
|
|||
|
||||
setActive: (cst: IConstituenta) => void
|
||||
reload: () => void
|
||||
upload: (data: any, callback: Function) => void
|
||||
destroy: (callback: Function) => void
|
||||
claim: (callback: Function) => void
|
||||
upload: (data: any, callback?: BackendCallback) => void
|
||||
destroy: (callback: BackendCallback) => void
|
||||
claim: (callback: BackendCallback) => void
|
||||
}
|
||||
|
||||
export const RSFormContext = createContext<IRSFormContext>({
|
||||
|
@ -58,49 +57,34 @@ export const RSFormState = ({ id, children }: RSFormStateProps) => {
|
|||
}
|
||||
}, [schema])
|
||||
|
||||
async function upload(data: any, callback?: Function) {
|
||||
console.log(`Update rsform with ${data}`);
|
||||
data['id'] = {id}
|
||||
async function upload(data: any, callback?: BackendCallback) {
|
||||
setError(undefined);
|
||||
setProcessing(true);
|
||||
axios.patch(`${config.url.BASE}rsforms/${id}/`, data)
|
||||
.then(function (response) {
|
||||
setProcessing(false);
|
||||
if (callback) callback(response.data);
|
||||
})
|
||||
.catch(function (error) {
|
||||
setProcessing(false);
|
||||
setError(error);
|
||||
patchRSForm(id, {
|
||||
data: data,
|
||||
showError: true,
|
||||
setLoading: setProcessing,
|
||||
onError: error => setError(error),
|
||||
onSucccess: callback
|
||||
});
|
||||
}
|
||||
|
||||
async function destroy(callback?: Function) {
|
||||
console.log(`Deleting rsform ${id}`);
|
||||
async function destroy(callback: BackendCallback) {
|
||||
setError(undefined);
|
||||
setProcessing(true);
|
||||
axios.delete(`${config.url.BASE}rsforms/${id}/`)
|
||||
.then(function (response) {
|
||||
setProcessing(false);
|
||||
if (callback) callback();
|
||||
})
|
||||
.catch(function (error) {
|
||||
setProcessing(false);
|
||||
setError(error);
|
||||
deleteRSForm(id, {
|
||||
showError: true,
|
||||
setLoading: setProcessing,
|
||||
onError: error => setError(error),
|
||||
onSucccess: callback
|
||||
});
|
||||
}
|
||||
|
||||
async function claim(callback?: Function) {
|
||||
console.log(`Claiming rsform ${id}`);
|
||||
async function claim(callback: BackendCallback) {
|
||||
setError(undefined);
|
||||
setProcessing(true);
|
||||
axios.post(`${config.url.BASE}rsforms/${id}/claim/`)
|
||||
.then(function (response) {
|
||||
setProcessing(false);
|
||||
if (callback) callback();
|
||||
})
|
||||
.catch(function (error) {
|
||||
setProcessing(false);
|
||||
setError(error);
|
||||
postClaimRSForm(id, {
|
||||
showError: true,
|
||||
setLoading: setProcessing,
|
||||
onError: error => setError(error),
|
||||
onSucccess: callback
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
import axios from 'axios'
|
||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
|
||||
import { IUserInfo } from '../models'
|
||||
import { config } from '../constants'
|
||||
import { ErrorInfo } from '../components/BackendError'
|
||||
import { getActiveUsers } from '../backendAPI'
|
||||
|
||||
|
||||
interface IUsersContext {
|
||||
users: IUserInfo[]
|
||||
error: ErrorInfo
|
||||
loading: boolean
|
||||
reload: () => void
|
||||
getUserLabel: (userID?: number) => string
|
||||
}
|
||||
|
||||
export const UsersContext = createContext<IUsersContext>({
|
||||
users: [],
|
||||
error: undefined,
|
||||
loading: false,
|
||||
reload: () => {},
|
||||
getUserLabel: () => ''
|
||||
})
|
||||
|
@ -27,8 +21,6 @@ interface UsersStateProps {
|
|||
|
||||
export const UsersState = ({ children }: UsersStateProps) => {
|
||||
const [users, setUsers] = useState<IUserInfo[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<ErrorInfo>(undefined);
|
||||
|
||||
const getUserLabel = (userID?: number) => {
|
||||
const user = users.find(({id}) => id === userID);
|
||||
|
@ -49,18 +41,12 @@ export const UsersState = ({ children }: UsersStateProps) => {
|
|||
|
||||
const reload = useCallback(
|
||||
async () => {
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
console.log('Profile requested');
|
||||
axios.get<IUserInfo[]>(`${config.url.AUTH}active-users`)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
setUsers(response.data);
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setUsers([]);
|
||||
setError(error);
|
||||
getActiveUsers({
|
||||
showError: true,
|
||||
onError: error => setUsers([]),
|
||||
onSucccess: response => {
|
||||
setUsers(response ? response.data : []);
|
||||
}
|
||||
});
|
||||
}, [setUsers]
|
||||
);
|
||||
|
@ -72,7 +58,6 @@ export const UsersState = ({ children }: UsersStateProps) => {
|
|||
return (
|
||||
<UsersContext.Provider value={{
|
||||
users,
|
||||
error, loading,
|
||||
reload, getUserLabel
|
||||
}}>
|
||||
{ children }
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import axios from 'axios'
|
||||
import { IUserProfile } from '../models'
|
||||
import { config } from '../constants'
|
||||
import { ErrorInfo } from '../components/BackendError'
|
||||
|
||||
function useAPI() {
|
||||
async function getProfile(
|
||||
args?: {onSucccess: Function, onError: Function}) {
|
||||
// setError(undefined);
|
||||
// setLoading(true);
|
||||
// console.log('Profile requested');
|
||||
// axios.get<IUserProfile>(`${config.url.AUTH}profile`)
|
||||
// .then(function (response) {
|
||||
// setLoading(false);
|
||||
// return response.data;
|
||||
// })
|
||||
// .catch(function (error) {
|
||||
// setLoading(false);
|
||||
// setError(error);
|
||||
// return undefined;
|
||||
// });
|
||||
}
|
||||
|
||||
return {
|
||||
getProfile
|
||||
};
|
||||
}
|
||||
|
||||
export default useAPI;
|
|
@ -1,33 +1,30 @@
|
|||
import axios from 'axios'
|
||||
import { useState } from 'react'
|
||||
import { config } from '../constants'
|
||||
import { ErrorInfo } from '../components/BackendError';
|
||||
import { postNewRSForm } from '../backendAPI';
|
||||
|
||||
function useNewRSForm({callback}: {callback: (newID: string) => void}) {
|
||||
function useNewRSForm() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<ErrorInfo>(undefined);
|
||||
|
||||
async function createNew({data, file}: {data: any, file?: File}) {
|
||||
async function createSchema({data, file, onSuccess}: {
|
||||
data: any, file?: File,
|
||||
onSuccess: (newID: string) => void
|
||||
}) {
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
if (file) {
|
||||
data['file']=file;
|
||||
data['fileName']=file.name;
|
||||
data['file'] = file;
|
||||
data['fileName'] = file.name;
|
||||
}
|
||||
axios.post(`${config.url.BASE}rsforms/create-detailed/`, data)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
if(callback) {
|
||||
callback(response.data.id);
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setError(error);
|
||||
postNewRSForm({
|
||||
data: data,
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => setError(error),
|
||||
onSucccess: response => onSuccess(response.data.id)
|
||||
});
|
||||
}
|
||||
|
||||
return { createNew, error, setError, loading };
|
||||
return { createSchema, error, setError, loading };
|
||||
}
|
||||
|
||||
export default useNewRSForm;
|
|
@ -1,8 +1,7 @@
|
|||
import axios from 'axios'
|
||||
import { config } from '../constants';
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { IRSForm } from '../models'
|
||||
import { ErrorInfo } from '../components/BackendError';
|
||||
import { getRSFormDetails } from '../backendAPI';
|
||||
|
||||
export function useRSFormDetails({target}: {target?: string}) {
|
||||
const [schema, setSchema] = useState<IRSForm | undefined>();
|
||||
|
@ -10,21 +9,16 @@ export function useRSFormDetails({target}: {target?: string}) {
|
|||
const [error, setError] = useState<ErrorInfo>(undefined);
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
console.log(`Requesting rsform ${target}`);
|
||||
setError(undefined);
|
||||
setSchema(undefined);
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
axios.get<IRSForm>(`${config.url.BASE}rsforms/${target}/details/`)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
setSchema(response.data);
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setError(error);
|
||||
getRSFormDetails(target, {
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => setError(error),
|
||||
onSucccess: response => setSchema(response.data)
|
||||
});
|
||||
}, [target]);
|
||||
|
||||
|
|
|
@ -1,32 +1,25 @@
|
|||
import axios from 'axios'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { IRSForm } from '../models'
|
||||
import { config } from '../constants'
|
||||
import { ErrorInfo } from '../components/BackendError';
|
||||
import { getRSForms } from '../backendAPI';
|
||||
|
||||
export function useRSForms() {
|
||||
const [rsforms, setRSForms] = useState<IRSForm[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<ErrorInfo>(undefined);
|
||||
|
||||
async function fetchRSForms() {
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
console.log('RSForms requested');
|
||||
axios.get<IRSForm[]>(`${config.url.BASE}rsforms/`)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
setRSForms(response.data);
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setError(error);
|
||||
const fetchData = useCallback(async () => {
|
||||
getRSForms({
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => setError(error),
|
||||
onSucccess: response => setRSForms(response.data)
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchRSForms();
|
||||
}, [])
|
||||
fetchData();
|
||||
}, [fetchData])
|
||||
|
||||
return { rsforms, error, loading };
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
import axios from 'axios'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { IUserProfile } from '../models'
|
||||
import { config } from '../constants'
|
||||
import { ErrorInfo } from '../components/BackendError'
|
||||
import { getProfile } from '../backendAPI'
|
||||
|
||||
|
||||
export function useUserProfile() {
|
||||
|
@ -13,17 +12,12 @@ export function useUserProfile() {
|
|||
const fetchUser = useCallback(
|
||||
async () => {
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
console.log('Profile requested');
|
||||
axios.get<IUserProfile>(`${config.url.AUTH}profile`)
|
||||
.then(function (response) {
|
||||
setLoading(false);
|
||||
setUser(response.data);
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoading(false);
|
||||
setUser(undefined);
|
||||
setError(error);
|
||||
getProfile({
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => setError(error),
|
||||
onSucccess: response => setUser(response.data)
|
||||
});
|
||||
}, [setUser]
|
||||
)
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
import React from 'react';
|
||||
import axios from 'axios';
|
||||
import './index.css';
|
||||
import 'react-toastify/dist/ReactToastify.css';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import { AuthState } from './context/AuthContext';
|
||||
import { ThemeState } from './context/ThemeContext';
|
||||
|
|
|
@ -20,6 +20,7 @@ function LoginPage() {
|
|||
useEffect(() => {
|
||||
const name = new URLSearchParams(search).get('username');
|
||||
setUsername(name || '');
|
||||
setPassword('');
|
||||
}, [search]);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -37,7 +38,7 @@ function LoginPage() {
|
|||
<div className='container py-2'> { user ?
|
||||
<InfoMessage message={`Вы вошли в систему как ${user.username}`} />
|
||||
:
|
||||
<Form title='Ввод данных пользователя' onSubmit={handleSubmit} widthClass='max-w-sm'>
|
||||
<Form title='Ввод данных пользователя' onSubmit={handleSubmit} widthClass='w-[20rem]'>
|
||||
<TextInput id='username'
|
||||
label='Имя пользователя'
|
||||
required
|
||||
|
@ -49,10 +50,11 @@ function LoginPage() {
|
|||
label='Пароль'
|
||||
required
|
||||
type='password'
|
||||
value={password}
|
||||
onChange={event => setPassword(event.target.value)}
|
||||
/>
|
||||
|
||||
<div className='flex items-center justify-between mt-4 mb-2'>
|
||||
<div className='flex items-center justify-between mt-4'>
|
||||
<SubmitButton text='Вход' loading={loading}/>
|
||||
<TextURL text='Восстановить пароль...' href='restore-password' />
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,7 @@ import { useNavigate } from 'react-router-dom';
|
|||
import TextArea from '../components/Common/TextArea';
|
||||
import Checkbox from '../components/Common/Checkbox';
|
||||
import FileInput from '../components/Common/FileInput';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
function RSFormCreatePage() {
|
||||
const navigate = useNavigate();
|
||||
|
@ -29,8 +30,11 @@ function RSFormCreatePage() {
|
|||
}
|
||||
}
|
||||
|
||||
const onSuccess = (newID: string) => navigate(`/rsforms/${newID}`);
|
||||
const { createNew, error, setError, loading } = useNewRSForm({callback: onSuccess})
|
||||
const onSuccess = (newID: string) => {
|
||||
toast.success('Схема успешно создана');
|
||||
navigate(`/rsforms/${newID}`);
|
||||
}
|
||||
const { createSchema, error, setError, loading } = useNewRSForm()
|
||||
|
||||
useEffect(() => {
|
||||
setError(undefined)
|
||||
|
@ -45,7 +49,11 @@ function RSFormCreatePage() {
|
|||
'comment': comment,
|
||||
'is_common': common,
|
||||
};
|
||||
createNew({data: data, file: file});
|
||||
createSchema({
|
||||
data: data,
|
||||
file: file,
|
||||
onSuccess: onSuccess
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ import TextInput from '../../components/Common/TextInput';
|
|||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import Button from '../../components/Common/Button';
|
||||
import { CrownIcon, DownloadIcon, DumpBinIcon, UploadIcon } from '../../components/Icons';
|
||||
import { CrownIcon, DownloadIcon, DumpBinIcon } from '../../components/Icons';
|
||||
import { useUsers } from '../../context/UsersContext';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import FileInput from '../../components/Common/FileInput';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
function RSFormCard() {
|
||||
const navigate = useNavigate();
|
||||
|
@ -22,8 +22,6 @@ function RSFormCard() {
|
|||
const [comment, setComment] = useState('');
|
||||
const [common, setCommon] = useState(false);
|
||||
|
||||
const onSuccess = (data: any) => reload();
|
||||
|
||||
useEffect(() => {
|
||||
setTitle(schema!.title)
|
||||
setAlias(schema!.alias)
|
||||
|
@ -40,28 +38,34 @@ function RSFormCard() {
|
|||
'comment': comment,
|
||||
'is_common': common,
|
||||
};
|
||||
upload(data, onSuccess);
|
||||
upload(data, () => {
|
||||
toast.success('Изменения сохранены');
|
||||
reload();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
if (window.confirm('Вы уверены, что хотите удалить данную схему?')) {
|
||||
destroy(() => navigate('/rsforms?filter=owned'))
|
||||
destroy(() => {
|
||||
toast.success('Схема удалена');
|
||||
navigate('/rsforms?filter=owned');
|
||||
});
|
||||
}
|
||||
}, [destroy, navigate]);
|
||||
|
||||
const handleClaimOwner = useCallback(() => {
|
||||
if (window.confirm('Вы уверены, что хотите стать владельцем данной схемы?')) {
|
||||
claim(() => reload());
|
||||
claim(() => {
|
||||
toast.success('Вы стали владельцем схемы');
|
||||
reload();
|
||||
});
|
||||
}
|
||||
}, [claim, reload]);
|
||||
|
||||
const handleUpload = useCallback(() => {
|
||||
|
||||
}, []);
|
||||
|
||||
const handleDownload = useCallback(() => {
|
||||
|
||||
// TODO: implement file download
|
||||
toast.info('Загрузка в разработке');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
|
@ -40,11 +40,11 @@ function RegisterPage() {
|
|||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='container py-2'>
|
||||
{ success &&
|
||||
<div className='flex flex-col items-center'>
|
||||
<InfoMessage message={`Вы успешно зарегистрировали пользователя ${username}`}/>
|
||||
<TextURL text='Войти в аккаунт' href={`login?username=${username}`}/>
|
||||
<TextURL text='Войти в аккаунт' href={`/login?username=${username}`}/>
|
||||
</div>}
|
||||
{ !success && user &&
|
||||
<InfoMessage message={`Вы вошли в систему как ${user.username}. Если хотите зарегистрировать нового пользователя, выйдите из системы (меню в правом верхнем углу экрана)`} /> }
|
||||
|
@ -90,7 +90,7 @@ function RegisterPage() {
|
|||
{ error && <BackendError error={error} />}
|
||||
</Form>
|
||||
}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user