import axios, { AxiosRequestConfig } from 'axios' import { toast } from 'react-toastify' import { type ErrorInfo } from '../components/BackendError' import { FilterType, RSFormsFilter } from '../hooks/useRSForms' import { config } from './constants' import { ExpressionParse, IConstituentaList, IConstituentaMeta, ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstUpdateData, ICurrentUser, IRSFormCreateData, IRSFormData, IRSFormMeta, IRSFormUpdateData, IRSFormUploadData, IUserInfo, IUserLoginData, IUserProfile, IUserSignupData, RSExpression } from './models' // ================ Data transfer types ================ export type DataCallback = (data: ResponseData) => void; interface IFrontRequest { data?: RequestData onSuccess?: DataCallback onError?: (error: ErrorInfo) => void setLoading?: (loading: boolean) => void showError?: boolean } export interface FrontPush extends IFrontRequest { data: DataType } export interface FrontPull extends IFrontRequest{ onSuccess: DataCallback } export interface FrontExchange extends IFrontRequest{ data: RequestData onSuccess: DataCallback } export interface FrontAction extends IFrontRequest{} interface IAxiosRequest { endpoint: string request: IFrontRequest title: string options?: AxiosRequestConfig } // ==================== API ==================== export function getAuth(request: FrontPull) { AxiosGet({ title: 'Current user', endpoint: `${config.url.AUTH}auth`, request: request }); } export function postLogin(request: FrontPush) { AxiosPost({ title: 'Login', endpoint: `${config.url.AUTH}login`, request: request }); } export function postLogout(request: FrontAction) { AxiosPost({ title: 'Logout', endpoint: `${config.url.AUTH}logout`, request: request }); } export function postSignup(request: IFrontRequest) { AxiosPost({ title: 'Register user', endpoint: `${config.url.AUTH}signup`, request: request }); } export function getProfile(request: FrontPull) { AxiosGet({ title: 'Current user profile', endpoint: `${config.url.AUTH}profile`, request: request }); } export function getActiveUsers(request: FrontPull) { AxiosGet({ title: 'Active users list', endpoint: `${config.url.AUTH}active-users`, request: request }); } export function getRSForms(filter: RSFormsFilter, request: FrontPull) { const endpoint = filter.type === FilterType.PERSONAL ? `${config.url.BASE}rsforms?owner=${filter.data as number}` : `${config.url.BASE}rsforms?is_common=true`; AxiosGet({ title: 'RSForms list', endpoint: endpoint, request: request }); } export function postNewRSForm(request: FrontExchange) { AxiosPost({ title: 'New RSForm', endpoint: `${config.url.BASE}rsforms/create-detailed/`, request: request, options: { headers: { 'Content-Type': 'multipart/form-data' } } }); } export function postCloneRSForm(schema: string, request: FrontExchange) { AxiosPost({ title: 'clone RSForm', endpoint: `${config.url.BASE}rsforms/${schema}/clone/`, request: request }); } export function getRSFormDetails(target: string, request: FrontPull) { AxiosGet({ title: `RSForm details for id=${target}`, endpoint: `${config.url.BASE}rsforms/${target}/details/`, request: request }); } export function patchRSForm(target: string, request: FrontExchange) { AxiosPatch({ title: `RSForm id=${target}`, endpoint: `${config.url.BASE}rsforms/${target}/`, request: request }); } export function deleteRSForm(target: string, request: FrontAction) { AxiosDelete({ title: `RSForm id=${target}`, endpoint: `${config.url.BASE}rsforms/${target}/`, request: request }); } export function postClaimRSForm(target: string, request: FrontPull) { AxiosPost({ title: `Claim on RSForm id=${target}`, endpoint: `${config.url.BASE}rsforms/${target}/claim/`, request: request }); } export function getTRSFile(target: string, request: FrontPull) { AxiosGet({ title: `RSForm TRS file for id=${target}`, endpoint: `${config.url.BASE}rsforms/${target}/export-trs/`, request: request, options: { responseType: 'blob' } }); } export function postNewConstituenta(schema: string, request: FrontExchange) { AxiosPost({ title: `New Constituenta for RSForm id=${schema}: ${request.data.alias}`, endpoint: `${config.url.BASE}rsforms/${schema}/cst-create/`, request: request }); } export function patchDeleteConstituenta(schema: string, request: FrontExchange) { AxiosPatch({ title: `Delete Constituents for RSForm id=${schema}: ${request.data.items.map(item => String(item.id)).join(' ')}`, endpoint: `${config.url.BASE}rsforms/${schema}/cst-multidelete/`, request: request }); } export function patchConstituenta(target: string, request: FrontExchange) { AxiosPatch({ title: `Constituenta id=${target}`, endpoint: `${config.url.BASE}constituents/${target}/`, request: request }); } export function patchMoveConstituenta(schema: string, request: FrontExchange) { AxiosPatch({ title: `Moving Constituents for RSForm id=${schema}: ${JSON.stringify(request.data.items)} to ${request.data.move_to}`, endpoint: `${config.url.BASE}rsforms/${schema}/cst-moveto/`, request: request }); } export function postCheckExpression(schema: string, request: FrontExchange) { AxiosPost({ title: `Check expression for RSForm id=${schema}: ${request.data.expression }`, endpoint: `${config.url.BASE}rsforms/${schema}/check/`, request: request }); } export function patchResetAliases(target: string, request: FrontPull) { AxiosPatch({ title: `Reset alias for RSForm id=${target}`, endpoint: `${config.url.BASE}rsforms/${target}/reset-aliases/`, request: request }); } export function patchUploadTRS(target: string, request: FrontExchange) { AxiosPatch({ title: `Replacing data with trs file for RSForm id=${target}`, endpoint: `${config.url.BASE}rsforms/${target}/load-trs/`, request: request, options: { headers: { 'Content-Type': 'multipart/form-data' } } }); } // ============ Helper functions ============= function AxiosGet({ endpoint, request, title, options }: IAxiosRequest) { console.log(`REQUEST: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.get(endpoint, options) .then((response) => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); }) .catch((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, options }: IAxiosRequest ) { console.log(`POST: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.post(endpoint, request.data, options) .then((response) => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); }) .catch((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, options }: IAxiosRequest ) { console.log(`DELETE: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.delete(endpoint, options) .then((response) => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); }) .catch((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, options }: IAxiosRequest ) { console.log(`PATCH: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.patch(endpoint, request.data, options) .then((response) => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); return response.data; }) .catch((error) => { if (request.setLoading) request.setLoading(false); if (request.showError) toast.error(error.message); if (request.onError) request.onError(error); }); }