2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
|
|
|
|
2023-12-05 01:22:44 +03:00
|
|
|
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2023-12-13 14:32:57 +03:00
|
|
|
import { type ErrorData } from '@/components/InfoError';
|
|
|
|
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
|
|
|
import { ILibraryItem } from '@/models/library';
|
|
|
|
import { ILibraryUpdateData } from '@/models/library';
|
2023-09-11 20:31:54 +03:00
|
|
|
import {
|
2023-12-28 14:04:44 +03:00
|
|
|
IConstituentaList,
|
|
|
|
IConstituentaMeta,
|
|
|
|
ICstCreateData,
|
|
|
|
ICstMovetoData,
|
|
|
|
ICstRenameData,
|
|
|
|
ICstUpdateData,
|
|
|
|
IRSForm,
|
|
|
|
IRSFormUploadData
|
2023-12-13 14:32:57 +03:00
|
|
|
} from '@/models/rsform';
|
2023-07-25 20:27:29 +03:00
|
|
|
import {
|
2023-12-28 14:04:44 +03:00
|
|
|
type DataCallback,
|
|
|
|
deleteUnsubscribe,
|
2023-12-13 14:32:57 +03:00
|
|
|
getTRSFile,
|
2023-12-28 14:04:44 +03:00
|
|
|
patchConstituenta,
|
|
|
|
patchDeleteConstituenta,
|
2023-12-13 14:32:57 +03:00
|
|
|
patchLibraryItem,
|
2023-12-28 14:04:44 +03:00
|
|
|
patchMoveConstituenta,
|
|
|
|
patchRenameConstituenta,
|
|
|
|
patchResetAliases,
|
|
|
|
patchUploadTRS,
|
|
|
|
postClaimLibraryItem,
|
|
|
|
postNewConstituenta,
|
|
|
|
postSubscribe
|
2023-12-13 14:32:57 +03:00
|
|
|
} from '@/utils/backendAPI';
|
|
|
|
|
2023-12-05 01:22:44 +03:00
|
|
|
import { useAuth } from './AuthContext';
|
|
|
|
import { useLibrary } from './LibraryContext';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
interface IRSFormContext {
|
2023-12-28 14:04:44 +03:00
|
|
|
schema?: IRSForm;
|
2023-07-24 22:34:03 +03:00
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
error: ErrorData;
|
|
|
|
loading: boolean;
|
|
|
|
processing: boolean;
|
2023-07-24 22:34:03 +03:00
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
isOwned: boolean;
|
|
|
|
isClaimable: boolean;
|
|
|
|
isSubscribed: boolean;
|
2023-08-11 19:28:12 +03:00
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
update: (data: ILibraryUpdateData, callback?: DataCallback<ILibraryItem>) => void;
|
|
|
|
claim: (callback?: DataCallback<ILibraryItem>) => void;
|
|
|
|
subscribe: (callback?: () => void) => void;
|
|
|
|
unsubscribe: (callback?: () => void) => void;
|
|
|
|
download: (callback: DataCallback<Blob>) => void;
|
|
|
|
upload: (data: IRSFormUploadData, callback: () => void) => void;
|
2023-07-23 21:38:04 +03:00
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
resetAliases: (callback: () => void) => void;
|
|
|
|
|
|
|
|
cstCreate: (data: ICstCreateData, callback?: DataCallback<IConstituentaMeta>) => void;
|
|
|
|
cstRename: (data: ICstRenameData, callback?: DataCallback<IConstituentaMeta>) => void;
|
|
|
|
cstUpdate: (data: ICstUpdateData, callback?: DataCallback<IConstituentaMeta>) => void;
|
|
|
|
cstDelete: (data: IConstituentaList, callback?: () => void) => void;
|
|
|
|
cstMoveTo: (data: ICstMovetoData, callback?: () => void) => void;
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
const RSFormContext = createContext<IRSFormContext | null>(null);
|
2023-07-24 22:34:03 +03:00
|
|
|
export const useRSForm = () => {
|
2023-12-28 14:04:44 +03:00
|
|
|
const context = useContext(RSFormContext);
|
2023-08-22 20:29:07 +03:00
|
|
|
if (context === null) {
|
2023-12-05 01:22:44 +03:00
|
|
|
throw new Error('useRSForm has to be used within <RSFormState.Provider>');
|
2023-07-24 22:34:03 +03:00
|
|
|
}
|
2023-12-05 01:22:44 +03:00
|
|
|
return context;
|
2023-12-28 14:04:44 +03:00
|
|
|
};
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
interface RSFormStateProps {
|
2023-12-28 14:04:44 +03:00
|
|
|
schemaID: string;
|
|
|
|
children: React.ReactNode;
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-07-23 15:23:01 +03:00
|
|
|
export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
|
2023-08-27 15:39:49 +03:00
|
|
|
const library = useLibrary();
|
2023-08-09 17:19:12 +03:00
|
|
|
const { user } = useAuth();
|
|
|
|
const { schema, reload, error, setError, setSchema, loading } = useRSFormDetails({ target: schemaID });
|
2023-12-05 01:22:44 +03:00
|
|
|
const [processing, setProcessing] = useState(false);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-12-05 01:22:44 +03:00
|
|
|
const [toggleTracking, setToggleTracking] = useState(false);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
const isOwned = useMemo(() => {
|
2023-08-25 22:51:20 +03:00
|
|
|
return user?.id === schema?.owner || false;
|
|
|
|
}, [user, schema?.owner]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
const isClaimable = useMemo(() => {
|
2023-08-25 22:51:20 +03:00
|
|
|
return (user?.id !== schema?.owner && schema?.is_common && !schema?.is_canonical) ?? false;
|
|
|
|
}, [user, schema?.owner, schema?.is_common, schema?.is_canonical]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
const isSubscribed = useMemo(() => {
|
2023-08-26 19:39:49 +03:00
|
|
|
if (!user || !schema || !user.id) {
|
2023-08-26 17:26:49 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return schema.subscribers.includes(user.id);
|
2023-12-28 14:04:44 +03:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2023-08-26 17:26:49 +03:00
|
|
|
}, [user, schema, toggleTracking]);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
2023-07-23 21:38:04 +03:00
|
|
|
const update = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: ILibraryUpdateData, callback?: DataCallback<ILibraryItem>) => {
|
|
|
|
if (!schema) {
|
|
|
|
return;
|
2023-07-26 23:11:00 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
setError(undefined);
|
|
|
|
patchLibraryItem(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(Object.assign(schema, newData));
|
|
|
|
library.localUpdateItem(newData);
|
|
|
|
if (callback) callback(newData);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, setSchema, schema, library]
|
|
|
|
);
|
|
|
|
|
2023-07-27 22:04:25 +03:00
|
|
|
const upload = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: IRSFormUploadData, callback?: () => void) => {
|
|
|
|
if (!schema) {
|
|
|
|
return;
|
2023-07-27 22:04:25 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
setError(undefined);
|
|
|
|
patchUploadTRS(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData);
|
|
|
|
library.localUpdateItem(newData);
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, setSchema, schema, library]
|
|
|
|
);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-07-23 21:38:04 +03:00
|
|
|
const claim = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(callback?: DataCallback<ILibraryItem>) => {
|
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
2023-07-24 22:34:03 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
setError(undefined);
|
|
|
|
postClaimLibraryItem(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(Object.assign(schema, newData));
|
|
|
|
library.localUpdateItem(newData);
|
|
|
|
if (!user.subscriptions.includes(newData.id)) {
|
|
|
|
user.subscriptions.push(newData.id);
|
|
|
|
}
|
|
|
|
if (callback) callback(newData);
|
2023-08-26 17:26:49 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, schema, user, setSchema, library]
|
|
|
|
);
|
|
|
|
|
|
|
|
const subscribe = useCallback(
|
|
|
|
(callback?: () => void) => {
|
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
2023-08-26 17:26:49 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
setError(undefined);
|
|
|
|
postSubscribe(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: () => {
|
|
|
|
if (user.id && !schema.subscribers.includes(user.id)) {
|
|
|
|
schema.subscribers.push(user.id);
|
|
|
|
}
|
|
|
|
if (!user.subscriptions.includes(schema.id)) {
|
|
|
|
user.subscriptions.push(schema.id);
|
|
|
|
}
|
|
|
|
setToggleTracking(prev => !prev);
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, schema, user]
|
|
|
|
);
|
2023-08-26 17:26:49 +03:00
|
|
|
|
|
|
|
const unsubscribe = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(callback?: () => void) => {
|
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
2023-08-26 17:26:49 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
setError(undefined);
|
|
|
|
deleteUnsubscribe(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: () => {
|
|
|
|
if (user.id && schema.subscribers.includes(user.id)) {
|
|
|
|
schema.subscribers.splice(schema.subscribers.indexOf(user.id), 1);
|
|
|
|
}
|
|
|
|
if (user.subscriptions.includes(schema.id)) {
|
|
|
|
user.subscriptions.splice(user.subscriptions.indexOf(schema.id), 1);
|
|
|
|
}
|
|
|
|
setToggleTracking(prev => !prev);
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, schema, user]
|
|
|
|
);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-07-27 22:04:25 +03:00
|
|
|
const resetAliases = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(callback?: () => void) => {
|
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
2023-07-27 22:04:25 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
setError(undefined);
|
|
|
|
patchResetAliases(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(Object.assign(schema, newData));
|
|
|
|
library.localUpdateTimestamp(newData.id);
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, schema, library, user, setSchema]
|
|
|
|
);
|
2023-07-27 22:04:25 +03:00
|
|
|
|
2023-07-23 21:38:04 +03:00
|
|
|
const download = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(callback: DataCallback<Blob>) => {
|
|
|
|
setError(undefined);
|
|
|
|
getTRSFile(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: callback
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError]
|
|
|
|
);
|
2023-07-16 22:25:23 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
const cstCreate = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: ICstCreateData, callback?: DataCallback<IConstituentaMeta>) => {
|
|
|
|
setError(undefined);
|
|
|
|
postNewConstituenta(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData.schema);
|
|
|
|
library.localUpdateTimestamp(newData.schema.id);
|
|
|
|
if (callback) callback(newData.new_cst);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, library, setSchema]
|
|
|
|
);
|
2023-07-18 14:55:40 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
const cstDelete = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: IConstituentaList, callback?: () => void) => {
|
|
|
|
setError(undefined);
|
|
|
|
patchDeleteConstituenta(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData);
|
|
|
|
library.localUpdateTimestamp(newData.id);
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, library, setSchema]
|
|
|
|
);
|
2023-07-23 21:38:04 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
const cstUpdate = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: ICstUpdateData, callback?: DataCallback<IConstituentaMeta>) => {
|
|
|
|
setError(undefined);
|
|
|
|
patchConstituenta(String(data.id), {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData =>
|
|
|
|
reload(setProcessing, () => {
|
|
|
|
library.localUpdateTimestamp(Number(schemaID));
|
|
|
|
if (callback) callback(newData);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[setError, schemaID, library, reload]
|
|
|
|
);
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2023-08-23 01:36:17 +03:00
|
|
|
const cstRename = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: ICstRenameData, callback?: DataCallback<IConstituentaMeta>) => {
|
|
|
|
setError(undefined);
|
|
|
|
patchRenameConstituenta(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData.schema);
|
|
|
|
library.localUpdateTimestamp(newData.schema.id);
|
|
|
|
if (callback) callback(newData.new_cst);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[setError, setSchema, library, schemaID]
|
|
|
|
);
|
2023-08-23 01:36:17 +03:00
|
|
|
|
2023-07-25 20:27:29 +03:00
|
|
|
const cstMoveTo = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: ICstMovetoData, callback?: () => void) => {
|
|
|
|
setError(undefined);
|
|
|
|
patchMoveConstituenta(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData);
|
|
|
|
library.localUpdateTimestamp(Number(schemaID));
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[schemaID, setError, library, setSchema]
|
|
|
|
);
|
2023-07-23 15:23:01 +03:00
|
|
|
|
2023-07-15 17:46:19 +03:00
|
|
|
return (
|
2023-12-28 14:04:44 +03:00
|
|
|
<RSFormContext.Provider
|
|
|
|
value={{
|
|
|
|
schema,
|
|
|
|
error,
|
|
|
|
loading,
|
|
|
|
processing,
|
|
|
|
isOwned,
|
|
|
|
isClaimable,
|
|
|
|
isSubscribed,
|
|
|
|
update,
|
|
|
|
download,
|
|
|
|
upload,
|
|
|
|
claim,
|
|
|
|
resetAliases,
|
|
|
|
subscribe,
|
|
|
|
unsubscribe,
|
|
|
|
cstUpdate,
|
|
|
|
cstCreate,
|
|
|
|
cstRename,
|
|
|
|
cstDelete,
|
|
|
|
cstMoveTo
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</RSFormContext.Provider>
|
|
|
|
);
|
|
|
|
};
|