Skip to content

Commit 0890a7e

Browse files
committed
fix: 새 API에 맞도록 수정 심사 어드민 수정
1 parent 50de9be commit 0890a7e

File tree

10 files changed

+153
-90
lines changed

10 files changed

+153
-90
lines changed

apps/pyconkr-admin/src/components/pages/modification_audit/components.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import {
1717
} from "@mui/material";
1818
import * as React from "react";
1919

20-
import { usePreviewImageData } from "./hooks";
21-
2220
type SharedPreviewFieldProps = {
2321
originalDataset: Record<string, unknown>;
2422
previewDataset: Record<string, unknown>;
@@ -111,7 +109,12 @@ const WidthSpecifiedFallbackImage = styled(Common.Components.FallbackImage)({
111109
});
112110

113111
export const PreviewImageField: React.FC<SharedPreviewFieldProps> = ({ originalDataset, previewDataset, name, label }) => {
114-
const { originalImage, previewImage } = usePreviewImageData(originalDataset, previewDataset, name) || {};
112+
const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
113+
const oldImgId = (originalDataset[name] as string) || "";
114+
const newImgId = (previewDataset[name] as string) || "";
115+
116+
const { data: originalImage } = Common.Hooks.BackendAdminAPI.usePublicFileQuery(backendAdminClient, oldImgId);
117+
const { data: previewImage } = Common.Hooks.BackendAdminAPI.usePublicFileQuery(backendAdminClient, newImgId);
115118

116119
return originalImage?.id === previewImage?.id ? (
117120
<Common.Components.Fieldset legend={label} style={{ width: "100%" }}>
@@ -130,7 +133,11 @@ export const PreviewImageField: React.FC<SharedPreviewFieldProps> = ({ originalD
130133
<Stack sx={{ width: "100%" }} direction="column" alignItems="flex-start" justifyContent="space-between">
131134
<Common.Components.Fieldset legend={label} style={{ width: "100%", backgroundColor: "rgba(255, 255, 0, 0.1)" }}>
132135
<Stack alignItems="center" justifyContent="center">
133-
<WidthSpecifiedFallbackImage src={previewImage?.file || ""} alt={label} errorFallback={<ImageFallback />} />
136+
{previewImage?.file ? (
137+
<WidthSpecifiedFallbackImage src={previewImage?.file || ""} alt={label} errorFallback={<ImageFallback />} />
138+
) : (
139+
<Typography variant="caption" children="새 이미지를 지정하지 않았습니다." />
140+
)}
134141
</Stack>
135142
</Common.Components.Fieldset>
136143
<Typography variant="caption">기존 이미지를 보려면 여기를 클릭해주세요.</Typography>

apps/pyconkr-admin/src/components/pages/modification_audit/hooks.tsx

Lines changed: 0 additions & 30 deletions
This file was deleted.

apps/pyconkr-admin/src/components/pages/modification_audit/pages.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Navigate, useParams } from "react-router-dom";
66

77
import { ModificationAuditProperties } from "./components";
88
import { ApproveSubmitConfirmDialog, RejectSubmitConfirmDialog } from "./dialogs";
9-
import { useModificationAuditData } from "./hooks";
109
import { SubModificationAuditPage } from "./sub_pages";
1110
import { BackendAdminSignInGuard } from "../../elements/admin_signin_guard";
1211

@@ -15,12 +14,14 @@ type EditorStateType = { actionStatus?: "approve" | "reject" };
1514
const InnerAdminModificationAuditEditor: React.FC = () => {
1615
const [editorState, setEditorState] = React.useState<EditorStateType>({});
1716
const { id } = useParams<{ id?: string }>();
18-
const auditData = useModificationAuditData<Record<string, string>>(id || "");
1917

20-
if (!auditData) return <Navigate to="/admin/modification-audit" replace />;
18+
const backendAdminClient = Common.Hooks.BackendAdminAPI.useBackendAdminClient();
19+
const { data } = Common.Hooks.BackendAdminAPI.useModificationAuditPreviewQuery<Record<string, string>>(backendAdminClient, id || "");
2120

22-
const { audit } = auditData;
23-
const { status, instance } = audit;
21+
if (!data) return <Navigate to="/admin/modification-audit" replace />;
22+
23+
const { modification_audit } = data;
24+
const { status, instance } = modification_audit;
2425
const { app, model } = instance;
2526
const btnDisabled = status !== "requested";
2627

@@ -30,17 +31,25 @@ const InnerAdminModificationAuditEditor: React.FC = () => {
3031

3132
return (
3233
<>
33-
<ApproveSubmitConfirmDialog open={editorState.actionStatus === "approve"} onClose={closeSubmitConfirmDialog} modificationAuditId={audit.id} />
34-
<RejectSubmitConfirmDialog open={editorState.actionStatus === "reject"} onClose={closeSubmitConfirmDialog} modificationAuditId={audit.id} />
34+
<ApproveSubmitConfirmDialog
35+
open={editorState.actionStatus === "approve"}
36+
onClose={closeSubmitConfirmDialog}
37+
modificationAuditId={modification_audit.id}
38+
/>
39+
<RejectSubmitConfirmDialog
40+
open={editorState.actionStatus === "reject"}
41+
onClose={closeSubmitConfirmDialog}
42+
modificationAuditId={modification_audit.id}
43+
/>
3544
<Box sx={{ flexGrow: 1, width: "100%", minHeight: "100%" }}>
3645
<Typography variant="h5" fontWeight="bold">
3746
{app.toUpperCase()} &gt; {model.toUpperCase()} &gt; 수정 심사
3847
</Typography>
3948
<Divider sx={{ my: 1, borderColor: "black" }} />
4049
<Stack sx={{ width: "100%", minHeight: "100%" }} spacing={2}>
4150
<Typography variant="h6" fontWeight="bold" children="심사 속성" />
42-
<ModificationAuditProperties audit={audit} />
43-
<SubModificationAuditPage {...auditData} />
51+
<ModificationAuditProperties audit={modification_audit} />
52+
<SubModificationAuditPage {...data} />
4453
<Stack alignItems="flex-end" spacing={1}>
4554
{btnDisabled && <Typography variant="body2" children={`현재 심사 상태가 ${status}입니다. 승인 또는 반려가 불가능합니다.`} />}
4655
<Stack direction="row" spacing={2} justifyContent="flex-end">
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { PresentationPreviewSubPage } from "./presentation_preview";
2-
import { SubModificationAuditPageType } from "./types";
2+
import { ModificationAuditPreviewSchema, PresentationPreviewSchema, SubModificationAuditPageType, UserPreviewSchema } from "./types";
33
import { UserExtPreviewSubPage } from "./userext_preview";
44

5-
export const SubModificationAuditPage: SubModificationAuditPageType = ({ audit, originalData, previewData }) => {
6-
switch (audit.instance.model) {
5+
export const SubModificationAuditPage: SubModificationAuditPageType<unknown> = (data) => {
6+
switch (data.modification_audit.instance.model) {
77
case "presentation":
8-
return <PresentationPreviewSubPage originalData={originalData} previewData={previewData} audit={audit} />;
8+
return <PresentationPreviewSubPage {...(data as unknown as ModificationAuditPreviewSchema<PresentationPreviewSchema>)} />;
99
case "userext":
10-
return <UserExtPreviewSubPage originalData={originalData} previewData={previewData} audit={audit} />;
10+
return <UserExtPreviewSubPage {...(data as unknown as ModificationAuditPreviewSchema<UserPreviewSchema>)} />;
1111
default:
12-
return <div>지원하지 않는 모델입니다: {audit.instance.model}</div>;
12+
return <div>지원하지 않는 모델입니다: {data.modification_audit.instance.model}</div>;
1313
}
1414
};
Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,73 @@
11
import * as Common from "@frontend/common";
2-
import { Divider, Typography } from "@mui/material";
2+
import { Card, Divider, TextField, Typography } from "@mui/material";
33

44
import { PreviewImageField, PreviewMarkdownField, PreviewTextField } from "../components";
5-
import { SubModificationAuditPageType } from "./types";
5+
import { PresentationPreviewSchema, SubModificationAuditPageType } from "./types";
66

7-
export const PresentationPreviewSubPage: SubModificationAuditPageType = ({ originalData, previewData }) => {
7+
type PresentationSpeakerPreviewItemProps = {
8+
originalSpeaker: PresentationPreviewSchema["speakers"][number];
9+
modifiedSpeaker: PresentationPreviewSchema["speakers"][number];
10+
};
11+
12+
const isSpeakerModified = (original: PresentationPreviewSchema["speakers"][number], modified: PresentationPreviewSchema["speakers"][number]) => {
13+
return (
14+
original.id !== modified.id ||
15+
original.user.id !== modified.user.id ||
16+
original.biography_ko !== modified.biography_ko ||
17+
original.biography_en !== modified.biography_en ||
18+
original.image !== modified.image
19+
);
20+
};
21+
22+
const PresentationSpeakerPreviewItem: React.FC<PresentationSpeakerPreviewItemProps> = ({ originalSpeaker, modifiedSpeaker }) => {
23+
const innerSpeakerPreviewItem = (
24+
<Common.Components.Fieldset legend={`발표자: ${modifiedSpeaker.user.nickname_ko} (${modifiedSpeaker.user.nickname_en})`}>
25+
<Common.Components.Fieldset legend="발표자 별칭">
26+
<TextField fullWidth disabled variant="outlined" value={modifiedSpeaker.user.nickname_ko} label="발표자 별칭 (국문)" sx={{ my: 1 }} />
27+
<TextField fullWidth disabled variant="outlined" value={modifiedSpeaker.user.nickname_en} label="발표자 별칭 (영문)" sx={{ my: 1 }} />
28+
</Common.Components.Fieldset>
29+
<PreviewImageField originalDataset={originalSpeaker} previewDataset={modifiedSpeaker} name="image_id" label="발표자 이미지" />
30+
<Common.Components.Fieldset legend="발표자 약력">
31+
<PreviewMarkdownField originalDataset={originalSpeaker} previewDataset={modifiedSpeaker} name="biography_ko" label="발표자 약력 (국문)" />
32+
<PreviewMarkdownField originalDataset={originalSpeaker} previewDataset={modifiedSpeaker} name="biography_en" label="발표자 약력 (영문)" />
33+
</Common.Components.Fieldset>
34+
</Common.Components.Fieldset>
35+
);
36+
37+
return isSpeakerModified(originalSpeaker, modifiedSpeaker) ? (
38+
<Card sx={{ width: "100%", backgroundColor: "rgba(255, 255, 0, 0.1)" }} children={innerSpeakerPreviewItem} />
39+
) : (
40+
innerSpeakerPreviewItem
41+
);
42+
};
43+
44+
export const PresentationPreviewSubPage: SubModificationAuditPageType<PresentationPreviewSchema> = ({ original, modified }) => {
845
return (
946
<>
1047
<Typography variant="h6" fontWeight="bold" children="발표 내용" />
1148
<Common.Components.Fieldset legend="제목">
12-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} name="title_ko" label="제목 (한국어)" />
13-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} name="title_en" label="제목 (영어)" />
49+
<PreviewTextField originalDataset={original} previewDataset={modified} name="title_ko" label="제목 (한국어)" />
50+
<PreviewTextField originalDataset={original} previewDataset={modified} name="title_en" label="제목 (영어)" />
1451
</Common.Components.Fieldset>
1552
<Common.Components.Fieldset legend="요약">
16-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} multiline name="summary_ko" label="요약 (한국어)" />
17-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} multiline name="summary_en" label="요약 (영어)" />
53+
<PreviewTextField originalDataset={original} previewDataset={modified} multiline name="summary_ko" label="요약 (한국어)" />
54+
<PreviewTextField originalDataset={original} previewDataset={modified} multiline name="summary_en" label="요약 (영어)" />
1855
</Common.Components.Fieldset>
1956
<Common.Components.Fieldset legend="상세 설명">
20-
<PreviewMarkdownField originalDataset={originalData} previewDataset={previewData} name="description_ko" label="상세 설명 (한국어)" />
21-
<PreviewMarkdownField originalDataset={originalData} previewDataset={previewData} name="description_en" label="상세 설명 (영어)" />
57+
<PreviewMarkdownField originalDataset={original} previewDataset={modified} name="description_ko" label="상세 설명 (한국어)" />
58+
<PreviewMarkdownField originalDataset={original} previewDataset={modified} name="description_en" label="상세 설명 (영어)" />
2259
</Common.Components.Fieldset>
23-
<PreviewImageField originalDataset={originalData} previewDataset={previewData} name="image" label="발표 이미지" />
60+
<PreviewImageField originalDataset={original} previewDataset={modified} name="image_id" label="발표 이미지" />
2461

2562
<Divider sx={{ my: 1, borderColor: "black" }} />
2663
<Typography variant="h6" fontWeight="bold" children="발표자 정보" />
64+
{modified.speakers.map((speaker) => (
65+
<PresentationSpeakerPreviewItem
66+
key={speaker.id}
67+
originalSpeaker={original.speakers.find((s) => s.id === speaker.id) || speaker}
68+
modifiedSpeaker={speaker}
69+
/>
70+
))}
2771
</>
2872
);
2973
};
Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
11
import BackendAdminAPISchemas from "../../../../../../../packages/common/src/schemas/backendAdminAPI";
22

3-
export type SubModificationAuditPageType = React.FC<{
4-
audit: BackendAdminAPISchemas.ModificationAuditSchema;
5-
originalData: Record<string, string>;
6-
previewData: Record<string, string>;
3+
export type ModificationAuditPreviewSchema<T> = BackendAdminAPISchemas.ModificationAuditPreviewSchema<T>;
4+
5+
export type PresentationPreviewSchema = {
6+
type: string;
7+
categories: string[];
8+
image: string | null;
9+
title_ko: string;
10+
title_en: string;
11+
summary_ko: string;
12+
summary_en: string;
13+
description_ko: string;
14+
description_en: string;
15+
speakers: {
16+
id: string;
17+
user: {
18+
id: number;
19+
nickname_ko: string;
20+
nickname_en: string;
21+
};
22+
image: string | null;
23+
biography_ko: string;
24+
biography_en: string;
25+
}[];
26+
};
27+
28+
export type UserPreviewSchema = {
29+
id: number;
30+
email: string;
31+
image: string | null;
32+
nickname_ko: string;
33+
nickname_en: string;
34+
};
35+
36+
export type SubModificationAuditPageType<T> = React.FC<{
37+
modification_audit: BackendAdminAPISchemas.ModificationAuditSchema;
38+
original: T;
39+
modified: T;
740
}>;

apps/pyconkr-admin/src/components/pages/modification_audit/sub_pages/userext_preview.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@ import * as Common from "@frontend/common";
22
import { Typography } from "@mui/material";
33

44
import { PreviewImageField, PreviewTextField } from "../components";
5-
import { SubModificationAuditPageType } from "./types";
5+
import { SubModificationAuditPageType, UserPreviewSchema } from "./types";
66

7-
export const UserExtPreviewSubPage: SubModificationAuditPageType = ({ originalData, previewData }) => {
7+
export const UserExtPreviewSubPage: SubModificationAuditPageType<UserPreviewSchema> = ({ original, modified }) => {
88
return (
99
<>
1010
<Typography variant="h6" fontWeight="bold" children="프로필 내용" />
1111
<Common.Components.Fieldset legend="계정 정보">
12-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} name="id" label="계정 일련번호" />
13-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} name="username" label="계정 ID" />
14-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} name="email" label="계정 이메일" />
12+
<PreviewTextField originalDataset={original} previewDataset={modified} name="id" label="계정 일련번호" />
13+
<PreviewTextField originalDataset={original} previewDataset={modified} name="username" label="계정 ID" />
14+
<PreviewTextField originalDataset={original} previewDataset={modified} name="email" label="계정 이메일" />
1515
</Common.Components.Fieldset>
16-
<PreviewImageField originalDataset={originalData} previewDataset={previewData} name="image" label="프로필 이미지" />
16+
<PreviewImageField originalDataset={original} previewDataset={modified} name="image_id" label="프로필 이미지" />
1717
<Common.Components.Fieldset legend="별칭">
18-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} multiline name="nickname_ko" label="별칭 (한국어)" />
19-
<PreviewTextField originalDataset={originalData} previewDataset={previewData} multiline name="nickname_en" label="별칭 (영어)" />
18+
<PreviewTextField originalDataset={original} previewDataset={modified} multiline name="nickname_ko" label="별칭 (한국어)" />
19+
<PreviewTextField originalDataset={original} previewDataset={modified} multiline name="nickname_en" label="별칭 (영어)" />
2020
</Common.Components.Fieldset>
2121
</>
2222
);

packages/common/src/apis/admin_api.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,9 @@ namespace BackendAdminAPIs {
9191
);
9292

9393
export const previewModificationAudit =
94-
<T>(client: BackendAPIClient, app: string, resource: string, instanceId: string, auditId: string) =>
95-
async () => {
96-
try {
97-
return await client.get<T>(`v1/admin-api/${app}/${resource}/${instanceId}/preview/${auditId}/`);
98-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
99-
} catch (_) {
100-
return null;
101-
}
102-
};
94+
<T>(client: BackendAPIClient, id: string) =>
95+
() =>
96+
client.get<BackendAdminAPISchemas.ModificationAuditPreviewSchema<T>>(`v1/admin-api/modification-audit/modification-audit/${id}/preview/`);
10397
}
10498

10599
export default BackendAdminAPIs;

0 commit comments

Comments
 (0)