diff --git a/apps/pyconkr-admin/src/components/elements/admin_signin_guard.tsx b/apps/pyconkr-admin/src/components/elements/admin_signin_guard.tsx
index 9bad3a7..52e73e8 100644
--- a/apps/pyconkr-admin/src/components/elements/admin_signin_guard.tsx
+++ b/apps/pyconkr-admin/src/components/elements/admin_signin_guard.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { useBackendAdminClient, useSignedInUserQuery } from "@frontend/common/src/hooks/useAdminAPI";
import { CircularProgress } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
@@ -9,8 +9,8 @@ import { addSnackbar } from "../../utils/snackbar";
export const BackendAdminSignInGuard: React.FC<{ children: React.ReactNode }> = ErrorBoundary.with(
{ fallback: <>로그인 정보를 불러오는 중 문제가 발생했습니다.> },
Suspense.with({ fallback: }, ({ children }) => {
- const backendAdminAPIClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const { data } = Common.Hooks.BackendAdminAPI.useSignedInUserQuery(backendAdminAPIClient);
+ const backendAdminAPIClient = useBackendAdminClient();
+ const { data } = useSignedInUserQuery(backendAdminAPIClient);
if (!data) {
addSnackbar("로그인 후 이용해주세요.", "error");
diff --git a/apps/pyconkr-admin/src/components/layouts/admin_editor.tsx b/apps/pyconkr-admin/src/components/layouts/admin_editor.tsx
index 9af4007..5c0cbc6 100644
--- a/apps/pyconkr-admin/src/components/layouts/admin_editor.tsx
+++ b/apps/pyconkr-admin/src/components/layouts/admin_editor.tsx
@@ -1,4 +1,18 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { retrieve } from "@frontend/common/src/apis/admin_api";
+import {
+ useBackendAdminClient,
+ useChoicesQuery,
+ useCreateMutation,
+ useRemoveMutation,
+ useSchemaQuery,
+ useUpdateMutation,
+} from "@frontend/common/src/hooks/useAdminAPI";
+import {
+ filterPropertiesByLanguageInJsonSchema,
+ filterReadOnlyPropertiesInJsonSchema,
+ filterWritablePropertiesInJsonSchema,
+} from "@frontend/common/src/utils";
import { Add, Close, Delete, Edit } from "@mui/icons-material";
import {
Box,
@@ -132,7 +146,7 @@ const fieldPropsToSelectedProps = (props: FieldProps): OutlinedSelectProps & { d
};
const M2MSelect: Field = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, (props) => {
const selectable = (props.schema.items as JSONSchema7).oneOf as DescriptedEnum[];
const selectableListObj: DescriptedEnumObject = selectable.reduce((a, i) => ({ ...a, [i.const]: i }), {} as DescriptedEnumObject);
@@ -167,29 +181,26 @@ const MDRendererContainer = styled(Box)(({ theme }) => ({
},
}));
-const MDEditorField: Field = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
- ({ disabled, formData, name, onChange: rawOnChange }) => {
- const [valueState, setValueState] = React.useState(formData?.toString() || "");
- const onChange = (value?: string) => {
- setValueState(value);
- rawOnChange(value, undefined, name);
- };
- return (
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-);
+const MDEditorField: Field = ErrorBoundary.with({ fallback: Components.ErrorFallback }, ({ disabled, formData, name, onChange: rawOnChange }) => {
+ const [valueState, setValueState] = React.useState(formData?.toString() || "");
+ const onChange = (value?: string) => {
+ setValueState(value);
+ rawOnChange(value, undefined, name);
+ };
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+});
type ReadOnlyValueFieldStateType = {
loading: boolean;
@@ -234,7 +245,7 @@ const ReadOnlyValueField: React.FC<{
)}
{fieldState.blob.type.startsWith("application/json") && fieldState.blobText && (
-
+
)}
링크
@@ -251,7 +262,7 @@ type InnerAdminEditorStateType = {
};
const InnerAdminEditor: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with(
{ fallback: },
({
@@ -275,9 +286,10 @@ const InnerAdminEditor: React.FC = Err
tab: 0,
formData: undefined,
});
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const { data: schemaInfo } = Common.Hooks.BackendAdminAPI.useSchemaQuery(backendAdminClient, app, resource);
- const { data: choicesData } = Common.Hooks.BackendAdminAPI.useChoicesQuery(backendAdminClient, app, resource);
+
+ const backendAdminClient = useBackendAdminClient();
+ const { data: schemaInfo } = useSchemaQuery(backendAdminClient, app, resource);
+ const { data: choicesData } = useChoicesQuery(backendAdminClient, app, resource);
// Merge choices into schema for FK/M2M fields
React.useMemo(() => {
@@ -299,9 +311,9 @@ const InnerAdminEditor: React.FC = Err
const selectedLanguage = editorState.tab === 0 ? "ko" : "en";
const notSelectedLanguage = editorState.tab === 0 ? "en" : "ko";
- const createMutation = Common.Hooks.BackendAdminAPI.useCreateMutation>(backendAdminClient, app, resource);
- const modifyMutation = Common.Hooks.BackendAdminAPI.useUpdateMutation>(backendAdminClient, app, resource, id || "");
- const deleteMutation = Common.Hooks.BackendAdminAPI.useRemoveMutation(backendAdminClient, app, resource, id || "undefined");
+ const createMutation = useCreateMutation>(backendAdminClient, app, resource);
+ const modifyMutation = useUpdateMutation>(backendAdminClient, app, resource, id || "");
+ const deleteMutation = useRemoveMutation(backendAdminClient, app, resource, id || "undefined");
const submitMutation = id ? modifyMutation : createMutation;
React.useEffect(() => {
@@ -311,7 +323,7 @@ const InnerAdminEditor: React.FC = Err
return;
}
- const initialData = await Common.BackendAdminAPIs.retrieve>(backendAdminClient, app, resource, id)();
+ const initialData = await retrieve>(backendAdminClient, app, resource, id)();
setFormData({ ...initialData, ...context });
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -359,13 +371,13 @@ const InnerAdminEditor: React.FC = Err
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {} as RJSFSchema);
}
- const writableSchema = Common.Utils.filterPropertiesByLanguageInJsonSchema(
- Common.Utils.filterWritablePropertiesInJsonSchema(schemaInfo.schema),
+ const writableSchema = filterPropertiesByLanguageInJsonSchema(
+ filterWritablePropertiesInJsonSchema(schemaInfo.schema),
schemaInfo.translation_fields,
selectedLanguage
);
- const readOnlySchema = Common.Utils.filterPropertiesByLanguageInJsonSchema(
- Common.Utils.filterReadOnlyPropertiesInJsonSchema(schemaInfo.schema),
+ const readOnlySchema = filterPropertiesByLanguageInJsonSchema(
+ filterReadOnlyPropertiesInJsonSchema(schemaInfo.schema),
schemaInfo.translation_fields,
selectedLanguage
);
diff --git a/apps/pyconkr-admin/src/components/layouts/admin_list.tsx b/apps/pyconkr-admin/src/components/layouts/admin_list.tsx
index edd9930..de63eba 100644
--- a/apps/pyconkr-admin/src/components/layouts/admin_list.tsx
+++ b/apps/pyconkr-admin/src/components/layouts/admin_list.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useChoicesQuery, useListQuery, useOpenApiSchemaQuery } from "@frontend/common/src/hooks/useAdminAPI";
+import { extractQueryParameters } from "@frontend/common/src/utils";
import { Add } from "@mui/icons-material";
import { Box, Button, CircularProgress, Stack, Table, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -24,22 +26,23 @@ type ListRowType = {
};
const InnerAdminList: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, ({ app, resource, hideCreatedAt, hideUpdatedAt, hideCreateNew }) => {
const navigate = useNavigate();
+
const [searchParams, setSearchParams] = useSearchParams();
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
+ const backendAdminClient = useBackendAdminClient();
const filterParams: Record = Object.fromEntries(searchParams.entries());
- const listQuery = Common.Hooks.BackendAdminAPI.useListQuery(backendAdminClient, app, resource, filterParams);
+ const listQuery = useListQuery(backendAdminClient, app, resource, filterParams);
- const openApiSchemaQuery = Common.Hooks.BackendAdminAPI.useOpenApiSchemaQuery(backendAdminClient);
+ const openApiSchemaQuery = useOpenApiSchemaQuery(backendAdminClient);
const queryParameters = React.useMemo(
- () => Common.Utils.extractQueryParameters(openApiSchemaQuery.data, app, resource),
+ () => extractQueryParameters(openApiSchemaQuery.data, app, resource),
[openApiSchemaQuery.data, app, resource]
);
- const choicesQuery = Common.Hooks.BackendAdminAPI.useChoicesQuery(backendAdminClient, app, resource);
+ const choicesQuery = useChoicesQuery(backendAdminClient, app, resource);
const handleFilterApply = (newParams: Record) => setSearchParams(newParams, { replace: true });
diff --git a/apps/pyconkr-admin/src/components/pages/account/account.tsx b/apps/pyconkr-admin/src/components/pages/account/account.tsx
index 8b48725..7249f46 100644
--- a/apps/pyconkr-admin/src/components/pages/account/account.tsx
+++ b/apps/pyconkr-admin/src/components/pages/account/account.tsx
@@ -1,14 +1,15 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useSignedInUserQuery } from "@frontend/common/src/hooks/useAdminAPI";
import { CircularProgress } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
import { Navigate } from "react-router-dom";
export const AccountRedirectPage: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
- const backendAdminAPIClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const { data } = Common.Hooks.BackendAdminAPI.useSignedInUserQuery(backendAdminAPIClient);
+ const backendAdminAPIClient = useBackendAdminClient();
+ const { data } = useSignedInUserQuery(backendAdminAPIClient);
return data ? : ;
})
diff --git a/apps/pyconkr-admin/src/components/pages/account/manage.tsx b/apps/pyconkr-admin/src/components/pages/account/manage.tsx
index 45c5b90..dbbdb03 100644
--- a/apps/pyconkr-admin/src/components/pages/account/manage.tsx
+++ b/apps/pyconkr-admin/src/components/pages/account/manage.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { me } from "@frontend/common/src/apis/admin_api";
+import { useBackendAdminClient, useChangePasswordMutation, useSignOutMutation } from "@frontend/common/src/hooks/useAdminAPI";
+import { getFormValue, isFormValid } from "@frontend/common/src/utils";
import { Logout } from "@mui/icons-material";
import { Button, Stack, Tab, Tabs, TextField, Typography } from "@mui/material";
import * as React from "react";
@@ -16,9 +18,9 @@ export const AccountManagementPage: React.FC = () => {
const changePasswordFormRef = React.useRef(null);
const [pageState, setPageState] = React.useState<{ tab: number }>({ tab: 0 });
const navigate = useNavigate();
- const backendAdminAPIClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const signOutMutation = Common.Hooks.BackendAdminAPI.useSignOutMutation(backendAdminAPIClient);
- const changePasswordMutation = Common.Hooks.BackendAdminAPI.useChangePasswordMutation(backendAdminAPIClient);
+ const backendAdminAPIClient = useBackendAdminClient();
+ const signOutMutation = useSignOutMutation(backendAdminAPIClient);
+ const changePasswordMutation = useChangePasswordMutation(backendAdminAPIClient);
const setTab = (_: React.SyntheticEvent, tab: number) => setPageState((ps) => ({ ...ps, tab }));
@@ -37,12 +39,12 @@ export const AccountManagementPage: React.FC = () => {
event.stopPropagation();
const form = changePasswordFormRef.current;
- if (!Common.Utils.isFormValid(form)) {
+ if (!isFormValid(form)) {
addSnackbar("폼에 오류가 있습니다. 다시 확인해주세요.", "error");
return;
}
- const formData = Common.Utils.getFormValue({ form });
+ const formData = getFormValue({ form });
if (formData.new_password !== formData.new_password_confirm) {
addSnackbar("새 비밀번호와 확인 비밀번호가 일치하지 않습니다.", "error");
return;
@@ -59,7 +61,7 @@ export const AccountManagementPage: React.FC = () => {
React.useEffect(() => {
(async () => {
- const userInfo = await Common.BackendAdminAPIs.me(backendAdminAPIClient)();
+ const userInfo = await me(backendAdminAPIClient)();
if (!userInfo) {
addSnackbar("로그아웃 상태입니다!", "error");
navigate("/");
diff --git a/apps/pyconkr-admin/src/components/pages/account/sign_in.tsx b/apps/pyconkr-admin/src/components/pages/account/sign_in.tsx
index 8cd3424..82e4d1c 100644
--- a/apps/pyconkr-admin/src/components/pages/account/sign_in.tsx
+++ b/apps/pyconkr-admin/src/components/pages/account/sign_in.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { useBackendAdminClient, useSignInMutation } from "@frontend/common/src/hooks/useAdminAPI";
+import { getFormValue } from "@frontend/common/src/utils";
+import { me } from "@frontend/common/src/apis/admin_api";
import { Login } from "@mui/icons-material";
import { Button, Stack, TextField, Typography } from "@mui/material";
import * as React from "react";
@@ -16,14 +18,14 @@ export const SignInPage: React.FC = () => {
const [pageState, setPageState] = React.useState({ userJustSignedIn: false });
const setUserJustSignedIn = () => setPageState((ps) => ({ ...ps, userJustSignedIn: true }));
- const backendAdminAPIClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const signInMutation = Common.Hooks.BackendAdminAPI.useSignInMutation(backendAdminAPIClient);
+ const backendAdminAPIClient = useBackendAdminClient();
+ const signInMutation = useSignInMutation(backendAdminAPIClient);
const handleSignIn = (event: React.FormEvent) => {
event.preventDefault();
if (!formRef.current) return;
- const formData = Common.Utils.getFormValue<{
+ const formData = getFormValue<{
identity: string;
password: string;
}>({ form: formRef.current });
@@ -41,7 +43,7 @@ export const SignInPage: React.FC = () => {
(async () => {
if (pageState.userJustSignedIn) return;
- const userInfo = await Common.BackendAdminAPIs.me(backendAdminAPIClient)();
+ const userInfo = await me(backendAdminAPIClient)();
if (userInfo) {
addSnackbar(`이미 ${userInfo.username}님으로 로그인되어 있습니다!`, "success");
navigate("/");
diff --git a/apps/pyconkr-admin/src/components/pages/file/upload.tsx b/apps/pyconkr-admin/src/components/pages/file/upload.tsx
index 7fdd5ed..251a60d 100644
--- a/apps/pyconkr-admin/src/components/pages/file/upload.tsx
+++ b/apps/pyconkr-admin/src/components/pages/file/upload.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { useBackendAdminClient, useUploadPublicFileMutation } from "@frontend/common/src/hooks/useAdminAPI";
import { CloudUpload, PermMedia } from "@mui/icons-material";
import { Box, Button, Input, Stack, Typography } from "@mui/material";
import * as React from "react";
@@ -25,8 +25,8 @@ const InnerPublicFileUploadPage: React.FC = () => {
});
const fileInputRef = React.useRef(null);
const fileDragBoxRef = React.useRef(null);
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const uploadPublicFileMutation = Common.Hooks.BackendAdminAPI.useUploadPublicFileMutation(backendAdminClient);
+ const backendAdminClient = useBackendAdminClient();
+ const uploadPublicFileMutation = useUploadPublicFileMutation(backendAdminClient);
const forceRerender = React.useCallback(
() =>
diff --git a/apps/pyconkr-admin/src/components/pages/modification_audit/components.tsx b/apps/pyconkr-admin/src/components/pages/modification_audit/components.tsx
index 816bb7b..5d69658 100644
--- a/apps/pyconkr-admin/src/components/pages/modification_audit/components.tsx
+++ b/apps/pyconkr-admin/src/components/pages/modification_audit/components.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, usePublicFileQuery } from "@frontend/common/src/hooks/useAdminAPI";
import {
Accordion,
AccordionDetails,
@@ -78,30 +79,30 @@ export const PreviewTextField: React.FC = ({ originalDataset,
export const PreviewMarkdownField: React.FC = ({ originalDataset, previewDataset, name, label }) => {
return originalDataset[name] === previewDataset[name] ? (
-
+
-
+
-
+
) : (
-
+
-
+
-
+
기존 값을 보려면 여기를 클릭해주세요.
-
+
-
+
-
+
@@ -114,21 +115,21 @@ const ImageFallback: React.FC = () => (
);
-const WidthSpecifiedFallbackImage = styled(Common.Components.FallbackImage)({
+const WidthSpecifiedFallbackImage = styled(Components.FallbackImage)({
maxWidth: "20rem",
objectFit: "cover",
});
export const PreviewImageField: React.FC = ({ originalDataset, previewDataset, name, label }) => {
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
+ const backendAdminClient = useBackendAdminClient();
const oldImgId = (originalDataset[name] as string) || "";
const newImgId = (previewDataset[name] as string) || "";
- const { data: originalImage } = Common.Hooks.BackendAdminAPI.usePublicFileQuery(backendAdminClient, oldImgId);
- const { data: previewImage } = Common.Hooks.BackendAdminAPI.usePublicFileQuery(backendAdminClient, newImgId);
+ const { data: originalImage } = usePublicFileQuery(backendAdminClient, oldImgId);
+ const { data: previewImage } = usePublicFileQuery(backendAdminClient, newImgId);
return originalImage?.id === previewImage?.id ? (
-
+
{previewImage?.file ? (
} />
@@ -136,13 +137,13 @@ export const PreviewImageField: React.FC = ({ originalD
)}
-
+
) : (
-
+
{previewImage?.file ? (
} />
@@ -150,12 +151,12 @@ export const PreviewImageField: React.FC = ({ originalD
)}
-
+
기존 이미지를 보려면 여기를 클릭해주세요.
-
+
{originalImage?.file ? (
} />
@@ -163,7 +164,7 @@ export const PreviewImageField: React.FC = ({ originalD
)}
-
+
diff --git a/apps/pyconkr-admin/src/components/pages/modification_audit/dialogs.tsx b/apps/pyconkr-admin/src/components/pages/modification_audit/dialogs.tsx
index 8251452..10da0cc 100644
--- a/apps/pyconkr-admin/src/components/pages/modification_audit/dialogs.tsx
+++ b/apps/pyconkr-admin/src/components/pages/modification_audit/dialogs.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useApproveModificationAuditMutation, useBackendAdminClient, useRejectModificationAuditMutation } from "@frontend/common/src/hooks/useAdminAPI";
+import { BackendAPIClientError } from "@frontend/common/src/apis";
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField, Typography } from "@mui/material";
import { enqueueSnackbar, OptionsObject } from "notistack";
import * as React from "react";
@@ -10,8 +12,8 @@ type SubmitConfirmDialogProps = {
};
export const ApproveSubmitConfirmDialog: React.FC = ({ open, onClose, modificationAuditId }) => {
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const approveModificationAuditMutation = Common.Hooks.BackendAdminAPI.useApproveModificationAuditMutation(backendAdminClient, modificationAuditId);
+ const backendAdminClient = useBackendAdminClient();
+ const approveModificationAuditMutation = useApproveModificationAuditMutation(backendAdminClient, modificationAuditId);
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
enqueueSnackbar(c, { variant, anchorOrigin: { vertical: "bottom", horizontal: "center" } });
@@ -25,7 +27,7 @@ export const ApproveSubmitConfirmDialog: React.FC = ({
onError: (error) => {
console.error("Approve modification audit failed:", error);
let errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) errorMessage = error.message;
+ if (error instanceof BackendAPIClientError) errorMessage = error.message;
addSnackbar(errorMessage, "error");
},
});
@@ -51,8 +53,8 @@ export const ApproveSubmitConfirmDialog: React.FC = ({
export const RejectSubmitConfirmDialog: React.FC = ({ open, onClose, modificationAuditId }) => {
const inputRef = React.useRef(null);
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const rejectModificationAuditMutation = Common.Hooks.BackendAdminAPI.useRejectModificationAuditMutation(backendAdminClient, modificationAuditId);
+ const backendAdminClient = useBackendAdminClient();
+ const rejectModificationAuditMutation = useRejectModificationAuditMutation(backendAdminClient, modificationAuditId);
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
enqueueSnackbar(c, { variant, anchorOrigin: { vertical: "bottom", horizontal: "center" } });
@@ -68,7 +70,7 @@ export const RejectSubmitConfirmDialog: React.FC = ({
onError: (error) => {
console.error("Reject modification audit failed:", error);
let errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) errorMessage = error.message;
+ if (error instanceof BackendAPIClientError) errorMessage = error.message;
addSnackbar(errorMessage, "error");
},
});
@@ -83,9 +85,9 @@ export const RejectSubmitConfirmDialog: React.FC = ({
반려 후에는 다시 승인할 수 없습니다!
-
+
-
+
diff --git a/apps/pyconkr-admin/src/components/pages/modification_audit/list.tsx b/apps/pyconkr-admin/src/components/pages/modification_audit/list.tsx
index bf146ae..a9bfd47 100644
--- a/apps/pyconkr-admin/src/components/pages/modification_audit/list.tsx
+++ b/apps/pyconkr-admin/src/components/pages/modification_audit/list.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useListQuery } from "@frontend/common/src/hooks/useAdminAPI";
import { CircularProgress, Stack, Table, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
@@ -15,10 +16,10 @@ type ListRowType = {
};
const InnerAdminModificationAuditList: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const listQuery = Common.Hooks.BackendAdminAPI.useListQuery(backendAdminClient, "modification-audit", "modification-audit");
+ const backendAdminClient = useBackendAdminClient();
+ const listQuery = useListQuery(backendAdminClient, "modification-audit", "modification-audit");
return (
diff --git a/apps/pyconkr-admin/src/components/pages/modification_audit/pages.tsx b/apps/pyconkr-admin/src/components/pages/modification_audit/pages.tsx
index 50a3f36..732f793 100644
--- a/apps/pyconkr-admin/src/components/pages/modification_audit/pages.tsx
+++ b/apps/pyconkr-admin/src/components/pages/modification_audit/pages.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useModificationAuditPreviewQuery } from "@frontend/common/src/hooks/useAdminAPI";
import { Box, Button, CircularProgress, Divider, Stack, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
@@ -15,8 +16,8 @@ const InnerAdminModificationAuditEditor: React.FC = () => {
const [editorState, setEditorState] = React.useState({});
const { id } = useParams<{ id?: string }>();
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const { data } = Common.Hooks.BackendAdminAPI.useModificationAuditPreviewQuery>(backendAdminClient, id || "");
+ const backendAdminClient = useBackendAdminClient();
+ const { data } = useModificationAuditPreviewQuery>(backendAdminClient, id || "");
if (!data) return ;
@@ -66,7 +67,7 @@ const InnerAdminModificationAuditEditor: React.FC = () => {
export const AdminModificationAuditEditor: React.FC = () => {
return (
-
+
}>
diff --git a/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/presentation_preview.tsx b/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/presentation_preview.tsx
index d222849..5cdc474 100644
--- a/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/presentation_preview.tsx
+++ b/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/presentation_preview.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import { Card, Divider, TextField, Typography } from "@mui/material";
import { PreviewImageField, PreviewMarkdownField, PreviewTextField } from "../components";
@@ -21,17 +21,17 @@ const isSpeakerModified = (original: PresentationPreviewSchema["speakers"][numbe
const PresentationSpeakerPreviewItem: React.FC = ({ originalSpeaker, modifiedSpeaker }) => {
const innerSpeakerPreviewItem = (
-
-
+
+
-
+
-
+
-
-
+
+
);
return isSpeakerModified(originalSpeaker, modifiedSpeaker) ? (
@@ -45,21 +45,21 @@ export const PresentationPreviewSubPage: SubModificationAuditPageType
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
diff --git a/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/userext_preview.tsx b/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/userext_preview.tsx
index 83bcf5e..ef15c67 100644
--- a/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/userext_preview.tsx
+++ b/apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/userext_preview.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import { Typography } from "@mui/material";
import { PreviewImageField, PreviewTextField } from "../components";
@@ -8,16 +8,16 @@ export const UserExtPreviewSubPage: SubModificationAuditPageType
-
+
-
+
-
+
-
+
>
);
};
diff --git a/apps/pyconkr-admin/src/components/pages/page/editor.tsx b/apps/pyconkr-admin/src/components/pages/page/editor.tsx
index 8258651..e445b1d 100644
--- a/apps/pyconkr-admin/src/components/pages/page/editor.tsx
+++ b/apps/pyconkr-admin/src/components/pages/page/editor.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useBulkUpdatePageSectionsMutation, useListPageSectionsQuery } from "@frontend/common/src/hooks/useAdminAPI";
+import { useCommonContext } from "@frontend/common/src/hooks/useCommonContext";
import { Add, Delete, OpenInNew } from "@mui/icons-material";
import { Box, Button, ButtonProps, CircularProgress, Divider, Stack, Tab, Tabs, ThemeProvider } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -45,14 +47,14 @@ const SectionTextEditor: React.FC = ({ disabled, defa
return (
-
+
}>
여기에 섹션 추가
-
+
@@ -81,17 +83,17 @@ type AdminCMSPageEditorStateType = {
};
export const AdminCMSPageEditor: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
const { id } = useParams<{ id?: string }>();
- const { frontendDomain } = Common.Hooks.Common.useCommonContext();
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const { data: initialSections } = Common.Hooks.BackendAdminAPI.useListPageSectionsQuery(backendAdminClient, id || "");
+ const { frontendDomain } = useCommonContext();
+ const backendAdminClient = useBackendAdminClient();
+ const { data: initialSections } = useListPageSectionsQuery(backendAdminClient, id || "");
const [editorState, setEditorState] = React.useState({
sections: initialSections,
tab: 0,
});
- const bulkUpdateSectionsMutation = Common.Hooks.BackendAdminAPI.useBulkUpdatePageSectionsMutation(backendAdminClient, id || "");
+ const bulkUpdateSectionsMutation = useBulkUpdatePageSectionsMutation(backendAdminClient, id || "");
const setTab = (_: React.SyntheticEvent, selectedTab: number) => setEditorState((ps) => ({ ...ps, tab: selectedTab }));
diff --git a/apps/pyconkr-admin/src/components/pages/presentation/editor.tsx b/apps/pyconkr-admin/src/components/pages/presentation/editor.tsx
index 8af3f85..16daa62 100644
--- a/apps/pyconkr-admin/src/components/pages/presentation/editor.tsx
+++ b/apps/pyconkr-admin/src/components/pages/presentation/editor.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useCreateMutation, useListQuery, useRemovePreparedMutation, useSchemaQuery, useUpdatePreparedMutation } from "@frontend/common/src/hooks/useAdminAPI";
import { Autocomplete, Box, Button, Card, CardContent, CircularProgress, Stack, styled, Tab, Tabs, TextField, Typography } from "@mui/material";
import { DateTimePicker, LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterLuxon } from "@mui/x-date-pickers/AdapterLuxon";
@@ -143,10 +144,10 @@ const PresentationSpeakerForm: React.FC = ({ di
-
+
-
+
@@ -263,29 +264,29 @@ type PresentationEditorStateType = {
};
export const AdminPresentationEditor: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
const { id } = useParams<{ id?: string }>();
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
enqueueSnackbar(c, { variant, anchorOrigin: { vertical: "bottom", horizontal: "center" } });
- const backendAdminAPIClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
+ const backendAdminAPIClient = useBackendAdminClient();
const speakerQueryParams = [backendAdminAPIClient, "event", "presentationspeaker"] as const;
const presentation = id || DUMMY_UUID;
- const speakerCreateMutation = Common.Hooks.BackendAdminAPI.useCreateMutation(...speakerQueryParams);
- const speakerUpdateMutation = Common.Hooks.BackendAdminAPI.useUpdatePreparedMutation(...speakerQueryParams);
- const speakerDeleteMutation = Common.Hooks.BackendAdminAPI.useRemovePreparedMutation(...speakerQueryParams);
- const { data: speakerJsonSchema } = Common.Hooks.BackendAdminAPI.useSchemaQuery(...speakerQueryParams);
- const { data: speakerInitialData } = Common.Hooks.BackendAdminAPI.useListQuery(...speakerQueryParams, { presentation });
+ const speakerCreateMutation = useCreateMutation(...speakerQueryParams);
+ const speakerUpdateMutation = useUpdatePreparedMutation(...speakerQueryParams);
+ const speakerDeleteMutation = useRemovePreparedMutation(...speakerQueryParams);
+ const { data: speakerJsonSchema } = useSchemaQuery(...speakerQueryParams);
+ const { data: speakerInitialData } = useListQuery(...speakerQueryParams, { presentation });
const speakers = speakerInitialData.map((s) => ({ ...s, trackId: s.id || Math.random().toString(36).substring(2, 15) }));
const scheduleQueryParams = [backendAdminAPIClient, "event", "roomschedule"] as const;
- const scheduleCreateMutation = Common.Hooks.BackendAdminAPI.useCreateMutation(...scheduleQueryParams);
- const scheduleUpdateMutation = Common.Hooks.BackendAdminAPI.useUpdatePreparedMutation(...scheduleQueryParams);
- const scheduleDeleteMutation = Common.Hooks.BackendAdminAPI.useRemovePreparedMutation(...scheduleQueryParams);
- const { data: scheduleJsonSchema } = Common.Hooks.BackendAdminAPI.useSchemaQuery(...scheduleQueryParams);
- const { data: scheduleInitialData } = Common.Hooks.BackendAdminAPI.useListQuery(...scheduleQueryParams, { presentation });
+ const scheduleCreateMutation = useCreateMutation(...scheduleQueryParams);
+ const scheduleUpdateMutation = useUpdatePreparedMutation(...scheduleQueryParams);
+ const scheduleDeleteMutation = useRemovePreparedMutation(...scheduleQueryParams);
+ const { data: scheduleJsonSchema } = useSchemaQuery(...scheduleQueryParams);
+ const { data: scheduleInitialData } = useListQuery(...scheduleQueryParams, { presentation });
const schedules = scheduleInitialData.map((s) => ({ ...s, trackId: s.id || Math.random().toString(36).substring(2, 15) }));
const createEmptySpeaker = (): OnMemoeryPresentationSpeaker => ({
@@ -359,7 +360,7 @@ export const AdminPresentationEditor: React.FC = ErrorBoundary.with(
{id ? (
-
+
스케줄 정보
{editorState.schedules.map((s) => (
@@ -373,8 +374,8 @@ export const AdminPresentationEditor: React.FC = ErrorBoundary.with(
))}
-
-
+
+
발표자 정보
{editorState.speakers.map((s) => (
@@ -388,7 +389,7 @@ export const AdminPresentationEditor: React.FC = ErrorBoundary.with(
))}
-
+
) : (
diff --git a/apps/pyconkr-admin/src/components/pages/sitemap/list.tsx b/apps/pyconkr-admin/src/components/pages/sitemap/list.tsx
index 2431cbe..a6cc6f5 100644
--- a/apps/pyconkr-admin/src/components/pages/sitemap/list.tsx
+++ b/apps/pyconkr-admin/src/components/pages/sitemap/list.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useListQuery, useRemovePreparedMutation, useUpdatePreparedMutation } from "@frontend/common/src/hooks/useAdminAPI";
+import { buildFlatSiteMap, buildNestedSiteMap } from "@frontend/common/src/utils";
import { Add, Delete, Edit, Save } from "@mui/icons-material";
import {
Box,
@@ -93,20 +95,20 @@ type InnerSiteMapStateType = {
const ModifyDetectionFields: (keyof FlatSiteMap)[] = ["order", "parent_sitemap"];
const InnerSiteMapList: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
- const backendAdminAPIClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const { data } = Common.Hooks.BackendAdminAPI.useListQuery(backendAdminAPIClient, "cms", "sitemap");
+ const backendAdminAPIClient = useBackendAdminClient();
+ const { data } = useListQuery(backendAdminAPIClient, "cms", "sitemap");
const originalFlatSiteMapObj = Object.values(data).reduce((acc, item) => ({ ...acc, [item.id]: item }), {} as FlatSiteMapObj);
- const deleteMutation = Common.Hooks.BackendAdminAPI.useRemovePreparedMutation(backendAdminAPIClient, "cms", "sitemap");
- const { mutateAsync: updateMutationAsync } = Common.Hooks.BackendAdminAPI.useUpdatePreparedMutation(backendAdminAPIClient, "cms", "sitemap");
+ const deleteMutation = useRemovePreparedMutation(backendAdminAPIClient, "cms", "sitemap");
+ const { mutateAsync: updateMutationAsync } = useUpdatePreparedMutation(backendAdminAPIClient, "cms", "sitemap");
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
enqueueSnackbar(c, { variant, anchorOrigin: { vertical: "bottom", horizontal: "center" } });
const [state, setState] = React.useState({ flatSiteMap: data });
- const nestedSiteMap = Common.Utils.buildNestedSiteMap(state.flatSiteMap)[""];
- const childrenFlatSiteMap = Common.Utils.buildFlatSiteMap(nestedSiteMap);
+ const nestedSiteMap = buildNestedSiteMap(state.flatSiteMap)[""];
+ const childrenFlatSiteMap = buildFlatSiteMap(nestedSiteMap);
const childrenFlatSiteMapObj = Object.values(childrenFlatSiteMap).reduce((acc, item) => ({ ...acc, [item.id]: item }), {} as FlatNestedSiteMap);
React.useEffect(() => setState((ps) => ({ ...ps, flatSiteMap: data })), [data]);
diff --git a/apps/pyconkr-admin/src/components/pages/user/editor.tsx b/apps/pyconkr-admin/src/components/pages/user/editor.tsx
index 7a3c752..7bc16c9 100644
--- a/apps/pyconkr-admin/src/components/pages/user/editor.tsx
+++ b/apps/pyconkr-admin/src/components/pages/user/editor.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendAdminClient, useResetUserPasswordMutation } from "@frontend/common/src/hooks/useAdminAPI";
import { KeyOff } from "@mui/icons-material";
import { Button, ButtonProps, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -17,7 +18,7 @@ type PageStateType = {
};
export const AdminUserExtEditor: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
const { id } = useParams<{ id?: string }>();
const navigate = useNavigate();
@@ -35,8 +36,8 @@ export const AdminUserExtEditor: React.FC = ErrorBoundary.with(
if (userId) navigate(`/user/userext/${userId}`);
};
- const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
- const useResetPasswordMutation = Common.Hooks.BackendAdminAPI.useResetUserPasswordMutation(backendAdminClient, id || "");
+ const backendAdminClient = useBackendAdminClient();
+ const useResetPasswordMutation = useResetUserPasswordMutation(backendAdminClient, id || "");
const resetUserPassword = () => {
closeConfirmDialog();
diff --git a/apps/pyconkr-admin/src/consts/mdx_components.ts b/apps/pyconkr-admin/src/consts/mdx_components.ts
index ef65626..8b2b767 100644
--- a/apps/pyconkr-admin/src/consts/mdx_components.ts
+++ b/apps/pyconkr-admin/src/consts/mdx_components.ts
@@ -1,5 +1,5 @@
// 후대의 개발자님께 : 컴포넌트 맨 첫글자가 대문자로 시작하지 않으면 JSX 컴포넌트가 아니라 일반 HTML 태그로 인식합니다. 제발 대문자로 시작해주세요.
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import * as Shop from "@frontend/shop";
import * as mui from "@mui/material";
import type { MDXComponents } from "mdx/types.js";
@@ -131,16 +131,16 @@ const MUIMDXComponents: MDXComponents = {
};
const PyConKRCommonMDXComponents: MDXComponents = {
- Common__Components__Lottie: Common.Components.LottiePlayer,
- Common__Components__NetworkLottie: Common.Components.NetworkLottiePlayer,
- Common__Components__MDX__Confetti: Common.Components.MDX.Confetti,
- Common__Components__MDX__PrimaryStyledDetails: Common.Components.MDX.PrimaryStyledDetails,
- Common__Components__MDX__SecondaryStyledDetails: Common.Components.MDX.SecondaryStyledDetails,
- Common__Components__MDX__Map: Common.Components.MDX.Map,
- Common__Components__MDX__FAQAccordion: Common.Components.MDX.FAQAccordion,
- Common__Components__MDX__FullWidthStyledButton: Common.Components.MDX.StyledFullWidthButton,
- Common__Components__Session__List: Common.Components.MDX.SessionList,
- Common__Components__Session__TimeTable: Common.Components.MDX.SessionTimeTable,
+ Common__Components__Lottie: Components.LottiePlayer,
+ Common__Components__NetworkLottie: Components.NetworkLottiePlayer,
+ Common__Components__MDX__Confetti: Components.MDX.Confetti,
+ Common__Components__MDX__PrimaryStyledDetails: Components.MDX.PrimaryStyledDetails,
+ Common__Components__MDX__SecondaryStyledDetails: Components.MDX.SecondaryStyledDetails,
+ Common__Components__MDX__Map: Components.MDX.Map,
+ Common__Components__MDX__FAQAccordion: Components.MDX.FAQAccordion,
+ Common__Components__MDX__FullWidthStyledButton: Components.MDX.StyledFullWidthButton,
+ Common__Components__Session__List: Components.MDX.SessionList,
+ Common__Components__Session__TimeTable: Components.MDX.SessionTimeTable,
};
const PythonKRShopMDXComponents: MDXComponents = {
diff --git a/apps/pyconkr-admin/src/main.tsx b/apps/pyconkr-admin/src/main.tsx
index 2eb62da..740ea9c 100644
--- a/apps/pyconkr-admin/src/main.tsx
+++ b/apps/pyconkr-admin/src/main.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import type { ContextOptions } from "@frontend/common/src/contexts";
import * as Shop from "@frontend/shop";
import { CircularProgress } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -30,7 +31,7 @@ const queryClient = new QueryClient({
}),
});
-const CommonOptions: Common.Contexts.ContextOptions = {
+const CommonOptions: ContextOptions = {
debug: true,
language: "ko",
baseUrl: ".",
@@ -51,17 +52,17 @@ const ShopOptions: Shop.Contexts.ContextOptions = {
ReactDom.createRoot(document.getElementById("root")!).render(
- 문제가 발생했습니다, 새로고침을 해주세요.}>
+ 문제가 발생했습니다, 새로고침을 해주세요.}>
+
-
+
}
>
-
+
@@ -77,7 +78,7 @@ ReactDom.createRoot(document.getElementById("root")!).render(
-
+
diff --git a/apps/pyconkr-admin/vite.config.ts b/apps/pyconkr-admin/vite.config.ts
index 1226307..e532c74 100644
--- a/apps/pyconkr-admin/vite.config.ts
+++ b/apps/pyconkr-admin/vite.config.ts
@@ -13,6 +13,7 @@ export default defineConfig({
plugins: [react(), mdx(), mkcert({ hosts: ["local.dev.pycon.kr"] }), svgr()],
resolve: {
alias: {
+ "@frontend/common/src": path.resolve(__dirname, "../../packages/common/src"),
"@frontend/common": path.resolve(__dirname, "../../packages/common/src/index.ts"),
"@frontend/shop": path.resolve(__dirname, "../../packages/shop/src/index.ts"),
"@apps/pyconkr-admin": path.resolve(__dirname, "./src"),
diff --git a/apps/pyconkr-participant-portal/src/components/dialogs/change_password.tsx b/apps/pyconkr-participant-portal/src/components/dialogs/change_password.tsx
index e74597a..52444ca 100644
--- a/apps/pyconkr-participant-portal/src/components/dialogs/change_password.tsx
+++ b/apps/pyconkr-participant-portal/src/components/dialogs/change_password.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { useChangePasswordMutation, useParticipantPortalClient } from "@frontend/common/src/hooks/useParticipantPortalAPI";
+import { getFormValue, isFormValid } from "@frontend/common/src/utils";
+import { BackendAPIClientError } from "@frontend/common/src/apis";
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Stack, TextField } from "@mui/material";
import { enqueueSnackbar, OptionsObject } from "notistack";
import * as React from "react";
@@ -19,8 +21,8 @@ type PasswordFormDataType = {
export const ChangePasswordDialog: React.FC = ({ open, onClose }) => {
const formRef = React.useRef(null);
const { language } = useAppContext();
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const changePasswordMutation = Common.Hooks.BackendParticipantPortalAPI.useChangePasswordMutation(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const changePasswordMutation = useChangePasswordMutation(participantPortalClient);
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
enqueueSnackbar(c, { variant, anchorOrigin: { vertical: "bottom", horizontal: "center" } });
@@ -34,9 +36,9 @@ export const ChangePasswordDialog: React.FC = ({ open
const passwordChangedStr = language === "ko" ? "비밀번호가 성공적으로 변경되었습니다." : "Password changed successfully.";
const handleSubmit = () => {
- if (!Common.Utils.isFormValid(formRef.current)) return;
+ if (!isFormValid(formRef.current)) return;
- const formData = Common.Utils.getFormValue({ form: formRef.current });
+ const formData = getFormValue({ form: formRef.current });
changePasswordMutation.mutate(formData, {
onSuccess: () => {
addSnackbar(passwordChangedStr, "success");
@@ -46,7 +48,7 @@ export const ChangePasswordDialog: React.FC = ({ open
console.error("Change password failed:", error);
let errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) errorMessage = error.message;
+ if (error instanceof BackendAPIClientError) errorMessage = error.message;
addSnackbar(errorMessage, "error");
},
diff --git a/apps/pyconkr-participant-portal/src/components/dialogs/modification_audit_cancel_confirm.tsx b/apps/pyconkr-participant-portal/src/components/dialogs/modification_audit_cancel_confirm.tsx
index 629dff2..2e8ae85 100644
--- a/apps/pyconkr-participant-portal/src/components/dialogs/modification_audit_cancel_confirm.tsx
+++ b/apps/pyconkr-participant-portal/src/components/dialogs/modification_audit_cancel_confirm.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { useCancelModificationAuditMutation, useParticipantPortalClient } from "@frontend/common/src/hooks/useParticipantPortalAPI";
+import { BackendAPIClientError } from "@frontend/common/src/apis";
import { Button, Chip, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@mui/material";
import { enqueueSnackbar, OptionsObject } from "notistack";
import * as React from "react";
@@ -14,8 +15,8 @@ type ModificationAuditCancelConfirmDialogProps = {
export const ModificationAuditCancelConfirmDialog: React.FC = ({ open, onClose, modificationAuditId }) => {
const reasonInputRef = React.useRef(null);
const { language } = useAppContext();
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const cancelModificationAuditMutation = Common.Hooks.BackendParticipantPortalAPI.useCancelModificationAuditMutation(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const cancelModificationAuditMutation = useCancelModificationAuditMutation(participantPortalClient);
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
enqueueSnackbar(c, { variant, anchorOrigin: { vertical: "bottom", horizontal: "center" } });
@@ -62,7 +63,7 @@ export const ModificationAuditCancelConfirmDialog: React.FC = ({ open, onClose, setFileIdAsValue }) => {
const { language } = useAppContext();
const [dialogState, setDialogState] = React.useState({ selectedFile: null, uploadedFileId: null });
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const uploadPublicFileMutation = Common.Hooks.BackendParticipantPortalAPI.useUploadPublicFileMutation(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const uploadPublicFileMutation = useUploadPublicFileMutation(participantPortalClient);
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
enqueueSnackbar(c, { variant, anchorOrigin: { vertical: "bottom", horizontal: "center" } });
@@ -80,7 +82,7 @@ export const PublicFileUploadDialog: React.FC = ({
console.error("Uploading file failed:", error);
let errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) errorMessage = error.message;
+ if (error instanceof BackendAPIClientError) errorMessage = error.message;
addSnackbar(`${failedToUploadStr}\n${errorMessage}`, "error");
},
@@ -106,7 +108,7 @@ export const PublicFileUploadDialog: React.FC = ({
diff --git a/apps/pyconkr-participant-portal/src/components/elements/public_file_selector.tsx b/apps/pyconkr-participant-portal/src/components/elements/public_file_selector.tsx
index a192d72..503b0cd 100644
--- a/apps/pyconkr-participant-portal/src/components/elements/public_file_selector.tsx
+++ b/apps/pyconkr-participant-portal/src/components/elements/public_file_selector.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useParticipantPortalClient, usePublicFilesQuery } from "@frontend/common/src/hooks/useParticipantPortalAPI";
import { PermMedia } from "@mui/icons-material";
import { Box, Button, CircularProgress, FormControl, InputLabel, MenuItem, Select, SelectProps, Stack, styled, useMediaQuery } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -19,20 +20,20 @@ type PublicFileSelectorState = {
openUploadDialog?: boolean;
};
-const ScaledFallbackImage = styled(Common.Components.FallbackImage)({
+const ScaledFallbackImage = styled(Components.FallbackImage)({
width: "100%",
maxWidth: "20rem",
objectFit: "contain",
});
export const PublicFileSelector: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, ({ value, onChange, disabled, ...props }) => {
const selectInputRef = React.useRef(null);
const [selectorState, setSelectorState] = React.useState({ value });
const { language } = useAppContext();
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const { data } = Common.Hooks.BackendParticipantPortalAPI.usePublicFilesQuery(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const { data } = usePublicFilesQuery(participantPortalClient);
const isMobile = useMediaQuery((theme) => theme.breakpoints.down("md"));
const setSelectedFile: SelectProps["onChange"] = (event, child) => {
diff --git a/apps/pyconkr-participant-portal/src/components/elements/signin_guard.tsx b/apps/pyconkr-participant-portal/src/components/elements/signin_guard.tsx
index b440472..b45597b 100644
--- a/apps/pyconkr-participant-portal/src/components/elements/signin_guard.tsx
+++ b/apps/pyconkr-participant-portal/src/components/elements/signin_guard.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { useParticipantPortalClient, useSignedInUserQuery } from "@frontend/common/src/hooks/useParticipantPortalAPI";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
import { Navigate } from "react-router-dom";
@@ -9,8 +9,8 @@ import { LoadingPage } from "./loading_page";
export const SignInGuard: React.FC = ErrorBoundary.with(
{ fallback: ErrorPage },
Suspense.with({ fallback: }, ({ children }) => {
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const { data } = Common.Hooks.BackendParticipantPortalAPI.useSignedInUserQuery(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const { data } = useSignedInUserQuery(participantPortalClient);
return data ? children : ;
})
diff --git a/apps/pyconkr-participant-portal/src/components/layout.tsx b/apps/pyconkr-participant-portal/src/components/layout.tsx
index 6cde96b..e271311 100644
--- a/apps/pyconkr-participant-portal/src/components/layout.tsx
+++ b/apps/pyconkr-participant-portal/src/components/layout.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { useParticipantPortalClient, useSignOutMutation, useSignedInUserQuery } from "@frontend/common/src/hooks/useParticipantPortalAPI";
import { AccountCircle } from "@mui/icons-material";
import { AppBar, ButtonBase, CircularProgress, IconButton, Menu, MenuItem, Stack, styled, Toolbar, Tooltip, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -60,7 +60,7 @@ type ProfileMenuButtonState = {
const InnerProfileMenuButton: React.FC = ({ loading, signedIn }) => {
const navigate = useNavigate();
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
+ const participantPortalClient = useParticipantPortalClient();
const [btnState, setBtnState] = React.useState({});
const openMenu: React.MouseEventHandler = (evt) => setBtnState((ps) => ({ ...ps, anchorEl: evt.currentTarget }));
const closeMenu = () => setBtnState((ps) => ({ ...ps, anchorEl: undefined }));
@@ -75,7 +75,7 @@ const InnerProfileMenuButton: React.FC = ({ loading, sig
closeMenu();
};
const goToSignIn = () => navigate("/signin");
- const signOutMutation = Common.Hooks.BackendParticipantPortalAPI.useSignOutMutation(participantPortalClient);
+ const signOutMutation = useSignOutMutation(participantPortalClient);
const onSignInOutClick = () => {
if (signedIn) signOutMutation.mutate();
else goToSignIn();
@@ -99,8 +99,8 @@ const InnerProfileMenuButton: React.FC = ({ loading, sig
const ProfileMenuButton: React.FC = ErrorBoundary.with(
{ fallback: },
Suspense.with({ fallback: }, () => {
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const { data } = Common.Hooks.BackendParticipantPortalAPI.useSignedInUserQuery(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const { data } = useSignedInUserQuery(participantPortalClient);
return ;
})
diff --git a/apps/pyconkr-participant-portal/src/components/pages/home.tsx b/apps/pyconkr-participant-portal/src/components/pages/home.tsx
index 8d68402..6b33112 100644
--- a/apps/pyconkr-participant-portal/src/components/pages/home.tsx
+++ b/apps/pyconkr-participant-portal/src/components/pages/home.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useListPresentationsQuery, useModificationAuditsQuery, useParticipantPortalClient, useSignedInUserQuery } from "@frontend/common/src/hooks/useParticipantPortalAPI";
import {
Button,
FormControlLabel,
@@ -69,7 +70,7 @@ const ProfileImageStyle: React.CSSProperties = {
textAlign: "center",
};
-const ProfileImage = styled(Common.Components.FallbackImage)(ProfileImageStyle);
+const ProfileImage = styled(Components.FallbackImage)(ProfileImageStyle);
const ProfileImageFallback: React.FC<{ language: "ko" | "en" }> = ({ language }) => {
const noProfileImageText = language === "ko" ? "프로필 이미지가 없어요." : "No profile image.";
@@ -94,10 +95,10 @@ const InnerLandingPage: React.FC = () => {
const navigate = useNavigate();
const { language } = useAppContext();
const isMobile = useMediaQuery((theme) => theme.breakpoints.down("sm"));
- const participantPortalAPIClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const { data: profile } = Common.Hooks.BackendParticipantPortalAPI.useSignedInUserQuery(participantPortalAPIClient);
- const { data: audits } = Common.Hooks.BackendParticipantPortalAPI.useModificationAuditsQuery(participantPortalAPIClient);
- const { data: sessions } = Common.Hooks.BackendParticipantPortalAPI.useListPresentationsQuery(participantPortalAPIClient);
+ const participantPortalAPIClient = useParticipantPortalClient();
+ const { data: profile } = useSignedInUserQuery(participantPortalAPIClient);
+ const { data: audits } = useModificationAuditsQuery(participantPortalAPIClient);
+ const { data: sessions } = useListPresentationsQuery(participantPortalAPIClient);
const ongoingAudits = audits.filter((audit) => audit.status === "requested");
const [state, setState] = React.useState({ showAllAudits: R.isEmpty(ongoingAudits) });
diff --git a/apps/pyconkr-participant-portal/src/components/pages/modification_audit_preview.tsx b/apps/pyconkr-participant-portal/src/components/pages/modification_audit_preview.tsx
index 3678096..9dbfade 100644
--- a/apps/pyconkr-participant-portal/src/components/pages/modification_audit_preview.tsx
+++ b/apps/pyconkr-participant-portal/src/components/pages/modification_audit_preview.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { useModificationAuditPreviewQuery, useParticipantPortalClient } from "@frontend/common/src/hooks/useParticipantPortalAPI";
import { Card, CardContent, Palette, PaletteColor, styled, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
@@ -100,8 +100,8 @@ const AuditNoticeHeader: React.FC = ({ language, audit }
export const InnerModificationAuditPreview: React.FC = () => {
const { language } = useAppContext();
const { auditId } = useParams<{ auditId?: string }>();
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const { data: auditData } = Common.Hooks.BackendParticipantPortalAPI.useModificationAuditPreviewQuery(participantPortalClient, auditId ?? "");
+ const participantPortalClient = useParticipantPortalClient();
+ const { data: auditData } = useModificationAuditPreviewQuery(participantPortalClient, auditId ?? "");
if (!auditData) return ;
diff --git a/apps/pyconkr-participant-portal/src/components/pages/profile_editor.tsx b/apps/pyconkr-participant-portal/src/components/pages/profile_editor.tsx
index 423d292..15ba6b2 100644
--- a/apps/pyconkr-participant-portal/src/components/pages/profile_editor.tsx
+++ b/apps/pyconkr-participant-portal/src/components/pages/profile_editor.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { useParticipantPortalClient, useSignedInUserQuery, useUpdateMeMutation } from "@frontend/common/src/hooks/useParticipantPortalAPI";
+import { BackendAPIClientError } from "@frontend/common/src/apis";
import { Key, SendAndArchive } from "@mui/icons-material";
import { Button, SelectChangeEvent, Stack } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -38,9 +39,9 @@ const DummyProfile: ProfileSchema = {
const InnerProfileEditor: React.FC = () => {
const { language } = useAppContext();
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const { data: profile } = Common.Hooks.BackendParticipantPortalAPI.useSignedInUserQuery(participantPortalClient);
- const updateMeMutation = Common.Hooks.BackendParticipantPortalAPI.useUpdateMeMutation(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const { data: profile } = useSignedInUserQuery(participantPortalClient);
+ const updateMeMutation = useUpdateMeMutation(participantPortalClient);
const [editorState, setEditorState] = React.useState({
openChangePasswordDialog: false,
openSubmitConfirmDialog: false,
@@ -86,7 +87,7 @@ const InnerProfileEditor: React.FC = () => {
console.error("Updating profile failed:", error);
let errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) errorMessage = error.message;
+ if (error instanceof BackendAPIClientError) errorMessage = error.message;
addSnackbar(errorMessage, "error");
},
diff --git a/apps/pyconkr-participant-portal/src/components/pages/session_editor.tsx b/apps/pyconkr-participant-portal/src/components/pages/session_editor.tsx
index 14bde5f..549e2e8 100644
--- a/apps/pyconkr-participant-portal/src/components/pages/session_editor.tsx
+++ b/apps/pyconkr-participant-portal/src/components/pages/session_editor.tsx
@@ -1,4 +1,6 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useParticipantPortalClient, useRetrievePresentationQuery, useUpdatePresentationMutation } from "@frontend/common/src/hooks/useParticipantPortalAPI";
+import { BackendAPIClientError } from "@frontend/common/src/apis";
import { SendAndArchive } from "@mui/icons-material";
import { Box, Button, Divider, SelectChangeEvent, Stack, TextField, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -138,7 +140,7 @@ export const SessionEditorForm: React.FC = ({ disabled,
disabled={disabled}
fullWidth
/>
-
+
= ({ disabled,
sx={{ mt: 2 }}
fullWidth
/>
-
+
{
const { sessionId } = useParams<{ sessionId?: string }>();
const { language } = useAppContext();
const [editorState, setEditorState] = React.useState({ openSubmitConfirmDialog: false });
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const updateSessionMutation = Common.Hooks.BackendParticipantPortalAPI.useUpdatePresentationMutation(participantPortalClient);
- const { data: session } = Common.Hooks.BackendParticipantPortalAPI.useRetrievePresentationQuery(participantPortalClient, sessionId || "");
+ const participantPortalClient = useParticipantPortalClient();
+ const updateSessionMutation = useUpdatePresentationMutation(participantPortalClient);
+ const { data: session } = useRetrievePresentationQuery(participantPortalClient, sessionId || "");
if (!sessionId || !session) return ;
@@ -251,7 +253,7 @@ const InnerSessionEditor: React.FC = () => {
console.error("Updating session failed:", error);
let errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) errorMessage = error.message;
+ if (error instanceof BackendAPIClientError) errorMessage = error.message;
addSnackbar(errorMessage, "error");
},
diff --git a/apps/pyconkr-participant-portal/src/components/pages/signin.tsx b/apps/pyconkr-participant-portal/src/components/pages/signin.tsx
index b8f71bf..c98369d 100644
--- a/apps/pyconkr-participant-portal/src/components/pages/signin.tsx
+++ b/apps/pyconkr-participant-portal/src/components/pages/signin.tsx
@@ -1,4 +1,7 @@
-import * as Common from "@frontend/common";
+import { useParticipantPortalClient, useSignInMutation, useSignedInUserQuery } from "@frontend/common/src/hooks/useParticipantPortalAPI";
+import { useEmail } from "@frontend/common/src/hooks/useEmail";
+import { getFormValue, isFormValid } from "@frontend/common/src/utils";
+import { BackendAPIClientError } from "@frontend/common/src/apis";
import { Button, Stack, TextField, Typography } from "@mui/material";
import { enqueueSnackbar, OptionsObject } from "notistack";
import * as React from "react";
@@ -10,10 +13,10 @@ import { Page } from "../page";
export const SignInPage: React.FC = () => {
const formRef = React.useRef(null);
const navigate = useNavigate();
- const { sendEmail } = Common.Hooks.Common.useEmail();
+ const { sendEmail } = useEmail();
const { language } = useAppContext();
- const participantPortalClient = Common.Hooks.BackendParticipantPortalAPI.useParticipantPortalClient();
- const { data } = Common.Hooks.BackendParticipantPortalAPI.useSignedInUserQuery(participantPortalClient);
+ const participantPortalClient = useParticipantPortalClient();
+ const { data } = useSignedInUserQuery(participantPortalClient);
if (data) return ;
const addSnackbar = (c: string | React.ReactNode, variant: OptionsObject["variant"]) =>
@@ -44,11 +47,11 @@ export const SignInPage: React.FC = () => {
>
);
- const signInMutation = Common.Hooks.BackendParticipantPortalAPI.useSignInMutation(participantPortalClient);
+ const signInMutation = useSignInMutation(participantPortalClient);
const signIn = () => {
- if (!Common.Utils.isFormValid(formRef.current)) return;
+ if (!isFormValid(formRef.current)) return;
- const formData = Common.Utils.getFormValue<{ identity: string; password: string }>({ form: formRef.current });
+ const formData = getFormValue<{ identity: string; password: string }>({ form: formRef.current });
signInMutation.mutate(formData, {
onSuccess: () => {
addSnackbar(signInSucceedStr, "success");
@@ -58,7 +61,7 @@ export const SignInPage: React.FC = () => {
console.error("Sign in failed:", error);
let errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) errorMessage = error.message;
+ if (error instanceof BackendAPIClientError) errorMessage = error.message;
addSnackbar(
<>
diff --git a/apps/pyconkr-participant-portal/src/main.tsx b/apps/pyconkr-participant-portal/src/main.tsx
index 8623564..64d9472 100644
--- a/apps/pyconkr-participant-portal/src/main.tsx
+++ b/apps/pyconkr-participant-portal/src/main.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import type { ContextOptions } from "@frontend/common/src/contexts";
import { CircularProgress, createTheme, CssBaseline, ThemeProvider } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import { matchQuery, MutationCache, QueryClient, QueryClientProvider } from "@tanstack/react-query";
@@ -33,7 +34,7 @@ const queryClient = new QueryClient({
export const muiTheme = createTheme();
-const CommonOptions: Common.Contexts.ContextOptions = {
+const CommonOptions: ContextOptions = {
language: "ko",
debug: IS_DEBUG_ENV,
baseUrl: ".",
@@ -44,9 +45,9 @@ const CommonOptions: Common.Contexts.ContextOptions = {
};
const SuspenseFallback = (
-
+
-
+
);
const MainApp: React.FC = () => {
@@ -61,7 +62,7 @@ const MainApp: React.FC = () => {
-
+
@@ -70,7 +71,7 @@ const MainApp: React.FC = () => {
-
+
diff --git a/apps/pyconkr-participant-portal/vite.config.mts b/apps/pyconkr-participant-portal/vite.config.mts
index d8314af..76b4827 100644
--- a/apps/pyconkr-participant-portal/vite.config.mts
+++ b/apps/pyconkr-participant-portal/vite.config.mts
@@ -13,6 +13,7 @@ export default defineConfig({
plugins: [react(), mdx(), mkcert({ hosts: ["local.dev.pycon.kr"] }), svgr()],
resolve: {
alias: {
+ "@frontend/common/src": path.resolve(__dirname, "../../packages/common/src"),
"@frontend/common": path.resolve(__dirname, "../../packages/common/src/index.ts"),
"@frontend/shop": path.resolve(__dirname, "../../packages/shop/src/index.ts"),
"@apps/pyconkr-participant-portal": path.resolve(__dirname, "./src"),
diff --git a/apps/pyconkr/src/App.tsx b/apps/pyconkr/src/App.tsx
index 8529ab2..7ce3a4c 100644
--- a/apps/pyconkr/src/App.tsx
+++ b/apps/pyconkr/src/App.tsx
@@ -1,9 +1,10 @@
-import * as Common from "@frontend/common";
+import { useBackendClient, useFlattenSiteMapQuery, useSponsorQuery } from "@frontend/common/src/hooks/useAPI";
+import { buildNestedSiteMap } from "@frontend/common/src/utils";
import * as React from "react";
import { Route, Routes, useLocation } from "react-router-dom";
import * as R from "remeda";
-import BackendAPISchemas from "../../../packages/common/src/schemas/backendAPI";
+import * as BackendAPISchemas from "@frontend/common/src/schemas/backendAPI";
import MainLayout from "./components/layout/index.tsx";
import { PageIdParamRenderer, RouteRenderer } from "./components/pages/dynamic_route.tsx";
import { PresentationDetailPage } from "./components/pages/presentation_detail.tsx";
@@ -14,10 +15,10 @@ import { IS_DEBUG_ENV } from "./consts";
import { useAppContext } from "./contexts/app_context";
export const App: React.FC = () => {
- const backendAPIClient = Common.Hooks.BackendAPI.useBackendClient();
- const { data: sponsorTiers } = Common.Hooks.BackendAPI.useSponsorQuery(backendAPIClient);
- const { data: flatSiteMap } = Common.Hooks.BackendAPI.useFlattenSiteMapQuery(backendAPIClient);
- const siteMapNode = Common.Utils.buildNestedSiteMap(flatSiteMap)?.[""];
+ const backendAPIClient = useBackendClient();
+ const { data: sponsorTiers } = useSponsorQuery(backendAPIClient);
+ const { data: flatSiteMap } = useFlattenSiteMapQuery(backendAPIClient);
+ const siteMapNode = buildNestedSiteMap(flatSiteMap)?.[""];
const location = useLocation();
const { setAppContext, language } = useAppContext();
diff --git a/apps/pyconkr/src/components/layout/Footer/Mobile/MobileFooter.tsx b/apps/pyconkr/src/components/layout/Footer/Mobile/MobileFooter.tsx
index 957f7aa..4df01d8 100644
--- a/apps/pyconkr/src/components/layout/Footer/Mobile/MobileFooter.tsx
+++ b/apps/pyconkr/src/components/layout/Footer/Mobile/MobileFooter.tsx
@@ -1,5 +1,5 @@
import styled from "@emotion/styled";
-import * as Common from "@frontend/common";
+import { useEmail } from "@frontend/common/src/hooks/useEmail";
import { Article, Email, Facebook, GitHub, Instagram, LinkedIn, X, YouTube } from "@mui/icons-material";
import * as React from "react";
@@ -45,7 +45,7 @@ const defaultIcons: IconItem[] = [
];
export default function MobileFooter() {
- const { sendEmail } = Common.Hooks.Common.useEmail();
+ const { sendEmail } = useEmail();
const { language } = useAppContext();
const title = language === "ko" ? "Weave with Python, 파이콘 한국 2025" : "Weave with Python, Pycon KR 2025";
diff --git a/apps/pyconkr/src/components/layout/Footer/index.tsx b/apps/pyconkr/src/components/layout/Footer/index.tsx
index 0235bac..7b3e108 100644
--- a/apps/pyconkr/src/components/layout/Footer/index.tsx
+++ b/apps/pyconkr/src/components/layout/Footer/index.tsx
@@ -1,5 +1,5 @@
import styled from "@emotion/styled";
-import * as Common from "@frontend/common";
+import { useEmail } from "@frontend/common/src/hooks/useEmail";
import { Article, Email, Facebook, GitHub, Instagram, LinkedIn, OpenInNew, X, YouTube } from "@mui/icons-material";
import { Button, useMediaQuery, useTheme } from "@mui/material";
import * as React from "react";
@@ -50,7 +50,7 @@ const defaultIcons: IconItem[] = [
const Bar: React.FC = () => |
;
export default function Footer() {
- const { sendEmail } = Common.Hooks.Common.useEmail();
+ const { sendEmail } = useEmail();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
diff --git a/apps/pyconkr/src/components/layout/Header/Mobile/MobileHeader.tsx b/apps/pyconkr/src/components/layout/Header/Mobile/MobileHeader.tsx
index 03b2f92..c93d8e9 100644
--- a/apps/pyconkr/src/components/layout/Header/Mobile/MobileHeader.tsx
+++ b/apps/pyconkr/src/components/layout/Header/Mobile/MobileHeader.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import { Box, Stack, styled, Typography } from "@mui/material";
import * as React from "react";
import { Link, useLocation } from "react-router-dom";
@@ -31,7 +31,7 @@ export const MobileHeader: React.FC = ({ isNavigationOpen = f
-
+
= ({ isOpen, onCl
-
+
파이콘 한국 2025
diff --git a/apps/pyconkr/src/components/layout/Header/index.tsx b/apps/pyconkr/src/components/layout/Header/index.tsx
index b6055ca..dcdb843 100644
--- a/apps/pyconkr/src/components/layout/Header/index.tsx
+++ b/apps/pyconkr/src/components/layout/Header/index.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import { ArrowForwardIos } from "@mui/icons-material";
import { Box, Button, CircularProgress, Divider, Stack, styled, SxProps, Theme, Typography, useMediaQuery, useTheme } from "@mui/material";
import { MUIStyledCommonProps } from "@mui/system";
@@ -63,7 +63,7 @@ const Header: React.FC = () => {
-
+
diff --git a/apps/pyconkr/src/components/pages/dynamic_route.tsx b/apps/pyconkr/src/components/pages/dynamic_route.tsx
index bc39578..0f71780 100644
--- a/apps/pyconkr/src/components/pages/dynamic_route.tsx
+++ b/apps/pyconkr/src/components/pages/dynamic_route.tsx
@@ -1,4 +1,7 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendClient, usePageQuery } from "@frontend/common/src/hooks/useAPI";
+import { parseCss } from "@frontend/common/src/utils";
+import { BackendAPIClientError } from "@frontend/common/src/apis";
import { CircularProgress, Stack, Theme } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import { useQueryClient } from "@tanstack/react-query";
@@ -58,9 +61,9 @@ const LoginRequired: React.FC = () => <>401 Login Required>;
const PermissionDenied: React.FC = () => <>403 Permission Denied>;
const PageNotFound: React.FC = () => <>404 Not Found>;
const CenteredLoadingPage: React.FC = () => (
-
+
-
+
);
const throwPageNotFound: (message: string) => never = (message) => {
@@ -68,11 +71,11 @@ const throwPageNotFound: (message: string) => never = (message) => {
const axiosError = new AxiosError(errorStr, errorStr, undefined, undefined, {
status: 404,
} as AxiosResponse);
- throw new Common.BackendAPIs.BackendAPIClientError(axiosError);
+ throw new BackendAPIClientError(axiosError);
};
const RouteErrorFallback: React.FC<{ error: Error; reset: () => void }> = ({ error, reset }) => {
- if (error instanceof Common.BackendAPIs.BackendAPIClientError) {
+ if (error instanceof BackendAPIClientError) {
switch (error.status) {
case 401:
return ;
@@ -81,10 +84,10 @@ const RouteErrorFallback: React.FC<{ error: Error; reset: () => void }> = ({ err
case 404:
return ;
default:
- return ;
+ return ;
}
}
- return ;
+ return ;
};
const WaitedCenteredLoadingPage: React.FC = Suspense.with({ fallback: }, () => {
@@ -101,8 +104,8 @@ const WaitedCenteredLoadingPage: React.FC = Suspense.with({ fallback: = Suspense.with({ fallback: }, ({ id }) => {
const { setAppContext } = useAppContext();
- const backendClient = Common.Hooks.BackendAPI.useBackendClient();
- const { data } = Common.Hooks.BackendAPI.usePageQuery(backendClient, id);
+ const backendClient = useBackendClient();
+ const { data } = usePageQuery(backendClient, id);
React.useEffect(() => {
setAppContext((prev) => ({
@@ -114,10 +117,10 @@ const InnerPageRenderer: React.FC<{ id: string }> = Suspense.with({ fallback:
+
{data.sections.map((s) => (
-
-
+
+
))}
diff --git a/apps/pyconkr/src/components/pages/presentation_detail.tsx b/apps/pyconkr/src/components/pages/presentation_detail.tsx
index 8183a16..790ad4e 100644
--- a/apps/pyconkr/src/components/pages/presentation_detail.tsx
+++ b/apps/pyconkr/src/components/pages/presentation_detail.tsx
@@ -1,4 +1,5 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { useBackendClient, useSessionQuery } from "@frontend/common/src/hooks/useAPI";
import { Box, Chip, CircularProgress, Divider, Stack, styled, Table, TableBody, TableCell, TableRow, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import { DateTime } from "luxon";
@@ -20,12 +21,12 @@ type SimplifiedSpeakerSchema = {
};
const CenteredLoadingPage: React.FC = () => (
-
+
-
+
);
-const StyledPresentationImage = styled(Common.Components.FallbackImage)(({ theme }) => ({
+const StyledPresentationImage = styled(Components.FallbackImage)(({ theme }) => ({
maxWidth: "75%",
maxHeight: "480px",
aspectRatio: "1",
@@ -90,7 +91,7 @@ const ProfileImageStyle: React.CSSProperties = {
objectFit: "cover",
};
-const ProfileImage = styled(Common.Components.FallbackImage)(ProfileImageStyle);
+const ProfileImage = styled(Components.FallbackImage)(ProfileImageStyle);
const ProfileImageErrorFallback: React.FC = () => (
@@ -108,7 +109,7 @@ const PresentationSpeakerItem: React.FC<{ speaker: SimplifiedSpeakerSchema }> =
{speaker.biography ? (
- } />
+ } />
) : (
<>
@@ -142,12 +143,12 @@ const PresentationImageFallback: React.FC<{ language: "ko" | "en" }> = ({ langua
};
export const PresentationDetailPage: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
const { id } = useParams();
const { language, setAppContext } = useAppContext();
- const backendClient = Common.Hooks.BackendAPI.useBackendClient();
- const { data: presentation } = Common.Hooks.BackendAPI.useSessionQuery(backendClient, id || "");
+ const backendClient = useBackendClient();
+ const { data: presentation } = useSessionQuery(backendClient, id || "");
if (!id || !presentation) return ;
@@ -244,7 +245,7 @@ export const PresentationDetailPage: React.FC = ErrorBoundary.with(
} />
({ color: theme.palette.primary.main, textDecoration: "underline" })}>
-
+
) : null}
@@ -258,7 +259,7 @@ export const PresentationDetailPage: React.FC = ErrorBoundary.with(
/>
)}
-
+
{presentation.speakers && (
diff --git a/apps/pyconkr/src/components/pages/sponsor_detail.tsx b/apps/pyconkr/src/components/pages/sponsor_detail.tsx
index 9adb7b7..c9e1632 100644
--- a/apps/pyconkr/src/components/pages/sponsor_detail.tsx
+++ b/apps/pyconkr/src/components/pages/sponsor_detail.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import { Box, Chip, CircularProgress, Divider, Stack, styled, Typography } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
import * as React from "react";
@@ -11,9 +11,9 @@ import { PageLayout } from "../layout/PageLayout";
const PageNotFound: React.FC = () => <>404 Not Found>;
const CenteredLoadingPage: React.FC = () => (
-
+
-
+
);
const LogoImage = styled("img")(({ theme }) => ({
@@ -50,7 +50,7 @@ const DescriptionBox = styled(Box)(({ theme }) => ({
}));
export const SponsorDetailPage: React.FC = ErrorBoundary.with(
- { fallback: Common.Components.ErrorFallback },
+ { fallback: Components.ErrorFallback },
Suspense.with({ fallback: }, () => {
const { id } = useParams();
const { language, sponsorTiers, setAppContext } = useAppContext();
@@ -88,7 +88,7 @@ export const SponsorDetailPage: React.FC = ErrorBoundary.with(
-
+
);
diff --git a/apps/pyconkr/src/consts/mdx_components.ts b/apps/pyconkr/src/consts/mdx_components.ts
index ef65626..8b2b767 100644
--- a/apps/pyconkr/src/consts/mdx_components.ts
+++ b/apps/pyconkr/src/consts/mdx_components.ts
@@ -1,5 +1,5 @@
// 후대의 개발자님께 : 컴포넌트 맨 첫글자가 대문자로 시작하지 않으면 JSX 컴포넌트가 아니라 일반 HTML 태그로 인식합니다. 제발 대문자로 시작해주세요.
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import * as Shop from "@frontend/shop";
import * as mui from "@mui/material";
import type { MDXComponents } from "mdx/types.js";
@@ -131,16 +131,16 @@ const MUIMDXComponents: MDXComponents = {
};
const PyConKRCommonMDXComponents: MDXComponents = {
- Common__Components__Lottie: Common.Components.LottiePlayer,
- Common__Components__NetworkLottie: Common.Components.NetworkLottiePlayer,
- Common__Components__MDX__Confetti: Common.Components.MDX.Confetti,
- Common__Components__MDX__PrimaryStyledDetails: Common.Components.MDX.PrimaryStyledDetails,
- Common__Components__MDX__SecondaryStyledDetails: Common.Components.MDX.SecondaryStyledDetails,
- Common__Components__MDX__Map: Common.Components.MDX.Map,
- Common__Components__MDX__FAQAccordion: Common.Components.MDX.FAQAccordion,
- Common__Components__MDX__FullWidthStyledButton: Common.Components.MDX.StyledFullWidthButton,
- Common__Components__Session__List: Common.Components.MDX.SessionList,
- Common__Components__Session__TimeTable: Common.Components.MDX.SessionTimeTable,
+ Common__Components__Lottie: Components.LottiePlayer,
+ Common__Components__NetworkLottie: Components.NetworkLottiePlayer,
+ Common__Components__MDX__Confetti: Components.MDX.Confetti,
+ Common__Components__MDX__PrimaryStyledDetails: Components.MDX.PrimaryStyledDetails,
+ Common__Components__MDX__SecondaryStyledDetails: Components.MDX.SecondaryStyledDetails,
+ Common__Components__MDX__Map: Components.MDX.Map,
+ Common__Components__MDX__FAQAccordion: Components.MDX.FAQAccordion,
+ Common__Components__MDX__FullWidthStyledButton: Components.MDX.StyledFullWidthButton,
+ Common__Components__Session__List: Components.MDX.SessionList,
+ Common__Components__Session__TimeTable: Components.MDX.SessionTimeTable,
};
const PythonKRShopMDXComponents: MDXComponents = {
diff --git a/apps/pyconkr/src/debug/page/component_test.tsx b/apps/pyconkr/src/debug/page/component_test.tsx
index 0635c2f..b406c61 100644
--- a/apps/pyconkr/src/debug/page/component_test.tsx
+++ b/apps/pyconkr/src/debug/page/component_test.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import { Chip, Stack, Table, TableBody, TableCell, TableRow } from "@mui/material";
import * as React from "react";
@@ -17,7 +17,7 @@ const HighlightedChip: React.FC<{ label: string }> = ({ label }) => (
export const ComponentTestPage: React.FC = () => {
return (
-
+
모든 자동차의 출입은 동국대 정문으로만 가능
@@ -47,9 +47,9 @@ export const ComponentTestPage: React.FC = () => {
-
+
-
+
모든 자동차의 출입은 동국대 정문으로만 가능
@@ -79,7 +79,7 @@ export const ComponentTestPage: React.FC = () => {
-
+
);
};
diff --git a/apps/pyconkr/src/debug/page/map_test.tsx b/apps/pyconkr/src/debug/page/map_test.tsx
index 6f5d097..9c6bace 100644
--- a/apps/pyconkr/src/debug/page/map_test.tsx
+++ b/apps/pyconkr/src/debug/page/map_test.tsx
@@ -1,13 +1,14 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import { getFormValue, isFormValid } from "@frontend/common/src/utils";
import { Box, Button, FormControlLabel, Stack, Switch, TextField } from "@mui/material";
import * as React from "react";
type MapTestPageStateType = {
checked: boolean;
- mapProps: Common.Components.MDX.MapPropType;
+ mapProps: Components.MDX.MapPropType;
};
-const INITIAL_DATA: Common.Components.MDX.MapPropType = {
+const INITIAL_DATA: Components.MDX.MapPropType = {
geo: { lat: 37.5580918, lng: 126.9982178 },
placeName: {
ko: "동국대학교 신공학관",
@@ -41,21 +42,21 @@ export const MapTestPage: React.FC = () => {
[geoForm, pNameForm, pCodeForm, gMapIframeUrl].forEach((formOrInput, index) => {
if (!formOrInput) throw new Error(`${formOrInput}[${index}] is not defined.`);
- if (formOrInput instanceof HTMLFormElement && !Common.Utils.isFormValid(formOrInput)) throw new Error(`${formOrInput}[${index}] is not valid.`);
+ if (formOrInput instanceof HTMLFormElement && !isFormValid(formOrInput)) throw new Error(`${formOrInput}[${index}] is not valid.`);
if (formOrInput instanceof HTMLInputElement && !formOrInput.checkValidity()) throw new Error(`${formOrInput}[${index}] is not valid.`);
});
if (!(geoForm && pNameForm && pCodeForm && gMapIframeUrl)) return;
- const strGeo = Common.Utils.getFormValue<{ lat: string; lng: string }>({ form: geoForm });
+ const strGeo = getFormValue<{ lat: string; lng: string }>({ form: geoForm });
if (!strGeo.lat || !strGeo.lng || isNaN(parseFloat(strGeo.lat)) || isNaN(parseFloat(strGeo.lng))) {
alert("위도와 경도를 올바르게 입력해주세요.");
return;
}
const geo = { lat: parseFloat(strGeo.lat), lng: parseFloat(strGeo.lng) };
const googleMapIframeSrc = gMapIframeUrl.value.trim();
- const placeCode = Common.Utils.getFormValue<{ kakao: string; naver: string; google: string }>({ form: pCodeForm });
- const placeName = Common.Utils.getFormValue<{ ko: string; en: string }>({ form: pNameForm });
+ const placeCode = getFormValue<{ kakao: string; naver: string; google: string }>({ form: pCodeForm });
+ const placeName = getFormValue<{ ko: string; en: string }>({ form: pNameForm });
placeName.ko = placeName.ko.trim().replace("\\n", "\n");
placeName.en = placeName.en.trim().replace("\\n", "\n");
@@ -89,7 +90,7 @@ export const MapTestPage: React.FC = () => {
-
+
);
diff --git a/apps/pyconkr/src/debug/page/mdi_test.tsx b/apps/pyconkr/src/debug/page/mdi_test.tsx
index f68d833..4c55d52 100644
--- a/apps/pyconkr/src/debug/page/mdi_test.tsx
+++ b/apps/pyconkr/src/debug/page/mdi_test.tsx
@@ -1,4 +1,4 @@
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
import { Box, Stack } from "@mui/material";
import React from "react";
@@ -25,10 +25,10 @@ export const MdiTestPage: React.FC = () => {
}}
>
-
+
-
+
);
diff --git a/apps/pyconkr/src/main.tsx b/apps/pyconkr/src/main.tsx
index 705368a..475971f 100644
--- a/apps/pyconkr/src/main.tsx
+++ b/apps/pyconkr/src/main.tsx
@@ -1,5 +1,6 @@
import { Global } from "@emotion/react";
-import * as Common from "@frontend/common";
+import { Components } from "@frontend/common";
+import type { ContextOptions } from "@frontend/common/src/contexts";
import * as Shop from "@frontend/shop";
import { CircularProgress, CssBaseline, ThemeProvider } from "@mui/material";
import { ErrorBoundary, Suspense } from "@suspensive/react";
@@ -42,7 +43,7 @@ const queryClient = new QueryClient({
}),
});
-const CommonOptions: Common.Contexts.ContextOptions = {
+const CommonOptions: ContextOptions = {
language: "ko",
debug: IS_DEBUG_ENV,
baseUrl: ".",
@@ -60,9 +61,9 @@ const ShopOptions: Shop.Contexts.ContextOptions = {
};
const SuspenseFallback = (
-
+
-
+
);
const MainApp: React.FC = () => {
@@ -83,9 +84,9 @@ const MainApp: React.FC = () => {
-
+
-
+
@@ -95,7 +96,7 @@ const MainApp: React.FC = () => {
-
+
diff --git a/apps/pyconkr/vite.config.mts b/apps/pyconkr/vite.config.mts
index 9765567..857fbbd 100644
--- a/apps/pyconkr/vite.config.mts
+++ b/apps/pyconkr/vite.config.mts
@@ -13,6 +13,7 @@ export default defineConfig({
plugins: [react(), mdx(), mkcert({ hosts: ["local.dev.pycon.kr"] }), svgr()],
resolve: {
alias: {
+ "@frontend/common/src": path.resolve(__dirname, "../../packages/common/src"),
"@frontend/common": path.resolve(__dirname, "../../packages/common/src/index.ts"),
"@frontend/shop": path.resolve(__dirname, "../../packages/shop/src/index.ts"),
"@apps/pyconkr": path.resolve(__dirname, "./src"),
diff --git a/packages/common/src/apis/admin_api.ts b/packages/common/src/apis/admin_api.ts
index 8ecc7a3..f3544fc 100644
--- a/packages/common/src/apis/admin_api.ts
+++ b/packages/common/src/apis/admin_api.ts
@@ -1,105 +1,107 @@
import { BackendAPIClient } from "./client";
-import BackendAdminAPISchemas from "../schemas/backendAdminAPI";
-
-namespace BackendAdminAPIs {
- export const me = (client: BackendAPIClient) => async () => {
- try {
- return await client.get("v1/admin-api/user/userext/me/");
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- } catch (_) {
- return null;
- }
+import {
+ AdminSchemaDefinition,
+ ChoicesResponse,
+ ModificationAuditPreviewSchema,
+ ModificationAuditSchema,
+ OpenAPISchema,
+ PageSectionBulkUpdateSchema,
+ PageSectionSchema,
+ PublicFileSchema,
+ UserChangePasswordSchema,
+ UserResetPasswordResponseSchema,
+ UserSchema,
+ UserSignInSchema,
+} from "../schemas/backendAdminAPI";
+
+export const me = (client: BackendAPIClient) => async () => {
+ try {
+ return await client.get("v1/admin-api/user/userext/me/");
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ } catch (_) {
+ return null;
+ }
+};
+
+export const signIn = (client: BackendAPIClient) => (data: UserSignInSchema) =>
+ client.post("v1/admin-api/user/userext/signin/", data);
+
+export const signOut = (client: BackendAPIClient) => () => client.delete("v1/admin-api/user/userext/signout/");
+
+export const changePassword = (client: BackendAPIClient) => (data: UserChangePasswordSchema) =>
+ client.post("v1/admin-api/user/userext/password/", data);
+
+export const resetUserPassword = (client: BackendAPIClient, id: string) => () =>
+ client.delete(`v1/admin-api/user/userext/${id}/password/`);
+
+export const list =
+ (client: BackendAPIClient, app: string, resource: string, params?: Record) =>
+ () =>
+ client.get(`v1/admin-api/${app}/${resource}/`, { params });
+
+export const retrieve =
+ (client: BackendAPIClient, app: string, resource: string, id: string) =>
+ () => {
+ if (!id) return Promise.resolve(null);
+ return client.get(`v1/admin-api/${app}/${resource}/${id}/`);
};
- export const signIn = (client: BackendAPIClient) => (data: BackendAdminAPISchemas.UserSignInSchema) =>
- client.post("v1/admin-api/user/userext/signin/", data);
-
- export const signOut = (client: BackendAPIClient) => () => client.delete("v1/admin-api/user/userext/signout/");
-
- export const changePassword = (client: BackendAPIClient) => (data: BackendAdminAPISchemas.UserChangePasswordSchema) =>
- client.post("v1/admin-api/user/userext/password/", data);
-
- export const resetUserPassword = (client: BackendAPIClient, id: string) => () =>
- client.delete(`v1/admin-api/user/userext/${id}/password/`);
-
- export const list =
- (client: BackendAPIClient, app: string, resource: string, params?: Record) =>
- () =>
- client.get(`v1/admin-api/${app}/${resource}/`, { params });
-
- export const retrieve =
- (client: BackendAPIClient, app: string, resource: string, id: string) =>
- () => {
- if (!id) return Promise.resolve(null);
- return client.get(`v1/admin-api/${app}/${resource}/${id}/`);
- };
-
- export const create =
- (client: BackendAPIClient, app: string, resource: string) =>
- (data: T) =>
- client.post, T>(`v1/admin-api/${app}/${resource}/`, data);
-
- export const update =
- (client: BackendAPIClient, app: string, resource: string, id: string) =>
- (data: Omit) =>
- client.patch>(`v1/admin-api/${app}/${resource}/${id}/`, data);
-
- export const updatePrepared =
- (client: BackendAPIClient, app: string, resource: string) =>
- (data: T) =>
- client.patch>(`v1/admin-api/${app}/${resource}/${data.id}/`, data);
-
- export const remove = (client: BackendAPIClient, app: string, resource: string, id: string) => () =>
- client.delete(`v1/admin-api/${app}/${resource}/${id}/`);
-
- export const removePrepared = (client: BackendAPIClient, app: string, resource: string) => (id: string) =>
- client.delete(`v1/admin-api/${app}/${resource}/${id}/`);
-
- export const schema = (client: BackendAPIClient, app: string, resource: string) => () =>
- client.get(`v1/admin-api/${app}/${resource}/json-schema/`);
-
- export const choices = (client: BackendAPIClient, app: string, resource: string) => () =>
- client.get(`v1/admin-api/${app}/${resource}/choices/`);
-
- export const openApiSchema = (client: BackendAPIClient) => () =>
- client.get("api/schema/v1/", { params: { format: "json" } });
-
- export const uploadPublicFile = (client: BackendAPIClient) => (file: File) => {
- const formData = new FormData();
- formData.append("file", file);
- return client.post(`v1/admin-api/file/publicfile/upload/`, formData, {
- headers: { "Content-Type": "multipart/form-data" },
- });
- };
-
- export const listSections = (client: BackendAPIClient, pageId: string) => () => {
- if (!pageId) return Promise.resolve([]);
- return client.get(`v1/admin-api/cms/page/${pageId}/section/`);
- };
-
- export const bulkUpdateSections =
- (client: BackendAPIClient, pageId: string) => (data: { sections: BackendAdminAPISchemas.PageSectionBulkUpdateSchema[] }) =>
- client.put(
- `v1/admin-api/cms/page/${pageId}/section/bulk-update/`,
- data
- );
-
- export const approveModificationAudit = (client: BackendAPIClient, id: string) => (reason?: string | null) =>
- client.patch(
- `v1/admin-api/modification-audit/modification-audit/${id}/approve/`,
- { reason: reason ?? null }
- );
-
- export const rejectModificationAudit = (client: BackendAPIClient, id: string) => (reason?: string | null) =>
- client.patch(
- `v1/admin-api/modification-audit/modification-audit/${id}/reject/`,
- { reason: reason ?? null }
- );
-
- export const previewModificationAudit =
- (client: BackendAPIClient, id: string) =>
- () =>
- client.get>(`v1/admin-api/modification-audit/modification-audit/${id}/preview/`);
-}
-
-export default BackendAdminAPIs;
+export const create =
+ (client: BackendAPIClient, app: string, resource: string) =>
+ (data: T) =>
+ client.post, T>(`v1/admin-api/${app}/${resource}/`, data);
+
+export const update =
+ (client: BackendAPIClient, app: string, resource: string, id: string) =>
+ (data: Omit) =>
+ client.patch>(`v1/admin-api/${app}/${resource}/${id}/`, data);
+
+export const updatePrepared =
+ (client: BackendAPIClient, app: string, resource: string) =>
+ (data: T) =>
+ client.patch>(`v1/admin-api/${app}/${resource}/${data.id}/`, data);
+
+export const remove = (client: BackendAPIClient, app: string, resource: string, id: string) => () =>
+ client.delete(`v1/admin-api/${app}/${resource}/${id}/`);
+
+export const removePrepared = (client: BackendAPIClient, app: string, resource: string) => (id: string) =>
+ client.delete(`v1/admin-api/${app}/${resource}/${id}/`);
+
+export const schema = (client: BackendAPIClient, app: string, resource: string) => () =>
+ client.get(`v1/admin-api/${app}/${resource}/json-schema/`);
+
+export const uploadPublicFile = (client: BackendAPIClient) => (file: File) => {
+ const formData = new FormData();
+ formData.append("file", file);
+ return client.post(`v1/admin-api/file/publicfile/upload/`, formData, {
+ headers: { "Content-Type": "multipart/form-data" },
+ });
+};
+
+export const listSections = (client: BackendAPIClient, pageId: string) => () => {
+ if (!pageId) return Promise.resolve([]);
+ return client.get(`v1/admin-api/cms/page/${pageId}/section/`);
+};
+
+export const choices = (client: BackendAPIClient, app: string, resource: string) => () =>
+ client.get(`v1/admin-api/${app}/${resource}/choices/`);
+
+export const openApiSchema = (client: BackendAPIClient) => () => client.get("api/schema/v1/", { params: { format: "json" } });
+
+export const bulkUpdateSections = (client: BackendAPIClient, pageId: string) => (data: { sections: PageSectionBulkUpdateSchema[] }) =>
+ client.put(`v1/admin-api/cms/page/${pageId}/section/bulk-update/`, data);
+
+export const approveModificationAudit = (client: BackendAPIClient, id: string) => (reason?: string | null) =>
+ client.patch(`v1/admin-api/modification-audit/modification-audit/${id}/approve/`, {
+ reason: reason ?? null,
+ });
+
+export const rejectModificationAudit = (client: BackendAPIClient, id: string) => (reason?: string | null) =>
+ client.patch(`v1/admin-api/modification-audit/modification-audit/${id}/reject/`, {
+ reason: reason ?? null,
+ });
+
+export const previewModificationAudit =
+ (client: BackendAPIClient, id: string) =>
+ () =>
+ client.get>(`v1/admin-api/modification-audit/modification-audit/${id}/preview/`);
diff --git a/packages/common/src/apis/client.ts b/packages/common/src/apis/client.ts
index f8506bd..958b461 100644
--- a/packages/common/src/apis/client.ts
+++ b/packages/common/src/apis/client.ts
@@ -1,7 +1,7 @@
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import * as R from "remeda";
-import BackendAPISchemas from "../schemas/backendAPI";
+import * as BackendAPISchemas from "../schemas/backendAPI";
import { getCookie } from "../utils/cookie";
const DEFAULT_ERROR_MESSAGE = "알 수 없는 문제가 발생했습니다, 잠시 후 다시 시도해주세요.";
diff --git a/packages/common/src/apis/index.ts b/packages/common/src/apis/index.ts
index 0166366..664752c 100644
--- a/packages/common/src/apis/index.ts
+++ b/packages/common/src/apis/index.ts
@@ -1,17 +1,13 @@
import { BackendAPIClient, BackendAPIClientError as _BackendAPIClientError } from "./client";
-import BackendAPISchemas from "../schemas/backendAPI";
+import * as BackendAPISchemas from "../schemas/backendAPI";
-namespace BackendAPIs {
- export const BackendAPIClientError = _BackendAPIClientError;
- export const listSiteMaps = (client: BackendAPIClient) => () => client.get("v1/cms/sitemap/");
- export const retrievePage = (client: BackendAPIClient) => (id: string) => client.get(`v1/cms/page/${id}/`);
- export const listSponsors = (client: BackendAPIClient) => () => client.get("v1/event/sponsor/");
- export const listSessions = (client: BackendAPIClient, params?: BackendAPISchemas.SessionQueryParameterSchema) => () =>
- client.get("v1/event/presentation/", { params });
- export const retrieveSession = (client: BackendAPIClient) => (id: string) => {
- if (!id) return Promise.resolve(null);
- return client.get(`v1/event/presentation/${id}/`);
- };
-}
-
-export default BackendAPIs;
+export const BackendAPIClientError = _BackendAPIClientError;
+export const listSiteMaps = (client: BackendAPIClient) => () => client.get("v1/cms/sitemap/");
+export const retrievePage = (client: BackendAPIClient) => (id: string) => client.get(`v1/cms/page/${id}/`);
+export const listSponsors = (client: BackendAPIClient) => () => client.get("v1/event/sponsor/");
+export const listSessions = (client: BackendAPIClient, params?: BackendAPISchemas.SessionQueryParameterSchema) => () =>
+ client.get("v1/event/presentation/", { params });
+export const retrieveSession = (client: BackendAPIClient) => (id: string) => {
+ if (!id) return Promise.resolve(null);
+ return client.get(`v1/event/presentation/${id}/`);
+};
diff --git a/packages/common/src/apis/participant_portal_api.ts b/packages/common/src/apis/participant_portal_api.ts
index 355b0fd..b09c0f4 100644
--- a/packages/common/src/apis/participant_portal_api.ts
+++ b/packages/common/src/apis/participant_portal_api.ts
@@ -1,80 +1,76 @@
import { BackendAPIClient } from "./client";
-import ParticipantPortalAPISchemas from "../schemas/backendParticipantPortalAPI";
-
-namespace BackendParticipantPortalAPIs {
- export const me = (client: BackendAPIClient) => async () => {
- try {
- return await client.get("v1/participant-portal/user/me/");
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- } catch (_) {
- return null;
- }
- };
-
- export const updateMe = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.UserUpdateSchema) =>
- client.patch("v1/participant-portal/user/me/", data);
-
- export const previewMeModAudit = (client: BackendAPIClient) => async () =>
- client.get("v1/participant-portal/user/me/preview/");
-
- export const signIn = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.UserSignInSchema) =>
- client.post("v1/participant-portal/user/signin/", data);
-
- export const signOut = (client: BackendAPIClient) => () => client.delete("v1/participant-portal/user/signout/");
-
- export const changePassword = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.UserChangePasswordSchema) =>
- client.put("v1/participant-portal/user/password/", data);
-
- export const listPublicFiles = (client: BackendAPIClient) => () =>
- client.get("v1/participant-portal/public-file/");
-
- export const uploadPublicFile = (client: BackendAPIClient) => (file: File) => {
- const formData = new FormData();
- formData.append("file", file);
- return client.post(`v1/participant-portal/public-file/upload/`, formData, {
- headers: { "Content-Type": "multipart/form-data" },
- });
- };
-
- export const listPresentations = (client: BackendAPIClient) => () =>
- client.get("v1/participant-portal/presentation/");
-
- export const retrievePresentation = (client: BackendAPIClient, id: string) => () => {
- if (!id) return Promise.resolve(null);
- return client.get(`v1/participant-portal/presentation/${id}/`);
- };
-
- export const previewPresentationModAudit = (client: BackendAPIClient, id: string) => () => {
- if (!id) return Promise.resolve(null);
- return client.get(`v1/participant-portal/presentation/${id}/preview/`);
- };
-
- export const patchPresentation = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.PresentationUpdateSchema) =>
- client.patch(
- `v1/participant-portal/presentation/${data.id}/`,
- data
- );
-
- export const listModificationAudits = (client: BackendAPIClient) => () =>
- client.get("v1/participant-portal/modification-audit/");
-
- export const previewModificationAudit = (client: BackendAPIClient, id: string) => () => {
- try {
- return client.get(`v1/participant-portal/modification-audit/${id}/preview/`);
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- } catch (_) {
- return Promise.resolve(null);
- }
- };
-
- export const retrieveModificationAudit = (client: BackendAPIClient, id: string) => () =>
- client.get(`v1/participant-portal/modification-audit/${id}`);
-
- export const cancelModificationAudit = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.ModificationAuditCancelRequestSchema) =>
- client.patch(
- `v1/participant-portal/modification-audit/${data.id}/cancel/`,
- data
- );
-}
-
-export default BackendParticipantPortalAPIs;
+import * as ParticipantPortalAPISchemas from "../schemas/backendParticipantPortalAPI";
+
+export const me = (client: BackendAPIClient) => async () => {
+ try {
+ return await client.get("v1/participant-portal/user/me/");
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ } catch (_) {
+ return null;
+ }
+};
+
+export const updateMe = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.UserUpdateSchema) =>
+ client.patch("v1/participant-portal/user/me/", data);
+
+export const previewMeModAudit = (client: BackendAPIClient) => async () =>
+ client.get("v1/participant-portal/user/me/preview/");
+
+export const signIn = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.UserSignInSchema) =>
+ client.post("v1/participant-portal/user/signin/", data);
+
+export const signOut = (client: BackendAPIClient) => () => client.delete("v1/participant-portal/user/signout/");
+
+export const changePassword = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.UserChangePasswordSchema) =>
+ client.put("v1/participant-portal/user/password/", data);
+
+export const listPublicFiles = (client: BackendAPIClient) => () =>
+ client.get("v1/participant-portal/public-file/");
+
+export const uploadPublicFile = (client: BackendAPIClient) => (file: File) => {
+ const formData = new FormData();
+ formData.append("file", file);
+ return client.post(`v1/participant-portal/public-file/upload/`, formData, {
+ headers: { "Content-Type": "multipart/form-data" },
+ });
+};
+
+export const listPresentations = (client: BackendAPIClient) => () =>
+ client.get("v1/participant-portal/presentation/");
+
+export const retrievePresentation = (client: BackendAPIClient, id: string) => () => {
+ if (!id) return Promise.resolve(null);
+ return client.get(`v1/participant-portal/presentation/${id}/`);
+};
+
+export const previewPresentationModAudit = (client: BackendAPIClient, id: string) => () => {
+ if (!id) return Promise.resolve(null);
+ return client.get(`v1/participant-portal/presentation/${id}/preview/`);
+};
+
+export const patchPresentation = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.PresentationUpdateSchema) =>
+ client.patch(
+ `v1/participant-portal/presentation/${data.id}/`,
+ data
+ );
+
+export const listModificationAudits = (client: BackendAPIClient) => () =>
+ client.get("v1/participant-portal/modification-audit/");
+
+export const previewModificationAudit = (client: BackendAPIClient, id: string) => () => {
+ try {
+ return client.get(`v1/participant-portal/modification-audit/${id}/preview/`);
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ } catch (_) {
+ return Promise.resolve(null);
+ }
+};
+
+export const retrieveModificationAudit = (client: BackendAPIClient, id: string) => () =>
+ client.get(`v1/participant-portal/modification-audit/${id}`);
+
+export const cancelModificationAudit = (client: BackendAPIClient) => (data: ParticipantPortalAPISchemas.ModificationAuditCancelRequestSchema) =>
+ client.patch(
+ `v1/participant-portal/modification-audit/${data.id}/cancel/`,
+ data
+ );
diff --git a/packages/common/src/apis/session.ts b/packages/common/src/apis/session.ts
index 0bfdd2f..c398708 100644
--- a/packages/common/src/apis/session.ts
+++ b/packages/common/src/apis/session.ts
@@ -1,14 +1,10 @@
import { BackendAPIClient } from "./client";
-import BackendSessionAPISchemas from "../schemas/backendSessionAPI";
+import * as BackendSessionAPISchemas from "../schemas/backendSessionAPI";
-namespace SessionAPIs {
- export const sessionList = (client: BackendAPIClient) => async () => {
- return await client.get("v1/event/presentation/");
- };
+export const sessionList = (client: BackendAPIClient) => async () => {
+ return await client.get("v1/event/presentation/");
+};
- export const sessionFilteredList = (client: BackendAPIClient, categoryName: string) => async () => {
- return await client.get(`v1/event/presentation/?category=${categoryName}`);
- };
-}
-
-export default SessionAPIs;
+export const sessionFilteredList = (client: BackendAPIClient, categoryName: string) => async () => {
+ return await client.get(`v1/event/presentation/?category=${categoryName}`);
+};
diff --git a/packages/common/src/components/common_context.tsx b/packages/common/src/components/common_context.tsx
index e798168..a3a2c59 100644
--- a/packages/common/src/components/common_context.tsx
+++ b/packages/common/src/components/common_context.tsx
@@ -1,12 +1,12 @@
import * as React from "react";
-import GlobalContext from "../contexts";
+import { context, ContextOptions } from "../contexts";
type CommonContextProps = {
- options: GlobalContext.ContextOptions;
+ options: ContextOptions;
children: React.ReactNode;
};
export const CommonContextProvider: React.FC = (props) => (
- {props.children}
+ {props.children}
);
diff --git a/packages/common/src/components/error_handler.tsx b/packages/common/src/components/error_handler.tsx
index 345590b..643e41f 100644
--- a/packages/common/src/components/error_handler.tsx
+++ b/packages/common/src/components/error_handler.tsx
@@ -2,7 +2,7 @@ import { Button, Typography } from "@mui/material";
import { Suspense } from "@suspensive/react";
import * as React from "react";
-import CommonContext from "../hooks/";
+import * as CommonContext from "../hooks";
const DetailedErrorFallback: React.FC<{ error: Error; reset: () => void }> = ({ error, reset }) => {
console.error(error);
diff --git a/packages/common/src/components/mdx.tsx b/packages/common/src/components/mdx.tsx
index 146d953..0afd1d1 100644
--- a/packages/common/src/components/mdx.tsx
+++ b/packages/common/src/components/mdx.tsx
@@ -9,7 +9,7 @@ import * as runtime from "react/jsx-runtime";
import remarkGfm from "remark-gfm";
import * as R from "remeda";
-import Hooks from "../hooks";
+import * as Hooks from "../hooks";
import { ErrorFallback } from "./error_handler";
import { LinkHandler } from "./link_handler";
import { rtrim } from "../utils/string";
diff --git a/packages/common/src/components/mdx_components/session_list.tsx b/packages/common/src/components/mdx_components/session_list.tsx
index e905e3f..97e77c7 100644
--- a/packages/common/src/components/mdx_components/session_list.tsx
+++ b/packages/common/src/components/mdx_components/session_list.tsx
@@ -5,8 +5,8 @@ import { Link } from "react-router-dom";
import * as R from "remeda";
import PyCon2025Logo from "../../assets/pyconkr2025_logo.png";
-import Hooks from "../../hooks";
-import BackendAPISchemas from "../../schemas/backendAPI";
+import * as Hooks from "../../hooks";
+import * as BackendAPISchemas from "../../schemas/backendAPI";
import { ErrorFallback } from "../error_handler";
import { FallbackImage } from "../fallback_image";
import { StyledDivider } from "./styled_divider";
diff --git a/packages/common/src/components/mdx_components/session_timetable.tsx b/packages/common/src/components/mdx_components/session_timetable.tsx
index 9f02cf5..a646c0a 100644
--- a/packages/common/src/components/mdx_components/session_timetable.tsx
+++ b/packages/common/src/components/mdx_components/session_timetable.tsx
@@ -5,8 +5,8 @@ import * as React from "react";
import { Link } from "react-router-dom";
import * as R from "remeda";
-import Hooks from "../../hooks";
-import BackendAPISchemas from "../../schemas/backendAPI";
+import * as Hooks from "../../hooks";
+import * as BackendAPISchemas from "../../schemas/backendAPI";
import { CenteredPage } from "../centered_page";
import { ErrorFallback } from "../error_handler";
import { StyledDivider } from "./styled_divider";
diff --git a/packages/common/src/components/mdx_editor.tsx b/packages/common/src/components/mdx_editor.tsx
index f83a003..2fa500c 100644
--- a/packages/common/src/components/mdx_editor.tsx
+++ b/packages/common/src/components/mdx_editor.tsx
@@ -8,7 +8,7 @@ import * as React from "react";
import * as R from "remeda";
// import * as CryptoJS from "crypto-js";
-import Hooks from "../hooks";
+import * as Hooks from "../hooks";
type CustomComponentInfoType = {
k: string; // key
diff --git a/packages/common/src/contexts/index.ts b/packages/common/src/contexts/index.ts
index 69ffc1d..421d589 100644
--- a/packages/common/src/contexts/index.ts
+++ b/packages/common/src/contexts/index.ts
@@ -1,27 +1,23 @@
import { MDXComponents } from "mdx/types";
import * as React from "react";
-namespace GlobalContext {
- export type ContextOptions = {
- language: "ko" | "en";
- frontendDomain?: string;
- baseUrl: string;
- debug?: boolean;
- backendApiDomain: string;
- backendApiTimeout: number;
- backendApiCSRFCookieName?: string;
- mdxComponents?: MDXComponents;
- };
+export type ContextOptions = {
+ language: "ko" | "en";
+ frontendDomain?: string;
+ baseUrl: string;
+ debug?: boolean;
+ backendApiDomain: string;
+ backendApiTimeout: number;
+ backendApiCSRFCookieName?: string;
+ mdxComponents?: MDXComponents;
+};
- export const context = React.createContext({
- language: "ko",
- frontendDomain: "",
- baseUrl: "",
- debug: false,
- backendApiDomain: "",
- backendApiTimeout: 10000,
- backendApiCSRFCookieName: "",
- });
-}
-
-export default GlobalContext;
+export const context = React.createContext({
+ language: "ko",
+ frontendDomain: "",
+ baseUrl: "",
+ debug: false,
+ backendApiDomain: "",
+ backendApiTimeout: 10000,
+ backendApiCSRFCookieName: "",
+});
diff --git a/packages/common/src/hooks/index.ts b/packages/common/src/hooks/index.ts
index 7dee57f..cc174e5 100644
--- a/packages/common/src/hooks/index.ts
+++ b/packages/common/src/hooks/index.ts
@@ -1,19 +1,7 @@
-import BackendAPIHooks from "./useAPI";
-import BackendAdminAPIHooks from "./useAdminAPI";
-import { useCommonContext as useCommonContextHook } from "./useCommonContext";
-import { useEmail as useEmailHook } from "./useEmail";
-import BackendParticipantPortalAPIHooks from "./useParticipantPortalAPI";
+import { useCommonContext } from "./useCommonContext";
+import { useEmail } from "./useEmail";
-export namespace CommonHooks {
- export const useCommonContext = useCommonContextHook;
- export const useEmail = useEmailHook;
-}
-
-namespace Hooks {
- export const Common = CommonHooks;
- export const BackendAPI = BackendAPIHooks;
- export const BackendAdminAPI = BackendAdminAPIHooks;
- export const BackendParticipantPortalAPI = BackendParticipantPortalAPIHooks;
-}
-
-export default Hooks;
+export * as BackendAPI from "./useAPI";
+export * as BackendAdminAPI from "./useAdminAPI";
+export * as BackendParticipantPortalAPI from "./useParticipantPortalAPI";
+export const Common = { useCommonContext, useEmail };
diff --git a/packages/common/src/hooks/useAPI.ts b/packages/common/src/hooks/useAPI.ts
index 10922c6..3cc90d9 100644
--- a/packages/common/src/hooks/useAPI.ts
+++ b/packages/common/src/hooks/useAPI.ts
@@ -1,10 +1,10 @@
import { useSuspenseQuery } from "@tanstack/react-query";
import * as React from "react";
-import BackendAPIs from "../apis";
+import * as BackendAPIs from "../apis";
import { BackendAPIClient } from "../apis/client";
-import BackendContext from "../contexts";
-import BackendAPISchemas from "../schemas/backendAPI";
+import { context as backendContext } from "../contexts";
+import * as BackendAPISchemas from "../schemas/backendAPI";
const QUERY_KEYS = {
SITEMAP_LIST: ["query", "sitemap", "list"],
@@ -13,47 +13,43 @@ const QUERY_KEYS = {
SESSION_LIST: ["query", "session", "list"],
};
-namespace BackendAPIHooks {
- export const useBackendContext = () => {
- const context = React.useContext(BackendContext.context);
- if (!context) throw new Error("useBackendContext must be used within a CommonProvider");
- return context;
- };
-
- export const useBackendClient = () => {
- const { language, backendApiDomain, backendApiTimeout } = useBackendContext();
- return new BackendAPIClient(backendApiDomain, backendApiTimeout, "", false, language);
- };
-
- export const useFlattenSiteMapQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.SITEMAP_LIST, client.language],
- queryFn: BackendAPIs.listSiteMaps(client),
- });
-
- export const usePageQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PAGE, id, client.language],
- queryFn: () => BackendAPIs.retrievePage(client)(id),
- });
-
- export const useSponsorQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.SPONSOR_LIST, client.language],
- queryFn: BackendAPIs.listSponsors(client),
- });
-
- export const useSessionsQuery = (client: BackendAPIClient, params?: BackendAPISchemas.SessionQueryParameterSchema) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.SESSION_LIST, client.language, ...(params ? [JSON.stringify(params)] : [])],
- queryFn: BackendAPIs.listSessions(client, params),
- });
-
- export const useSessionQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.SESSION_LIST, id, client.language],
- queryFn: () => BackendAPIs.retrieveSession(client)(id),
- });
-}
-
-export default BackendAPIHooks;
+export const useBackendContext = () => {
+ const ctx = React.useContext(backendContext);
+ if (!ctx) throw new Error("useBackendContext must be used within a CommonProvider");
+ return ctx;
+};
+
+export const useBackendClient = () => {
+ const { language, backendApiDomain, backendApiTimeout } = useBackendContext();
+ return new BackendAPIClient(backendApiDomain, backendApiTimeout, "", false, language);
+};
+
+export const useFlattenSiteMapQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.SITEMAP_LIST, client.language],
+ queryFn: BackendAPIs.listSiteMaps(client),
+ });
+
+export const usePageQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PAGE, id, client.language],
+ queryFn: () => BackendAPIs.retrievePage(client)(id),
+ });
+
+export const useSponsorQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.SPONSOR_LIST, client.language],
+ queryFn: BackendAPIs.listSponsors(client),
+ });
+
+export const useSessionsQuery = (client: BackendAPIClient, params?: BackendAPISchemas.SessionQueryParameterSchema) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.SESSION_LIST, client.language, ...(params ? [JSON.stringify(params)] : [])],
+ queryFn: BackendAPIs.listSessions(client, params),
+ });
+
+export const useSessionQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.SESSION_LIST, id, client.language],
+ queryFn: () => BackendAPIs.retrieveSession(client)(id),
+ });
diff --git a/packages/common/src/hooks/useAdminAPI.ts b/packages/common/src/hooks/useAdminAPI.ts
index 41695e8..43eba86 100644
--- a/packages/common/src/hooks/useAdminAPI.ts
+++ b/packages/common/src/hooks/useAdminAPI.ts
@@ -1,9 +1,9 @@
import { useMutation, useSuspenseQuery } from "@tanstack/react-query";
-import BackendAPIHooks from "./useAPI";
-import BackendAdminAPIs from "../apis/admin_api";
+import { useBackendContext } from "./useAPI";
+import * as BackendAdminAPIs from "../apis/admin_api";
import { BackendAPIClient } from "../apis/client";
-import BackendAdminAPISchemas from "../schemas/backendAdminAPI";
+import * as BackendAdminAPISchemas from "../schemas/backendAdminAPI";
const QUERY_KEYS = {
ADMIN_ME: ["query", "admin", "me"],
@@ -27,144 +27,140 @@ const MUTATION_KEYS = {
ADMIN_REJECT_MODIFICATION_AUDIT: ["mutation", "admin", "reject", "modification-audit"],
};
-namespace BackendAdminAPIHooks {
- export const useBackendAdminClient = () => {
- const { backendApiDomain, backendApiTimeout, backendApiCSRFCookieName } = BackendAPIHooks.useBackendContext();
- return new BackendAPIClient(backendApiDomain, backendApiTimeout, backendApiCSRFCookieName, true);
- };
-
- export const useSignedInUserQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: QUERY_KEYS.ADMIN_ME,
- queryFn: BackendAdminAPIs.me(client),
- });
-
- export const useSignInMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_SIGN_IN],
- mutationFn: BackendAdminAPIs.signIn(client),
- });
-
- export const useSignOutMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_SIGN_OUT],
- mutationFn: BackendAdminAPIs.signOut(client),
- });
-
- export const useChangePasswordMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_CHANGE_PASSWORD],
- mutationFn: BackendAdminAPIs.changePassword(client),
- });
-
- export const useResetUserPasswordMutation = (client: BackendAPIClient, id: string) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_RESET_PASSWORD, id],
- mutationFn: BackendAdminAPIs.resetUserPassword(client, id),
- });
-
- export const useSchemaQuery = (client: BackendAPIClient, app: string, resource: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.ADMIN_SCHEMA, app, resource],
- queryFn: BackendAdminAPIs.schema(client, app, resource),
- });
-
- export const useChoicesQuery = (client: BackendAPIClient, app: string, resource: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.ADMIN_CHOICES, app, resource],
- queryFn: BackendAdminAPIs.choices(client, app, resource),
- });
-
- export const useOpenApiSchemaQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: QUERY_KEYS.ADMIN_OPENAPI_SCHEMA,
- queryFn: BackendAdminAPIs.openApiSchema(client),
- staleTime: Infinity,
- });
-
- export const useListQuery = (client: BackendAPIClient, app: string, resource: string, params?: Record) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.ADMIN_LIST, app, resource, JSON.stringify(params)],
- queryFn: BackendAdminAPIs.list(client, app, resource, params),
- });
-
- export const useRetrieveQuery = (client: BackendAPIClient, app: string, resource: string, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.ADMIN_RETRIEVE, app, resource, id],
- queryFn: BackendAdminAPIs.retrieve(client, app, resource, id),
- });
-
- export const useCreateMutation = (client: BackendAPIClient, app: string, resource: string) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_CREATE, app, resource],
- mutationFn: BackendAdminAPIs.create(client, app, resource),
- });
-
- export const useUpdateMutation = (client: BackendAPIClient, app: string, resource: string, id: string) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_UPDATE, app, resource, id],
- mutationFn: BackendAdminAPIs.update(client, app, resource, id),
- });
-
- export const useUpdatePreparedMutation = (client: BackendAPIClient, app: string, resource: string) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_UPDATE, app, resource, "prepared"],
- mutationFn: BackendAdminAPIs.updatePrepared(client, app, resource),
- });
-
- export const useRemoveMutation = (client: BackendAPIClient, app: string, resource: string, id: string) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_REMOVE, app, resource, id],
- mutationFn: BackendAdminAPIs.remove(client, app, resource, id),
- });
-
- export const useRemovePreparedMutation = (client: BackendAPIClient, app: string, resource: string) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_REMOVE, app, resource, "prepared"],
- mutationFn: BackendAdminAPIs.removePrepared(client, app, resource),
- });
-
- export const usePublicFileQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.ADMIN_RETRIEVE, "file", "publicfile", id],
- queryFn: BackendAdminAPIs.retrieve(client, "file", "publicfile", id),
- });
-
- export const useUploadPublicFileMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_CREATE, "public-file", "upload"],
- mutationFn: BackendAdminAPIs.uploadPublicFile(client),
- });
-
- export const useListPageSectionsQuery = (client: BackendAPIClient, pageId: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.ADMIN_LIST, "cms", "page", pageId, "section"],
- queryFn: BackendAdminAPIs.listSections(client, pageId),
- });
-
- export const useBulkUpdatePageSectionsMutation = (client: BackendAPIClient, pageId: string) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.ADMIN_UPDATE, "cms", "page", pageId, "section"],
- mutationFn: BackendAdminAPIs.bulkUpdateSections(client, pageId),
- });
-
- export const useModificationAuditPreviewQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.ADMIN_PREVIEW_MODIFICATION_AUDIT, id],
- queryFn: BackendAdminAPIs.previewModificationAudit(client, id),
- });
-
- export const useApproveModificationAuditMutation = (client: BackendAPIClient, id: string) =>
- useMutation({
- mutationKey: MUTATION_KEYS.ADMIN_APPROVE_MODIFICATION_AUDIT,
- mutationFn: BackendAdminAPIs.approveModificationAudit(client, id),
- });
-
- export const useRejectModificationAuditMutation = (client: BackendAPIClient, id: string) =>
- useMutation({
- mutationKey: MUTATION_KEYS.ADMIN_REJECT_MODIFICATION_AUDIT,
- mutationFn: BackendAdminAPIs.rejectModificationAudit(client, id),
- });
-}
-
-export default BackendAdminAPIHooks;
+export const useBackendAdminClient = () => {
+ const { backendApiDomain, backendApiTimeout, backendApiCSRFCookieName } = useBackendContext();
+ return new BackendAPIClient(backendApiDomain, backendApiTimeout, backendApiCSRFCookieName, true);
+};
+
+export const useSignedInUserQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: QUERY_KEYS.ADMIN_ME,
+ queryFn: BackendAdminAPIs.me(client),
+ });
+
+export const useSignInMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_SIGN_IN],
+ mutationFn: BackendAdminAPIs.signIn(client),
+ });
+
+export const useSignOutMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_SIGN_OUT],
+ mutationFn: BackendAdminAPIs.signOut(client),
+ });
+
+export const useChangePasswordMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_CHANGE_PASSWORD],
+ mutationFn: BackendAdminAPIs.changePassword(client),
+ });
+
+export const useResetUserPasswordMutation = (client: BackendAPIClient, id: string) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_RESET_PASSWORD, id],
+ mutationFn: BackendAdminAPIs.resetUserPassword(client, id),
+ });
+
+export const useSchemaQuery = (client: BackendAPIClient, app: string, resource: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.ADMIN_SCHEMA, app, resource],
+ queryFn: BackendAdminAPIs.schema(client, app, resource),
+ });
+
+export const useChoicesQuery = (client: BackendAPIClient, app: string, resource: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.ADMIN_CHOICES, app, resource],
+ queryFn: BackendAdminAPIs.choices(client, app, resource),
+ });
+
+export const useOpenApiSchemaQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: QUERY_KEYS.ADMIN_OPENAPI_SCHEMA,
+ queryFn: BackendAdminAPIs.openApiSchema(client),
+ staleTime: Infinity,
+ });
+
+export const useListQuery = (client: BackendAPIClient, app: string, resource: string, params?: Record) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.ADMIN_LIST, app, resource, JSON.stringify(params)],
+ queryFn: BackendAdminAPIs.list(client, app, resource, params),
+ });
+
+export const useRetrieveQuery = (client: BackendAPIClient, app: string, resource: string, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.ADMIN_RETRIEVE, app, resource, id],
+ queryFn: BackendAdminAPIs.retrieve(client, app, resource, id),
+ });
+
+export const useCreateMutation = (client: BackendAPIClient, app: string, resource: string) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_CREATE, app, resource],
+ mutationFn: BackendAdminAPIs.create(client, app, resource),
+ });
+
+export const useUpdateMutation = (client: BackendAPIClient, app: string, resource: string, id: string) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_UPDATE, app, resource, id],
+ mutationFn: BackendAdminAPIs.update(client, app, resource, id),
+ });
+
+export const useUpdatePreparedMutation = (client: BackendAPIClient, app: string, resource: string) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_UPDATE, app, resource, "prepared"],
+ mutationFn: BackendAdminAPIs.updatePrepared(client, app, resource),
+ });
+
+export const useRemoveMutation = (client: BackendAPIClient, app: string, resource: string, id: string) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_REMOVE, app, resource, id],
+ mutationFn: BackendAdminAPIs.remove(client, app, resource, id),
+ });
+
+export const useRemovePreparedMutation = (client: BackendAPIClient, app: string, resource: string) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_REMOVE, app, resource, "prepared"],
+ mutationFn: BackendAdminAPIs.removePrepared(client, app, resource),
+ });
+
+export const usePublicFileQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.ADMIN_RETRIEVE, "file", "publicfile", id],
+ queryFn: BackendAdminAPIs.retrieve(client, "file", "publicfile", id),
+ });
+
+export const useUploadPublicFileMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_CREATE, "public-file", "upload"],
+ mutationFn: BackendAdminAPIs.uploadPublicFile(client),
+ });
+
+export const useListPageSectionsQuery = (client: BackendAPIClient, pageId: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.ADMIN_LIST, "cms", "page", pageId, "section"],
+ queryFn: BackendAdminAPIs.listSections(client, pageId),
+ });
+
+export const useBulkUpdatePageSectionsMutation = (client: BackendAPIClient, pageId: string) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.ADMIN_UPDATE, "cms", "page", pageId, "section"],
+ mutationFn: BackendAdminAPIs.bulkUpdateSections(client, pageId),
+ });
+
+export const useModificationAuditPreviewQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.ADMIN_PREVIEW_MODIFICATION_AUDIT, id],
+ queryFn: BackendAdminAPIs.previewModificationAudit(client, id),
+ });
+
+export const useApproveModificationAuditMutation = (client: BackendAPIClient, id: string) =>
+ useMutation({
+ mutationKey: MUTATION_KEYS.ADMIN_APPROVE_MODIFICATION_AUDIT,
+ mutationFn: BackendAdminAPIs.approveModificationAudit(client, id),
+ });
+
+export const useRejectModificationAuditMutation = (client: BackendAPIClient, id: string) =>
+ useMutation({
+ mutationKey: MUTATION_KEYS.ADMIN_REJECT_MODIFICATION_AUDIT,
+ mutationFn: BackendAdminAPIs.rejectModificationAudit(client, id),
+ });
diff --git a/packages/common/src/hooks/useCommonContext.ts b/packages/common/src/hooks/useCommonContext.ts
index 36ae9cc..3cb5e56 100644
--- a/packages/common/src/hooks/useCommonContext.ts
+++ b/packages/common/src/hooks/useCommonContext.ts
@@ -1,11 +1,11 @@
import * as React from "react";
-import GlobalContext from "../contexts";
+import { context } from "../contexts";
export const useCommonContext = () => {
- const context = React.useContext(GlobalContext.context);
- if (!context) {
+ const ctx = React.useContext(context);
+ if (!ctx) {
throw new Error("useCommonContext must be used within a CommonProvider");
}
- return context;
+ return ctx;
};
diff --git a/packages/common/src/hooks/useParticipantPortalAPI.ts b/packages/common/src/hooks/useParticipantPortalAPI.ts
index 266f759..f5d4d33 100644
--- a/packages/common/src/hooks/useParticipantPortalAPI.ts
+++ b/packages/common/src/hooks/useParticipantPortalAPI.ts
@@ -1,8 +1,8 @@
import { useMutation, useSuspenseQuery } from "@tanstack/react-query";
-import BackendAPIHooks from "./useAPI";
+import { useBackendContext } from "./useAPI";
import { BackendAPIClient } from "../apis/client";
-import ParticipantPortalAPI from "../apis/participant_portal_api";
+import * as ParticipantPortalAPI from "../apis/participant_portal_api";
const QUERY_KEYS = {
PARTICIPANT_ME: ["query", "participant", "me"],
@@ -23,107 +23,103 @@ const MUTATION_KEYS = {
PARTICIPANT_CANCEL_MODIFICATION_AUDIT: ["mutation", "participant", "cancel", "modification-audit"],
};
-namespace BackendParticipantPortalAPIHooks {
- export const useParticipantPortalClient = () => {
- const { backendApiDomain, backendApiTimeout, backendApiCSRFCookieName, language } = BackendAPIHooks.useBackendContext();
- return new BackendAPIClient(backendApiDomain, backendApiTimeout, backendApiCSRFCookieName, true, language);
- };
-
- export const useSignedInUserQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_ME, client.language],
- queryFn: ParticipantPortalAPI.me(client),
- });
-
- export const usePreviewMeModAuditQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_ME, "preview", client.language],
- queryFn: ParticipantPortalAPI.previewMeModAudit(client),
- });
-
- export const useUpdateMeMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.PARTICIPANT_UPDATE_ME],
- mutationFn: ParticipantPortalAPI.updateMe(client),
- });
-
- export const useSignInMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.PARTICIPANT_SIGN_IN],
- mutationFn: ParticipantPortalAPI.signIn(client),
- });
-
- export const useSignOutMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.PARTICIPANT_SIGN_OUT],
- mutationFn: ParticipantPortalAPI.signOut(client),
- });
-
- export const useChangePasswordMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.PARTICIPANT_CHANGE_PASSWORD],
- mutationFn: ParticipantPortalAPI.changePassword(client),
- });
-
- export const usePublicFilesQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_PUBLIC_FILES, client.language],
- queryFn: ParticipantPortalAPI.listPublicFiles(client),
- });
-
- export const useUploadPublicFileMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.PARTICIPANT_UPLOAD_PUBLIC_FILE, "upload"],
- mutationFn: ParticipantPortalAPI.uploadPublicFile(client),
- });
-
- export const useListPresentationsQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_LIST_PRESENTATION, client.language],
- queryFn: ParticipantPortalAPI.listPresentations(client),
- });
-
- export const useRetrievePresentationQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_RETRIEVE_PRESENTATION, id, client.language],
- queryFn: ParticipantPortalAPI.retrievePresentation(client, id),
- });
-
- export const useUpdatePresentationMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.PARTICIPANT_UPDATE_PRESENTATION],
- mutationFn: ParticipantPortalAPI.patchPresentation(client),
- });
-
- export const usePreviewPresentationModAuditQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_RETRIEVE_PRESENTATION, id, "preview", client.language],
- queryFn: ParticipantPortalAPI.previewPresentationModAudit(client, id),
- });
-
- export const useModificationAuditsQuery = (client: BackendAPIClient) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_LIST_MODIFICATION_AUDIT, client.language],
- queryFn: ParticipantPortalAPI.listModificationAudits(client),
- });
-
- export const useModificationAuditPreviewQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_LIST_MODIFICATION_AUDIT, "preview", id, client.language],
- queryFn: ParticipantPortalAPI.previewModificationAudit(client, id),
- });
-
- export const useRetrieveModificationAuditQuery = (client: BackendAPIClient, id: string) =>
- useSuspenseQuery({
- queryKey: [...QUERY_KEYS.PARTICIPANT_RETRIEVE_MODIFICATION_AUDIT, id, client.language],
- queryFn: ParticipantPortalAPI.retrieveModificationAudit(client, id),
- });
-
- export const useCancelModificationAuditMutation = (client: BackendAPIClient) =>
- useMutation({
- mutationKey: [...MUTATION_KEYS.PARTICIPANT_CANCEL_MODIFICATION_AUDIT],
- mutationFn: ParticipantPortalAPI.cancelModificationAudit(client),
- });
-}
-
-export default BackendParticipantPortalAPIHooks;
+export const useParticipantPortalClient = () => {
+ const { backendApiDomain, backendApiTimeout, backendApiCSRFCookieName, language } = useBackendContext();
+ return new BackendAPIClient(backendApiDomain, backendApiTimeout, backendApiCSRFCookieName, true, language);
+};
+
+export const useSignedInUserQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_ME, client.language],
+ queryFn: ParticipantPortalAPI.me(client),
+ });
+
+export const usePreviewMeModAuditQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_ME, "preview", client.language],
+ queryFn: ParticipantPortalAPI.previewMeModAudit(client),
+ });
+
+export const useUpdateMeMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.PARTICIPANT_UPDATE_ME],
+ mutationFn: ParticipantPortalAPI.updateMe(client),
+ });
+
+export const useSignInMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.PARTICIPANT_SIGN_IN],
+ mutationFn: ParticipantPortalAPI.signIn(client),
+ });
+
+export const useSignOutMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.PARTICIPANT_SIGN_OUT],
+ mutationFn: ParticipantPortalAPI.signOut(client),
+ });
+
+export const useChangePasswordMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.PARTICIPANT_CHANGE_PASSWORD],
+ mutationFn: ParticipantPortalAPI.changePassword(client),
+ });
+
+export const usePublicFilesQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_PUBLIC_FILES, client.language],
+ queryFn: ParticipantPortalAPI.listPublicFiles(client),
+ });
+
+export const useUploadPublicFileMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.PARTICIPANT_UPLOAD_PUBLIC_FILE, "upload"],
+ mutationFn: ParticipantPortalAPI.uploadPublicFile(client),
+ });
+
+export const useListPresentationsQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_LIST_PRESENTATION, client.language],
+ queryFn: ParticipantPortalAPI.listPresentations(client),
+ });
+
+export const useRetrievePresentationQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_RETRIEVE_PRESENTATION, id, client.language],
+ queryFn: ParticipantPortalAPI.retrievePresentation(client, id),
+ });
+
+export const useUpdatePresentationMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.PARTICIPANT_UPDATE_PRESENTATION],
+ mutationFn: ParticipantPortalAPI.patchPresentation(client),
+ });
+
+export const usePreviewPresentationModAuditQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_RETRIEVE_PRESENTATION, id, "preview", client.language],
+ queryFn: ParticipantPortalAPI.previewPresentationModAudit(client, id),
+ });
+
+export const useModificationAuditsQuery = (client: BackendAPIClient) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_LIST_MODIFICATION_AUDIT, client.language],
+ queryFn: ParticipantPortalAPI.listModificationAudits(client),
+ });
+
+export const useModificationAuditPreviewQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_LIST_MODIFICATION_AUDIT, "preview", id, client.language],
+ queryFn: ParticipantPortalAPI.previewModificationAudit(client, id),
+ });
+
+export const useRetrieveModificationAuditQuery = (client: BackendAPIClient, id: string) =>
+ useSuspenseQuery({
+ queryKey: [...QUERY_KEYS.PARTICIPANT_RETRIEVE_MODIFICATION_AUDIT, id, client.language],
+ queryFn: ParticipantPortalAPI.retrieveModificationAudit(client, id),
+ });
+
+export const useCancelModificationAuditMutation = (client: BackendAPIClient) =>
+ useMutation({
+ mutationKey: [...MUTATION_KEYS.PARTICIPANT_CANCEL_MODIFICATION_AUDIT],
+ mutationFn: ParticipantPortalAPI.cancelModificationAudit(client),
+ });
diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts
index 3517381..15451f6 100644
--- a/packages/common/src/index.ts
+++ b/packages/common/src/index.ts
@@ -1,8 +1,8 @@
-export { default as BackendAdminAPIs } from "./apis/admin_api";
-export { default as BackendAPIs } from "./apis/index";
-export { default as BackendParticipantPortalAPIs } from "./apis/participant_portal_api";
+export * as BackendAdminAPIs from "./apis/admin_api";
+export * as BackendAPIs from "./apis/index";
+export * as BackendParticipantPortalAPIs from "./apis/participant_portal_api";
export { default as Components } from "./components/index";
-export { default as Contexts } from "./contexts/index";
-export { default as Hooks } from "./hooks/index";
-export { default as Schemas } from "./schemas/index";
-export { default as Utils } from "./utils/index";
+export * as Contexts from "./contexts/index";
+export * as Hooks from "./hooks/index";
+export * as Schemas from "./schemas/index";
+export * as Utils from "./utils/index";
diff --git a/packages/common/src/schemas/backendAPI.ts b/packages/common/src/schemas/backendAPI.ts
index be05f0b..5b7ba58 100644
--- a/packages/common/src/schemas/backendAPI.ts
+++ b/packages/common/src/schemas/backendAPI.ts
@@ -1,116 +1,112 @@
import * as R from "remeda";
-namespace BackendAPISchemas {
- export type EmptyObject = Record;
+export type EmptyObject = Record;
- export type DetailedErrorSchema = {
- code: string;
- detail: string;
- attr: string | null;
- };
+export type DetailedErrorSchema = {
+ code: string;
+ detail: string;
+ attr: string | null;
+};
- export type ErrorResponseSchema = {
- type: string;
- errors: DetailedErrorSchema[];
- };
+export type ErrorResponseSchema = {
+ type: string;
+ errors: DetailedErrorSchema[];
+};
- export type FlattenedSiteMapSchema = {
- id: string;
- route_code: string;
- name: string;
- order: number;
- parent_sitemap: string | null;
- hide: boolean;
- page: string | null;
- external_link: string | null;
- };
+export type FlattenedSiteMapSchema = {
+ id: string;
+ route_code: string;
+ name: string;
+ order: number;
+ parent_sitemap: string | null;
+ hide: boolean;
+ page: string | null;
+ external_link: string | null;
+};
- export type NestedSiteMapSchema = {
- id: string;
- route_code: string;
- name: string;
- order: number;
- hide: boolean;
- parent_sitemap: string | null;
- children: NestedSiteMapSchema[];
- page: string | null;
- external_link: string | null;
- };
+export type NestedSiteMapSchema = {
+ id: string;
+ route_code: string;
+ name: string;
+ order: number;
+ hide: boolean;
+ parent_sitemap: string | null;
+ children: NestedSiteMapSchema[];
+ page: string | null;
+ external_link: string | null;
+};
- export type SectionSchema = {
- id: string;
- css: string;
+export type SectionSchema = {
+ id: string;
+ css: string;
- order: number;
- body: string;
- };
+ order: number;
+ body: string;
+};
- export type PageSchema = {
- id: string;
- css: string;
- title: string;
- subtitle: string;
+export type PageSchema = {
+ id: string;
+ css: string;
+ title: string;
+ subtitle: string;
- show_top_title_banner: boolean;
- show_bottom_sponsor_banner: boolean;
+ show_top_title_banner: boolean;
+ show_bottom_sponsor_banner: boolean;
- sections: SectionSchema[];
- };
+ sections: SectionSchema[];
+};
- export type SponsorTierSchema = {
+export type SponsorTierSchema = {
+ id: string;
+ name: string;
+ order: number;
+ sponsors: {
id: string;
name: string;
- order: number;
- sponsors: {
- id: string;
- name: string;
- logo: string;
- description: string;
- tags: string[];
- }[];
- };
+ logo: string;
+ description: string;
+ tags: string[];
+ }[];
+};
- export type SessionQueryParameterSchema = {
- event?: string;
- types?: string;
- };
+export type SessionQueryParameterSchema = {
+ event?: string;
+ types?: string;
+};
- export type SessionSchema = {
+export type SessionSchema = {
+ id: string;
+ title: string;
+ summary: string | null;
+ description: string;
+ slideshow_url: string | null;
+ public_slideshow_file: string | null;
+ image: string | null;
+ categories: {
id: string;
- title: string;
- summary: string | null;
- description: string;
- slideshow_url: string | null;
- public_slideshow_file: string | null;
+ name: string;
+ }[];
+ speakers: {
+ id: string;
+ nickname: string;
+ biography: string;
image: string | null;
- categories: {
- id: string;
- name: string;
- }[];
- speakers: {
- id: string;
- nickname: string;
- biography: string;
- image: string | null;
- }[];
- room_schedules: {
- id: string;
- room_name: string;
- start_at: string;
- end_at: string;
- }[];
- };
-
- export const isObjectErrorResponseSchema = (obj?: unknown): obj is BackendAPISchemas.ErrorResponseSchema => {
- return (
- R.isPlainObject(obj) &&
- R.isString(obj.type) &&
- R.isArray(obj.errors) &&
- obj.errors.every((error) => {
- return R.isPlainObject(error) && R.isString(error.code) && R.isString(error.detail) && (error.attr === null || R.isString(error.attr));
- })
- );
- };
-}
+ }[];
+ room_schedules: {
+ id: string;
+ room_name: string;
+ start_at: string;
+ end_at: string;
+ }[];
+};
-export default BackendAPISchemas;
+export const isObjectErrorResponseSchema = (obj?: unknown): obj is ErrorResponseSchema => {
+ return (
+ R.isPlainObject(obj) &&
+ R.isString(obj.type) &&
+ R.isArray(obj.errors) &&
+ obj.errors.every((error) => {
+ return R.isPlainObject(error) && R.isString(error.code) && R.isString(error.detail) && (error.attr === null || R.isString(error.attr));
+ })
+ );
+};
diff --git a/packages/common/src/schemas/backendAdminAPI.ts b/packages/common/src/schemas/backendAdminAPI.ts
index bfc064a..fb94077 100644
--- a/packages/common/src/schemas/backendAdminAPI.ts
+++ b/packages/common/src/schemas/backendAdminAPI.ts
@@ -1,155 +1,151 @@
import { RJSFSchema, UiSchema } from "@rjsf/utils";
-namespace BackendAdminAPISchemas {
- export type DetailedErrorSchema = {
- code: string;
- detail: string;
- attr: string | null;
- };
-
- export type ErrorResponseSchema = {
- type: string;
- errors: DetailedErrorSchema[];
- };
-
- export type AdminSchemaDefinition = {
- schema: RJSFSchema;
- ui_schema: UiSchema;
- translation_fields: string[];
- };
-
- export type ChoicesResponse = Record;
-
- export type UserSchema = {
- id: number;
- username: string;
- email: string;
- first_name: string;
- last_name: string;
- is_staff: boolean;
- is_active: boolean;
- date_joined: string; // ISO 8601 format
- };
-
- export type UserSignInSchema = {
- identity: string; // username or email
- password: string;
- };
-
- export type UserChangePasswordSchema = {
- old_password: string;
- new_password: string;
- new_password_confirm: string;
- };
-
- export type UserResetPasswordResponseSchema = {
- password: string;
- };
-
- export type PublicFileSchema = {
- id: string; // UUID
- file: string; // URL to the public file
- mimetype: string | null; // MIME type of the file
- hash: string; // Hash of the file for integrity check
- size: number; // Size of the file in bytes
- };
-
- export type PageSectionSchema = {
- id?: string;
- order: number;
- css: string;
- body_ko: string | null;
- body_en: string | null;
- };
-
- export type FlattenedSiteMapSchema = {
- id: string;
- route_code: string;
- name_ko: string;
- name_en: string;
- order: number;
- parent_sitemap: string | null;
- hide: boolean;
- page: string | null;
- external_link: string | null;
- };
-
- export type NestedSiteMapSchema = {
- id: string;
- route_code: string;
- name_ko: string;
- name_en: string;
- order: number;
- parent_sitemap: string | null;
- hide: boolean;
- children: NestedSiteMapSchema[];
- page: string | null;
- external_link: string | null;
- };
-
- export type PageSectionBulkUpdateSchema = PageSectionSchema | Omit;
-
- export type PresentationSchema = {
- id: string; // UUID
- type: string; // UUID of the presentation type
- categories: string[]; // Array of category UUIDs
- title_ko: string;
- title_en: string;
- summary_ko: string;
- summary_en: string;
- description_ko: string;
- description_en: string;
- slideshow_url: string | null;
- image: string | null;
- };
-
- export type ModificationAuditSchema = {
- id: string; // UUID
- status: "requested" | "approved" | "rejected" | "cancelled"; // Status of the modification request
+export type DetailedErrorSchema = {
+ code: string;
+ detail: string;
+ attr: string | null;
+};
+
+export type ErrorResponseSchema = {
+ type: string;
+ errors: DetailedErrorSchema[];
+};
+
+export type AdminSchemaDefinition = {
+ schema: RJSFSchema;
+ ui_schema: UiSchema;
+ translation_fields: string[];
+};
+
+export type ChoicesResponse = Record;
+
+export type UserSchema = {
+ id: number;
+ username: string;
+ email: string;
+ first_name: string;
+ last_name: string;
+ is_staff: boolean;
+ is_active: boolean;
+ date_joined: string; // ISO 8601 format
+};
+
+export type UserSignInSchema = {
+ identity: string; // username or email
+ password: string;
+};
+
+export type UserChangePasswordSchema = {
+ old_password: string;
+ new_password: string;
+ new_password_confirm: string;
+};
+
+export type UserResetPasswordResponseSchema = {
+ password: string;
+};
+
+export type PublicFileSchema = {
+ id: string; // UUID
+ file: string; // URL to the public file
+ mimetype: string | null; // MIME type of the file
+ hash: string; // Hash of the file for integrity check
+ size: number; // Size of the file in bytes
+};
+
+export type PageSectionSchema = {
+ id?: string;
+ order: number;
+ css: string;
+ body_ko: string | null;
+ body_en: string | null;
+};
+
+export type FlattenedSiteMapSchema = {
+ id: string;
+ route_code: string;
+ name_ko: string;
+ name_en: string;
+ order: number;
+ parent_sitemap: string | null;
+ hide: boolean;
+ page: string | null;
+ external_link: string | null;
+};
+
+export type NestedSiteMapSchema = {
+ id: string;
+ route_code: string;
+ name_ko: string;
+ name_en: string;
+ order: number;
+ parent_sitemap: string | null;
+ hide: boolean;
+ children: NestedSiteMapSchema[];
+ page: string | null;
+ external_link: string | null;
+};
+
+export type PageSectionBulkUpdateSchema = PageSectionSchema | Omit;
+
+export type PresentationSchema = {
+ id: string; // UUID
+ type: string; // UUID of the presentation type
+ categories: string[]; // Array of category UUIDs
+ title_ko: string;
+ title_en: string;
+ summary_ko: string;
+ summary_en: string;
+ description_ko: string;
+ description_en: string;
+ slideshow_url: string | null;
+ image: string | null;
+};
+
+export type ModificationAuditSchema = {
+ id: string; // UUID
+ status: "requested" | "approved" | "rejected" | "cancelled"; // Status of the modification request
+ created_at: string; // ISO 8601 timestamp
+ updated_at: string; // ISO 8601 timestamp
+ created_by: string;
+ updated_by: string | null; // User ID of the person who last updated the audit
+ modification_data: string; // JSON string containing the modification data
+ str_repr: string; // String representation of the modification audit, e.g., "Presentation Title - Status"
+ comments: {
+ id: string; // UUID of the comment
+ content: string; // Content of the comment
created_at: string; // ISO 8601 timestamp
- updated_at: string; // ISO 8601 timestamp
- created_by: string;
- updated_by: string | null; // User ID of the person who last updated the audit
- modification_data: string; // JSON string containing the modification data
- str_repr: string; // String representation of the modification audit, e.g., "Presentation Title - Status"
- comments: {
- id: string; // UUID of the comment
- content: string; // Content of the comment
- created_at: string; // ISO 8601 timestamp
- created_by: {
- id: number; // User ID of the commenter
- nickname: string; // Nickname of the commenter
- is_superuser: boolean; // Whether the commenter is a staff member
- };
- updated_at: string; // ISO 8601 timestamp
- }[];
- instance: {
- app: string;
- model: string;
- id: string; // UUID of the instance being modified, e.g., presentation ID
+ created_by: {
+ id: number; // User ID of the commenter
+ nickname: string; // Nickname of the commenter
+ is_superuser: boolean; // Whether the commenter is a staff member
};
+ updated_at: string; // ISO 8601 timestamp
+ }[];
+ instance: {
+ app: string;
+ model: string;
+ id: string; // UUID of the instance being modified, e.g., presentation ID
};
-
- export type ModificationAuditPreviewSchema = {
- modification_audit: ModificationAuditSchema;
- original: T;
- modified: T;
+};
+
+export type ModificationAuditPreviewSchema = {
+ modification_audit: ModificationAuditSchema;
+ original: T;
+ modified: T;
+};
+
+export type OpenAPIParameterSchema = {
+ name: string;
+ in: "query" | "path" | "header" | "cookie";
+ required?: boolean;
+ description?: string;
+ schema?: {
+ type?: string;
+ format?: string;
+ items?: { type?: string; enum?: string[] };
+ enum?: string[];
};
+};
- export type OpenAPIParameterSchema = {
- name: string;
- in: "query" | "path" | "header" | "cookie";
- required?: boolean;
- description?: string;
- schema?: {
- type?: string;
- format?: string;
- items?: { type?: string; enum?: string[] };
- enum?: string[];
- };
- };
-
- export type OpenAPISchema = { paths: Record };
-}
-
-export default BackendAdminAPISchemas;
+export type OpenAPISchema = { paths: Record };
diff --git a/packages/common/src/schemas/backendParticipantPortalAPI.ts b/packages/common/src/schemas/backendParticipantPortalAPI.ts
index f10a1e0..b35339f 100644
--- a/packages/common/src/schemas/backendParticipantPortalAPI.ts
+++ b/packages/common/src/schemas/backendParticipantPortalAPI.ts
@@ -1,143 +1,139 @@
-namespace BackendParticipantPortalAPISchemas {
- export type EmptyObject = Record;
-
- export type DetailedErrorSchema = {
- code: string;
- detail: string;
- attr: string | null;
- };
-
- export type ErrorResponseSchema = {
- type: string;
- errors: DetailedErrorSchema[];
- };
-
- export type UserSchema = {
- id: number;
- email: string;
- username: string;
- nickname: string | null;
- nickname_ko: string | null;
- nickname_en: string | null;
- image: string | null; // PK of the user's profile image
- profile_image: string | null; // URL to the user's profile image
-
- has_requested_modification_audit: boolean;
- requested_modification_audit_id: string | null;
- };
-
- export type UserUpdateSchema = {
- nickname_ko: string | null;
- nickname_en: string | null;
- image?: string | null; // PK of the user's profile image
- };
-
- export type UserSignInSchema = {
- identity: string; // email
- password: string;
- };
-
- export type UserChangePasswordSchema = {
- old_password: string;
- new_password: string;
- new_password_confirm: string;
- };
-
- export type PublicFileSchema = {
- id: string; // UUID
- file: string; // URL to the public file
- name: string; // Name of the public file
- };
-
- export type PresentationRetrieveSchema = {
- id: string; // UUID
- title: string; // Title of the presentation, translated to the current language
- title_ko: string; // Title in Korean
- title_en: string; // Title in English
- summary: string; // Summary of the presentation, translated to the current language
- summary_ko: string; // Summary in Korean
- summary_en: string; // Summary in English
- description: string; // Description of the presentation, translated to the current language
- description_ko: string; // Description in Korean
- description_en: string; // Description in English
- slideshow_url: string | null; // URL to the presentation's slideshow, if available
- image: string | null; // PK of the presentation's image
- speakers: {
- id: string; // UUID of the speaker
- biography_ko: string; // Biography in Korean
- biography_en: string; // Biography in English
- image: string | null; // PK of the speaker's image
- user: {
- id: number; // User ID of the speaker
- email: string; // Email of the speaker
- nickname_ko: string | null; // Nickname in Korean
- nickname_en: string | null; // Nickname in English
- };
- }[];
-
- has_requested_modification_audit: boolean;
- requested_modification_audit_id: string | null;
- };
-
- export type PresentationUpdateSchema = {
- id: string;
- title_ko: string;
- title_en: string;
- summary_ko: string;
- summary_en: string;
- description_ko: string;
- description_en: string;
- image: string | null;
- speakers: {
- id: string; // UUID of the speaker
- biography_ko: string; // Biography in Korean
- biography_en: string; // Biography in English
- image: string | null; // PK of the speaker's image
- }[];
- };
-
- export type ModificationAuditSchema = {
- id: string; // UUID
- str_repr: string; // String representation of the modification audit, e.g., "Presentation Title - Status"
- status: "requested" | "approved" | "rejected" | "cancelled"; // Status of the modification request
+export type EmptyObject = Record;
+
+export type DetailedErrorSchema = {
+ code: string;
+ detail: string;
+ attr: string | null;
+};
+
+export type ErrorResponseSchema = {
+ type: string;
+ errors: DetailedErrorSchema[];
+};
+
+export type UserSchema = {
+ id: number;
+ email: string;
+ username: string;
+ nickname: string | null;
+ nickname_ko: string | null;
+ nickname_en: string | null;
+ image: string | null; // PK of the user's profile image
+ profile_image: string | null; // URL to the user's profile image
+
+ has_requested_modification_audit: boolean;
+ requested_modification_audit_id: string | null;
+};
+
+export type UserUpdateSchema = {
+ nickname_ko: string | null;
+ nickname_en: string | null;
+ image?: string | null; // PK of the user's profile image
+};
+
+export type UserSignInSchema = {
+ identity: string; // email
+ password: string;
+};
+
+export type UserChangePasswordSchema = {
+ old_password: string;
+ new_password: string;
+ new_password_confirm: string;
+};
+
+export type PublicFileSchema = {
+ id: string; // UUID
+ file: string; // URL to the public file
+ name: string; // Name of the public file
+};
+
+export type PresentationRetrieveSchema = {
+ id: string; // UUID
+ title: string; // Title of the presentation, translated to the current language
+ title_ko: string; // Title in Korean
+ title_en: string; // Title in English
+ summary: string; // Summary of the presentation, translated to the current language
+ summary_ko: string; // Summary in Korean
+ summary_en: string; // Summary in English
+ description: string; // Description of the presentation, translated to the current language
+ description_ko: string; // Description in Korean
+ description_en: string; // Description in English
+ slideshow_url: string | null; // URL to the presentation's slideshow, if available
+ image: string | null; // PK of the presentation's image
+ speakers: {
+ id: string; // UUID of the speaker
+ biography_ko: string; // Biography in Korean
+ biography_en: string; // Biography in English
+ image: string | null; // PK of the speaker's image
+ user: {
+ id: number; // User ID of the speaker
+ email: string; // Email of the speaker
+ nickname_ko: string | null; // Nickname in Korean
+ nickname_en: string | null; // Nickname in English
+ };
+ }[];
+
+ has_requested_modification_audit: boolean;
+ requested_modification_audit_id: string | null;
+};
+
+export type PresentationUpdateSchema = {
+ id: string;
+ title_ko: string;
+ title_en: string;
+ summary_ko: string;
+ summary_en: string;
+ description_ko: string;
+ description_en: string;
+ image: string | null;
+ speakers: {
+ id: string; // UUID of the speaker
+ biography_ko: string; // Biography in Korean
+ biography_en: string; // Biography in English
+ image: string | null; // PK of the speaker's image
+ }[];
+};
+
+export type ModificationAuditSchema = {
+ id: string; // UUID
+ str_repr: string; // String representation of the modification audit, e.g., "Presentation Title - Status"
+ status: "requested" | "approved" | "rejected" | "cancelled"; // Status of the modification request
+ created_at: string; // ISO 8601 timestamp
+ updated_at: string; // ISO 8601 timestamp
+
+ instance_type: T; // Type of the instance being modified (e.g., "presentation")
+ instance_id: string; // UUID of the instance being modified (e.g., presentation ID)
+ modification_data: string; // JSON string containing the modification data
+
+ comments: {
+ id: string; // UUID of the comment
+ content: string; // Content of the comment
created_at: string; // ISO 8601 timestamp
+ created_by: {
+ id: number; // User ID of the commenter
+ nickname: string; // Nickname of the commenter
+ is_superuser: boolean; // Whether the commenter is a staff member
+ };
updated_at: string; // ISO 8601 timestamp
-
- instance_type: T; // Type of the instance being modified (e.g., "presentation")
- instance_id: string; // UUID of the instance being modified (e.g., presentation ID)
- modification_data: string; // JSON string containing the modification data
-
- comments: {
- id: string; // UUID of the comment
- content: string; // Content of the comment
- created_at: string; // ISO 8601 timestamp
- created_by: {
- id: number; // User ID of the commenter
- nickname: string; // Nickname of the commenter
- is_superuser: boolean; // Whether the commenter is a staff member
- };
- updated_at: string; // ISO 8601 timestamp
- }[];
- };
-
- type ModificationAuditPresentationPreviewSchema = {
- modification_audit: ModificationAuditSchema<"presentation">;
- original: PresentationRetrieveSchema;
- modified: PresentationRetrieveSchema;
- };
-
- type ModificationAuditUserPreviewSchema = {
- modification_audit: ModificationAuditSchema<"userext">;
- original: UserSchema;
- modified: UserSchema;
- };
-
- export type ModificationAuditPreviewSchema = ModificationAuditPresentationPreviewSchema | ModificationAuditUserPreviewSchema;
-
- export type ModificationAuditCancelRequestSchema = {
- id: string; // UUID of the modification audit
- reason: string | null; // Reason for cancelling the modification request
- };
-}
-
-export default BackendParticipantPortalAPISchemas;
+ }[];
+};
+
+type ModificationAuditPresentationPreviewSchema = {
+ modification_audit: ModificationAuditSchema<"presentation">;
+ original: PresentationRetrieveSchema;
+ modified: PresentationRetrieveSchema;
+};
+
+type ModificationAuditUserPreviewSchema = {
+ modification_audit: ModificationAuditSchema<"userext">;
+ original: UserSchema;
+ modified: UserSchema;
+};
+
+export type ModificationAuditPreviewSchema = ModificationAuditPresentationPreviewSchema | ModificationAuditUserPreviewSchema;
+
+export type ModificationAuditCancelRequestSchema = {
+ id: string; // UUID of the modification audit
+ reason: string | null; // Reason for cancelling the modification request
+};
diff --git a/packages/common/src/schemas/backendSessionAPI.ts b/packages/common/src/schemas/backendSessionAPI.ts
index a9e2cc1..91aac87 100644
--- a/packages/common/src/schemas/backendSessionAPI.ts
+++ b/packages/common/src/schemas/backendSessionAPI.ts
@@ -1,33 +1,29 @@
-namespace BackendSessionAPISchemas {
- export type SessionTypeSchema = {
- id: string;
- event: string;
- name: string;
- };
+export type SessionTypeSchema = {
+ id: string;
+ event: string;
+ name: string;
+};
- export type SessionCategorySchema = {
- id: string;
- presentationType: string;
- name: string;
- };
+export type SessionCategorySchema = {
+ id: string;
+ presentationType: string;
+ name: string;
+};
- export type SessionSpeakerSchema = {
- id: string;
- presentation: string;
- user: string;
- name: string;
- biography: string;
- image: string; // DB 반영 필요
- };
+export type SessionSpeakerSchema = {
+ id: string;
+ presentation: string;
+ user: string;
+ name: string;
+ biography: string;
+ image: string; // DB 반영 필요
+};
- export type SessionSchema = {
- id: string;
- name: string; // DB 반영 필요
- doNotRecord: boolean; // DB 반영 필요
- presentationType: SessionTypeSchema;
- presentationCategories: SessionCategorySchema[];
- presentationSpeaker: SessionSpeakerSchema[];
- };
-}
-
-export default BackendSessionAPISchemas;
+export type SessionSchema = {
+ id: string;
+ name: string; // DB 반영 필요
+ doNotRecord: boolean; // DB 반영 필요
+ presentationType: SessionTypeSchema;
+ presentationCategories: SessionCategorySchema[];
+ presentationSpeaker: SessionSpeakerSchema[];
+};
diff --git a/packages/common/src/schemas/index.ts b/packages/common/src/schemas/index.ts
index 96569e3..66cfe36 100644
--- a/packages/common/src/schemas/index.ts
+++ b/packages/common/src/schemas/index.ts
@@ -1,9 +1,3 @@
-import * as _BackendAPISchemas from "./backendAPI";
-import * as _BackendAdminAPISchemas from "./backendAdminAPI";
-
-namespace CommonSchemas {
- export const BackendAPI = _BackendAPISchemas;
- export const BackendAdminAPI = _BackendAdminAPISchemas;
-}
-
-export default CommonSchemas;
+export * as BackendAPI from "./backendAPI";
+export * as BackendAdminAPI from "./backendAdminAPI";
+export * as ParticipantPortalAPI from "./backendParticipantPortalAPI";
diff --git a/packages/common/src/utils/index.ts b/packages/common/src/utils/index.ts
index cb31d2c..8bf3a3f 100644
--- a/packages/common/src/utils/index.ts
+++ b/packages/common/src/utils/index.ts
@@ -1,28 +1,6 @@
-import { buildFlatSiteMap as _buildFlatSiteMap, buildNestedSiteMap as _buildNestedSiteMap, parseCss as _parseCss } from "./api";
-import { getCookie as _getCookie } from "./cookie";
-import { getFormValue as _getFormValue, isFormValid as _isFormValid } from "./form";
-import {
- filterPropertiesByLanguageInJsonSchema as _filterPropertiesByLanguageInJsonSchema,
- filterReadOnlyPropertiesInJsonSchema as _filterReadOnlyPropertiesInJsonSchema,
- filterWritablePropertiesInJsonSchema as _filterWritablePropertiesInJsonSchema,
-} from "./json_schema";
-import { extractQueryParameters as _extractQueryParameters } from "./openapi";
-import { isFilledString as _isFilledString, isValidHttpUrl as _isValidHttpUrl, rtrim as _rtrim } from "./string";
-
-namespace Utils {
- export const buildFlatSiteMap = _buildFlatSiteMap;
- export const buildNestedSiteMap = _buildNestedSiteMap;
- export const parseCss = _parseCss;
- export const getCookie = _getCookie;
- export const isFormValid = _isFormValid;
- export const getFormValue = _getFormValue;
- export const isFilledString = _isFilledString;
- export const isValidHttpUrl = _isValidHttpUrl;
- export const rtrim = _rtrim;
- export const filterWritablePropertiesInJsonSchema = _filterWritablePropertiesInJsonSchema;
- export const filterReadOnlyPropertiesInJsonSchema = _filterReadOnlyPropertiesInJsonSchema;
- export const filterPropertiesByLanguageInJsonSchema = _filterPropertiesByLanguageInJsonSchema;
- export const extractQueryParameters = _extractQueryParameters;
-}
-
-export default Utils;
+export { buildFlatSiteMap, buildNestedSiteMap, parseCss } from "./api";
+export { getCookie } from "./cookie";
+export { getFormValue, isFormValid } from "./form";
+export { filterPropertiesByLanguageInJsonSchema, filterReadOnlyPropertiesInJsonSchema, filterWritablePropertiesInJsonSchema } from "./json_schema";
+export { extractQueryParameters } from "./openapi";
+export { isFilledString, isValidHttpUrl, rtrim } from "./string";
diff --git a/packages/common/src/utils/openapi.ts b/packages/common/src/utils/openapi.ts
index 9373b5b..c795897 100644
--- a/packages/common/src/utils/openapi.ts
+++ b/packages/common/src/utils/openapi.ts
@@ -1,10 +1,6 @@
-import BackendAdminAPISchemas from "../schemas/backendAdminAPI";
+import { OpenAPIParameterSchema, OpenAPISchema } from "../schemas/backendAdminAPI";
-export const extractQueryParameters = (
- schema: BackendAdminAPISchemas.OpenAPISchema,
- app: string,
- resource: string
-): BackendAdminAPISchemas.OpenAPIParameterSchema[] => {
+export const extractQueryParameters = (schema: OpenAPISchema, app: string, resource: string): OpenAPIParameterSchema[] => {
const pathItem = schema.paths[`/v1/admin-api/${app}/${resource}/`];
if (!pathItem?.get?.parameters) return [];