@tipp/ui 2.10.5 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/index.js +6 -6
- package/dist/app/platform/edit-coaching-time.js +6 -6
- package/dist/app/platform/edit-service-type.js +6 -6
- package/dist/app/platform/goal-manage-card-edit.js +6 -6
- package/dist/app/platform/on-offline-radio-card.js +6 -6
- package/dist/app/platform/reservation-card.js +6 -6
- package/dist/app/platform/session-card.js +6 -6
- package/dist/app/roleplay/index.cjs +8 -27
- package/dist/app/roleplay/index.cjs.map +1 -1
- package/dist/app/roleplay/index.js +10 -10
- package/dist/app/roleplay/parts/content.cjs +1 -24
- package/dist/app/roleplay/parts/content.cjs.map +1 -1
- package/dist/app/roleplay/parts/content.js +8 -8
- package/dist/app/roleplay/parts/header.cjs +4 -2
- package/dist/app/roleplay/parts/header.cjs.map +1 -1
- package/dist/app/roleplay/parts/header.d.cts +3 -1
- package/dist/app/roleplay/parts/header.d.ts +3 -1
- package/dist/app/roleplay/parts/header.js +1 -1
- package/dist/app/roleplay/parts/score-trend-section.js +6 -6
- package/dist/app/roleplay/parts/step-detail.cjs +1 -24
- package/dist/app/roleplay/parts/step-detail.cjs.map +1 -1
- package/dist/app/roleplay/parts/step-detail.js +1 -1
- package/dist/app/roleplay/rp-session-detail.cjs +8 -27
- package/dist/app/roleplay/rp-session-detail.cjs.map +1 -1
- package/dist/app/roleplay/rp-session-detail.d.cts +3 -1
- package/dist/app/roleplay/rp-session-detail.d.ts +3 -1
- package/dist/app/roleplay/rp-session-detail.js +10 -10
- package/dist/{chunk-CPSXONQO.js → chunk-BTU3IMVG.js} +2 -2
- package/dist/{chunk-VJREZH2Z.js → chunk-JDCA3TP5.js} +5 -3
- package/dist/chunk-JDCA3TP5.js.map +1 -0
- package/dist/{chunk-W7LO5KYT.js → chunk-NEJCZABQ.js} +4 -4
- package/dist/{chunk-6GODZ2YW.js → chunk-ORP7UCUU.js} +6 -4
- package/dist/chunk-ORP7UCUU.js.map +1 -0
- package/dist/{chunk-KJPBBBVK.js → chunk-YHA4OOND.js} +2 -25
- package/dist/chunk-YHA4OOND.js.map +1 -0
- package/dist/index.js +15 -15
- package/dist/molecules/dynamic-form-editor.js +4 -4
- package/dist/molecules/index.js +15 -15
- package/package.json +1 -1
- package/src/app/roleplay/parts/header.tsx +4 -0
- package/src/app/roleplay/parts/step-detail.tsx +1 -24
- package/src/app/roleplay/rp-session-detail.tsx +4 -0
- package/dist/chunk-6GODZ2YW.js.map +0 -1
- package/dist/chunk-KJPBBBVK.js.map +0 -1
- package/dist/chunk-VJREZH2Z.js.map +0 -1
- /package/dist/{chunk-CPSXONQO.js.map → chunk-BTU3IMVG.js.map} +0 -0
- /package/dist/{chunk-W7LO5KYT.js.map → chunk-NEJCZABQ.js.map} +0 -0
|
@@ -11,7 +11,9 @@ interface RpSessionDetailProps {
|
|
|
11
11
|
}) => string | Promise<string>;
|
|
12
12
|
onError?: (error: unknown, context: Record<string, unknown>) => void;
|
|
13
13
|
sectionScrollMarginTop?: string;
|
|
14
|
+
/** 헤더 액션 행(PDF 다운로드·영상)의 '영상' 버튼 우측에 렌더되는 소비자 정의 액션 슬롯(예: website 공유하기 버튼). */
|
|
15
|
+
headerActions?: React__default.ReactNode;
|
|
14
16
|
}
|
|
15
|
-
declare function RpSessionDetail({ detail, history, isLoading, script, onResolveMediaUrl, onError: _onError, sectionScrollMarginTop, }: RpSessionDetailProps): React__default.ReactElement;
|
|
17
|
+
declare function RpSessionDetail({ detail, history, isLoading, script, onResolveMediaUrl, onError: _onError, sectionScrollMarginTop, headerActions, }: RpSessionDetailProps): React__default.ReactElement;
|
|
16
18
|
|
|
17
19
|
export { RpSessionDetail, type RpSessionDetailProps };
|
|
@@ -11,7 +11,9 @@ interface RpSessionDetailProps {
|
|
|
11
11
|
}) => string | Promise<string>;
|
|
12
12
|
onError?: (error: unknown, context: Record<string, unknown>) => void;
|
|
13
13
|
sectionScrollMarginTop?: string;
|
|
14
|
+
/** 헤더 액션 행(PDF 다운로드·영상)의 '영상' 버튼 우측에 렌더되는 소비자 정의 액션 슬롯(예: website 공유하기 버튼). */
|
|
15
|
+
headerActions?: React__default.ReactNode;
|
|
14
16
|
}
|
|
15
|
-
declare function RpSessionDetail({ detail, history, isLoading, script, onResolveMediaUrl, onError: _onError, sectionScrollMarginTop, }: RpSessionDetailProps): React__default.ReactElement;
|
|
17
|
+
declare function RpSessionDetail({ detail, history, isLoading, script, onResolveMediaUrl, onError: _onError, sectionScrollMarginTop, headerActions, }: RpSessionDetailProps): React__default.ReactElement;
|
|
16
18
|
|
|
17
19
|
export { RpSessionDetail, type RpSessionDetailProps };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
RpSessionDetail
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-ORP7UCUU.js";
|
|
5
5
|
import "../../chunk-TFJJKM3W.js";
|
|
6
|
-
import "../../chunk-
|
|
7
|
-
import "../../chunk-
|
|
6
|
+
import "../../chunk-BTU3IMVG.js";
|
|
7
|
+
import "../../chunk-YHA4OOND.js";
|
|
8
8
|
import "../../chunk-WVY3C64M.js";
|
|
9
9
|
import "../../chunk-5QIT4URV.js";
|
|
10
10
|
import "../../chunk-GA6W62DO.js";
|
|
11
|
-
import "../../chunk-
|
|
11
|
+
import "../../chunk-JDCA3TP5.js";
|
|
12
12
|
import "../../chunk-2XDAK4B7.js";
|
|
13
13
|
import "../../chunk-2IRG44IV.js";
|
|
14
14
|
import "../../chunk-DIISQDYA.js";
|
|
@@ -56,7 +56,6 @@ import "../../chunk-K3Q4XLCN.js";
|
|
|
56
56
|
import "../../chunk-AT5PAJLW.js";
|
|
57
57
|
import "../../chunk-VVWQZK5L.js";
|
|
58
58
|
import "../../chunk-2ISIAPFS.js";
|
|
59
|
-
import "../../chunk-AHYOAFOU.js";
|
|
60
59
|
import "../../chunk-CUS3ORMD.js";
|
|
61
60
|
import "../../chunk-6OT5OYGM.js";
|
|
62
61
|
import "../../chunk-P4DJ5F6Z.js";
|
|
@@ -69,24 +68,25 @@ import "../../chunk-BXX3B3E4.js";
|
|
|
69
68
|
import "../../chunk-NRPDVI76.js";
|
|
70
69
|
import "../../chunk-2BPFXK4L.js";
|
|
71
70
|
import "../../chunk-NWJSLIQ3.js";
|
|
72
|
-
import "../../chunk-
|
|
73
|
-
import "../../chunk-
|
|
71
|
+
import "../../chunk-AHYOAFOU.js";
|
|
72
|
+
import "../../chunk-NEJCZABQ.js";
|
|
74
73
|
import "../../chunk-77H5BUYO.js";
|
|
75
74
|
import "../../chunk-K7LTEKQS.js";
|
|
76
|
-
import "../../chunk-SQ3FYBJT.js";
|
|
77
75
|
import "../../chunk-2EPKY2VT.js";
|
|
78
76
|
import "../../chunk-QLNAAZJX.js";
|
|
79
77
|
import "../../chunk-PAUEQXYG.js";
|
|
80
|
-
import "../../chunk-OOM522XP.js";
|
|
81
78
|
import "../../chunk-N3FMP27I.js";
|
|
82
79
|
import "../../chunk-BEKSO5JG.js";
|
|
83
80
|
import "../../chunk-IJOOKMKQ.js";
|
|
84
81
|
import "../../chunk-C6HO3IGE.js";
|
|
85
|
-
import "../../chunk-NK6S7ZMB.js";
|
|
86
82
|
import "../../chunk-3DZIX4CE.js";
|
|
87
83
|
import "../../chunk-CBYIPRND.js";
|
|
88
84
|
import "../../chunk-Z7WNKARH.js";
|
|
89
85
|
import "../../chunk-D4U2ZV2A.js";
|
|
86
|
+
import "../../chunk-V7KAHLW2.js";
|
|
87
|
+
import "../../chunk-SQ3FYBJT.js";
|
|
88
|
+
import "../../chunk-NK6S7ZMB.js";
|
|
89
|
+
import "../../chunk-OOM522XP.js";
|
|
90
90
|
import "../../chunk-FAL6S2XK.js";
|
|
91
91
|
import "../../chunk-HBF6IIVZ.js";
|
|
92
92
|
import "../../chunk-AELKCD6B.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
StepDetail
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YHA4OOND.js";
|
|
4
4
|
import {
|
|
5
5
|
StepSummary
|
|
6
6
|
} from "./chunk-WVY3C64M.js";
|
|
@@ -128,4 +128,4 @@ function Content({
|
|
|
128
128
|
export {
|
|
129
129
|
Content
|
|
130
130
|
};
|
|
131
|
-
//# sourceMappingURL=chunk-
|
|
131
|
+
//# sourceMappingURL=chunk-BTU3IMVG.js.map
|
|
@@ -70,7 +70,8 @@ function Header({
|
|
|
70
70
|
detail,
|
|
71
71
|
hasScript,
|
|
72
72
|
onOpenReplay,
|
|
73
|
-
onResolveMediaUrl
|
|
73
|
+
onResolveMediaUrl,
|
|
74
|
+
actions
|
|
74
75
|
}) {
|
|
75
76
|
var _a;
|
|
76
77
|
const pdfHref = detail.embedLink;
|
|
@@ -175,7 +176,8 @@ function Header({
|
|
|
175
176
|
/* @__PURE__ */ jsx("span", { style: { whiteSpace: "nowrap" }, children: "\uC601\uC0C1" })
|
|
176
177
|
]
|
|
177
178
|
}
|
|
178
|
-
) : null
|
|
179
|
+
) : null,
|
|
180
|
+
actions != null ? actions : null
|
|
179
181
|
]
|
|
180
182
|
}
|
|
181
183
|
)
|
|
@@ -187,4 +189,4 @@ function Header({
|
|
|
187
189
|
export {
|
|
188
190
|
Header
|
|
189
191
|
};
|
|
190
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-JDCA3TP5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/app/roleplay/parts/header.tsx"],"sourcesContent":["'use client';\n\nimport { Badge, Box, Button, Flex, Heading, Typo } from '../../../atoms';\nimport type { RpSessionDetailData } from '../types';\nimport { formatDate, formatDuration, statusLabelOf } from '../utils/session-utils';\n\nexport interface HeaderProps {\n detail: RpSessionDetailData;\n hasScript: boolean;\n onOpenReplay: () => void;\n onResolveMediaUrl?: (\n rawUrl: string,\n options: { disposition: 'inline' | 'attachment' }\n ) => string | Promise<string>;\n /** '영상' 버튼 우측에 렌더되는 소비자 정의 액션 슬롯. */\n actions?: React.ReactNode;\n}\n\nfunction PdfIcon(): React.ReactElement {\n return (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height=\"13\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"13\"\n >\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 3v5h5\" />\n <path d=\"M12 12v5\" />\n <path d=\"M9.5 14.5 12 17l2.5-2.5\" />\n </svg>\n );\n}\n\nfunction VideoIcon(): React.ReactElement {\n return (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height=\"13\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"13\"\n >\n <rect height=\"12\" rx=\"2\" width=\"13\" x=\"2\" y=\"6\" />\n <path d=\"m15 10 6-3v10l-6-3z\" />\n </svg>\n );\n}\n\nexport function Header({\n detail,\n hasScript,\n onOpenReplay,\n onResolveMediaUrl,\n actions,\n}: HeaderProps): React.ReactElement {\n // PDF 산출물은 embedLink(AI 리포트 PDF). trainingLogURL 은 대화 스크립트 JSON 이므로 PDF 가 아니다.\n const pdfHref = detail.embedLink;\n const hasReplayMedia = Boolean(\n detail.trainingVideoURL || detail.trainingAudioURL\n );\n\n const handlePdfClick = (): void => {\n if (!pdfHref || !onResolveMediaUrl) return;\n void Promise.resolve(\n onResolveMediaUrl(pdfHref, { disposition: 'attachment' })\n ).then((url) => {\n window.open(url, '_blank');\n });\n };\n\n const replayActive = hasScript && hasReplayMedia;\n\n return (\n <Box>\n <Flex\n align={{ md: 'start' }}\n direction={{ initial: 'column', md: 'row' }}\n gap=\"4\"\n justify=\"between\"\n >\n <Box style={{ minWidth: 0 }}>\n <Flex align=\"center\" gap=\"2\" mb=\"2\" wrap=\"wrap\">\n <Badge color=\"neutral\" size=\"small\" variant=\"soft\">\n {statusLabelOf(detail.status)}\n </Badge>\n <Typo as=\"span\" color=\"gray\" variant=\"body\">\n {detail.trainingSessionNum}회차\n {detail.characterTitle ? ` · ${detail.characterTitle}` : ''}\n </Typo>\n </Flex>\n <Heading\n size={{ initial: '5', md: '7' }}\n style={{ textWrap: 'balance' }}\n weight=\"bold\"\n >\n {detail.scenarioTitle ?? '롤플레잉 세션'}\n </Heading>\n <Typo as=\"p\" color=\"gray\" mono mt=\"1\" variant=\"body\">\n {formatDate(detail.createdAt)} · {formatDuration(detail.trainingTime)}\n </Typo>\n </Box>\n <Flex\n gap=\"2\"\n justify={{ initial: 'start', md: 'end' }}\n style={{ flexShrink: 0 }}\n wrap=\"wrap\"\n >\n {onResolveMediaUrl ? (\n <Button\n color=\"gray\"\n disabled={!pdfHref}\n onClick={pdfHref ? handlePdfClick : undefined}\n size={{ initial: 'small', md: 'medium' }}\n title={pdfHref ? undefined : '산출물 없음'}\n type=\"button\"\n variant=\"outline\"\n >\n <PdfIcon />\n <span style={{ whiteSpace: 'nowrap' }}>PDF 다운로드</span>\n </Button>\n ) : (\n <Button\n asChild={Boolean(pdfHref)}\n color=\"gray\"\n disabled={!pdfHref}\n size={{ initial: 'small', md: 'medium' }}\n title={pdfHref ? undefined : '산출물 없음'}\n type=\"button\"\n variant=\"outline\"\n >\n {pdfHref ? (\n <a href={pdfHref} rel=\"noopener noreferrer\" target=\"_blank\">\n <PdfIcon />\n <span style={{ whiteSpace: 'nowrap' }}>PDF 다운로드</span>\n </a>\n ) : (\n <span>\n <PdfIcon />\n <span style={{ whiteSpace: 'nowrap' }}>PDF 다운로드</span>\n </span>\n )}\n </Button>\n )}\n {hasScript ? (\n <Button\n color=\"gray\"\n disabled={!replayActive}\n onClick={onOpenReplay}\n size={{ initial: 'small', md: 'medium' }}\n title={replayActive ? undefined : '다시보기 없음'}\n type=\"button\"\n variant=\"outline\"\n >\n <VideoIcon />\n <span style={{ whiteSpace: 'nowrap' }}>영상</span>\n </Button>\n ) : null}\n {actions ?? null}\n </Flex>\n </Flex>\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DynamicFormEditorPreviewPanel
|
|
3
|
-
} from "./chunk-V7KAHLW2.js";
|
|
4
1
|
import {
|
|
5
2
|
DynamicFormEditorFieldEditorPanel
|
|
6
3
|
} from "./chunk-3DZIX4CE.js";
|
|
@@ -22,6 +19,9 @@ import {
|
|
|
22
19
|
import {
|
|
23
20
|
DynamicFormEditorIssuesPanel
|
|
24
21
|
} from "./chunk-D4U2ZV2A.js";
|
|
22
|
+
import {
|
|
23
|
+
DynamicFormEditorPreviewPanel
|
|
24
|
+
} from "./chunk-V7KAHLW2.js";
|
|
25
25
|
import {
|
|
26
26
|
Flex
|
|
27
27
|
} from "./chunk-25HMMI7R.js";
|
|
@@ -227,4 +227,4 @@ function DynamicFormEditor(props) {
|
|
|
227
227
|
export {
|
|
228
228
|
DynamicFormEditor
|
|
229
229
|
};
|
|
230
|
-
//# sourceMappingURL=chunk-
|
|
230
|
+
//# sourceMappingURL=chunk-NEJCZABQ.js.map
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-TFJJKM3W.js";
|
|
4
4
|
import {
|
|
5
5
|
Content
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BTU3IMVG.js";
|
|
7
7
|
import {
|
|
8
8
|
Header
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JDCA3TP5.js";
|
|
10
10
|
import {
|
|
11
11
|
SessionReplayDialog
|
|
12
12
|
} from "./chunk-AS3JVRQ3.js";
|
|
@@ -83,7 +83,8 @@ function RpSessionDetail({
|
|
|
83
83
|
script,
|
|
84
84
|
onResolveMediaUrl,
|
|
85
85
|
onError: _onError,
|
|
86
|
-
sectionScrollMarginTop = "120px"
|
|
86
|
+
sectionScrollMarginTop = "120px",
|
|
87
|
+
headerActions
|
|
87
88
|
}) {
|
|
88
89
|
const [replayOpen, setReplayOpen] = useState(false);
|
|
89
90
|
const speechShare = useMemo(
|
|
@@ -104,6 +105,7 @@ function RpSessionDetail({
|
|
|
104
105
|
/* @__PURE__ */ jsx(
|
|
105
106
|
Header,
|
|
106
107
|
{
|
|
108
|
+
actions: headerActions,
|
|
107
109
|
detail,
|
|
108
110
|
hasScript,
|
|
109
111
|
onOpenReplay: () => {
|
|
@@ -139,4 +141,4 @@ function RpSessionDetail({
|
|
|
139
141
|
export {
|
|
140
142
|
RpSessionDetail
|
|
141
143
|
};
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
144
|
+
//# sourceMappingURL=chunk-ORP7UCUU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/app/roleplay/rp-session-detail.tsx"],"sourcesContent":["'use client';\n\nimport React, { useMemo, useState } from 'react';\nimport { Box, Card, Flex, Heading, Progress, Skeleton, Typo } from '../../atoms';\nimport type { RpSessionDetailData, RpSessionHistoryItem, RpSessionScript } from './types';\nimport { parseReportData } from './utils/report-parse';\nimport { computeSpeechShare } from './utils/session-utils';\nimport { Content } from './parts/content';\nimport { Header } from './parts/header';\nimport { SessionReplayDialog } from './parts/session-replay-dialog';\n\n/* ───────────────────────── Public contract ───────────────────────── */\n\nexport interface RpSessionDetailProps {\n detail: RpSessionDetailData;\n history: RpSessionHistoryItem[];\n isLoading?: boolean;\n script?: RpSessionScript | null;\n onResolveMediaUrl?: (\n rawUrl: string,\n options: { disposition: 'inline' | 'attachment' }\n ) => string | Promise<string>;\n onError?: (error: unknown, context: Record<string, unknown>) => void;\n sectionScrollMarginTop?: string;\n /** 헤더 액션 행(PDF 다운로드·영상)의 '영상' 버튼 우측에 렌더되는 소비자 정의 액션 슬롯(예: website 공유하기 버튼). */\n headerActions?: React.ReactNode;\n}\n\n/* ───────────────────────── Skeleton ───────────────────────── */\n\nfunction RpSessionDetailSkeleton(): React.ReactElement {\n return (\n <Box py=\"6\">\n <Flex direction=\"column\" gap=\"6\">\n <Box>\n <Skeleton>\n <Heading size=\"7\">롤플레잉 세션 제목 로딩 중</Heading>\n </Skeleton>\n <Box mt=\"2\">\n <Skeleton>\n <Typo as=\"p\" variant=\"body\">\n 날짜 · 소요 시간이 로딩되는 영역입니다\n </Typo>\n </Skeleton>\n </Box>\n </Box>\n <section>\n <Skeleton>\n <Heading size=\"5\">종합 점수</Heading>\n </Skeleton>\n <Box mt=\"3\">\n <Card variant=\"surface\">\n <Flex align=\"center\" direction=\"column\" gap=\"2\" py=\"3\">\n <Skeleton>\n <Heading size=\"7\">00</Heading>\n </Skeleton>\n </Flex>\n </Card>\n </Box>\n </section>\n <section>\n <Skeleton>\n <Heading size=\"5\">평가 지표 요약</Heading>\n </Skeleton>\n <Box mt=\"3\">\n <Flex direction=\"column\" gap=\"3\">\n {[0, 1, 2].map((i) => (\n <Skeleton key={i}>\n <Typo as=\"p\" variant=\"body\">\n 평가 지표 항목이 로딩되는 중입니다\n </Typo>\n </Skeleton>\n ))}\n </Flex>\n </Box>\n </section>\n </Flex>\n </Box>\n );\n}\n\n/* ───────────────────────── Analyzing state ───────────────────────── */\n\nfunction AnalyzingState(): React.ReactElement {\n return (\n <Flex\n align=\"center\"\n direction=\"column\"\n justify=\"center\"\n style={{\n border: '1px dashed var(--gray-6)',\n borderRadius: 'var(--radius-3)',\n background: 'var(--gray-a1)',\n padding: '40px 24px',\n textAlign: 'center',\n }}\n >\n <Heading size={{ initial: '4', md: '5' }} weight=\"bold\">\n AI 분석 중입니다\n </Heading>\n <Box mt=\"2\" style={{ maxWidth: '480px' }}>\n <Typo as=\"p\" variant=\"body\">\n 대화와 산출물은 저장되었고, AI가 지표별 근거와 코칭을 생성하는 중입니다.\n </Typo>\n </Box>\n <Box mt=\"4\" style={{ width: '100%', maxWidth: '280px' }}>\n <Progress size=\"2\" value={66} />\n </Box>\n </Flex>\n );\n}\n\n/* ───────────────────────── Main component ───────────────────────── */\n\nexport function RpSessionDetail({\n detail,\n history,\n isLoading = false,\n script,\n onResolveMediaUrl,\n onError: _onError,\n sectionScrollMarginTop = '120px',\n headerActions,\n}: RpSessionDetailProps): React.ReactElement {\n const [replayOpen, setReplayOpen] = useState(false);\n\n // script 미전달 시 발화량 표시 생략. 전달 시 script로 계산.\n const speechShare = useMemo(\n () => (script !== null && script !== undefined ? computeSpeechShare(script.items) : null),\n [script],\n );\n\n const report = useMemo(\n () => parseReportData(detail.reportData, detail.guideline, detail.displayMeta),\n [detail.reportData, detail.guideline, detail.displayMeta],\n );\n\n const hasScript = script !== null && script !== undefined;\n const isAnalyzing = detail.status === 'analyzing';\n\n if (isLoading) {\n return <RpSessionDetailSkeleton />;\n }\n\n return (\n <Box py=\"6\">\n <Flex direction=\"column\" gap={{ initial: '5', md: '7' }}>\n <Header\n actions={headerActions}\n detail={detail}\n hasScript={hasScript}\n onOpenReplay={() => {\n setReplayOpen(true);\n }}\n onResolveMediaUrl={onResolveMediaUrl}\n />\n\n {isAnalyzing ? (\n <AnalyzingState />\n ) : (\n <Content\n detail={detail}\n history={history}\n report={report}\n scrollMarginTop={sectionScrollMarginTop}\n speechShare={speechShare}\n />\n )}\n </Flex>\n\n <SessionReplayDialog\n detail={detail}\n onOpenChange={setReplayOpen}\n onResolveMediaUrl={onResolveMediaUrl}\n open={replayOpen}\n script={script}\n />\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -83,7 +83,7 @@ function StepDetail({
|
|
|
83
83
|
step.basis ? /* @__PURE__ */ jsx(RubricField, { label: "\uADFC\uAC70", value: step.basis }) : null,
|
|
84
84
|
step.issue ? /* @__PURE__ */ jsx(RubricField, { label: "\uC544\uC26C\uC6B4 \uC810", value: step.issue }) : null
|
|
85
85
|
] }) }) : null,
|
|
86
|
-
step.improve || step.example
|
|
86
|
+
step.improve || step.example ? /* @__PURE__ */ jsx(Box, { pt: "3", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "3", children: [
|
|
87
87
|
step.improve ? /* @__PURE__ */ jsx(RubricField, { label: "\uAC1C\uC120\uC810", value: step.improve }) : null,
|
|
88
88
|
step.example ? /* @__PURE__ */ jsxs(
|
|
89
89
|
Box,
|
|
@@ -107,29 +107,6 @@ function StepDetail({
|
|
|
107
107
|
/* @__PURE__ */ jsx(Box, { mt: "1", style: { maxWidth: "65ch" }, children: /* @__PURE__ */ jsx(Typo, { as: "p", style: { color: "var(--accent-11)" }, variant: "body", children: step.example }) })
|
|
108
108
|
]
|
|
109
109
|
}
|
|
110
|
-
) : null,
|
|
111
|
-
step.idealExample ? /* @__PURE__ */ jsxs(
|
|
112
|
-
Box,
|
|
113
|
-
{
|
|
114
|
-
p: "2",
|
|
115
|
-
style: {
|
|
116
|
-
borderRadius: "var(--radius-2)",
|
|
117
|
-
background: "var(--gray-a2)"
|
|
118
|
-
},
|
|
119
|
-
children: [
|
|
120
|
-
/* @__PURE__ */ jsx(Typo, { as: "p", color: "gray", variant: "body", weight: "medium", children: "\uBAA8\uBC94 \uC608\uC2DC" }),
|
|
121
|
-
/* @__PURE__ */ jsx(Box, { mt: "1", style: { maxWidth: "65ch" }, children: /* @__PURE__ */ jsx(
|
|
122
|
-
Typo,
|
|
123
|
-
{
|
|
124
|
-
as: "p",
|
|
125
|
-
color: "gray",
|
|
126
|
-
style: { whiteSpace: "pre-line" },
|
|
127
|
-
variant: "body",
|
|
128
|
-
children: step.idealExample
|
|
129
|
-
}
|
|
130
|
-
) })
|
|
131
|
-
]
|
|
132
|
-
}
|
|
133
110
|
) : null
|
|
134
111
|
] }) }) : null
|
|
135
112
|
] })
|
|
@@ -139,4 +116,4 @@ function StepDetail({
|
|
|
139
116
|
export {
|
|
140
117
|
StepDetail
|
|
141
118
|
};
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
119
|
+
//# sourceMappingURL=chunk-YHA4OOND.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/app/roleplay/parts/step-detail.tsx"],"sourcesContent":["'use client';\n\nimport { Box, Flex, Progress, Typo } from '../../../atoms';\nimport type { RpReportStep } from '../utils/report-parse';\nimport {\n stepCode,\n stepColor,\n stepGradeLabel,\n stepRatio,\n stepScoreText,\n stepVars,\n} from '../utils/session-utils';\n\nexport interface StepDetailProps {\n step: RpReportStep;\n scrollMarginTop?: string;\n}\n\nfunction RubricField({\n label,\n value,\n}: {\n label: string;\n value: string;\n}): React.ReactElement {\n return (\n <Box>\n <Typo as=\"p\" variant=\"body\" weight=\"medium\">\n {label}\n </Typo>\n <Box mt=\"1\" style={{ maxWidth: '65ch' }}>\n <Typo as=\"p\" variant=\"body\">\n {value}\n </Typo>\n </Box>\n </Box>\n );\n}\n\nexport function StepDetail({\n step,\n scrollMarginTop = '120px',\n}: StepDetailProps): React.ReactElement {\n const qv = stepVars(step);\n const ratio = stepRatio(step);\n const scoreText = stepScoreText(step);\n const gradeLabel = stepGradeLabel(step);\n\n return (\n <Box id={`step-${step.key}`} style={{ scrollMarginTop }}>\n <Flex align=\"center\" gap=\"2\" justify=\"between\" mb=\"1\">\n <Box style={{ minWidth: 0 }}>\n <Typo as=\"span\" color=\"gray\" mono variant=\"body\">\n {stepCode(step)}\n </Typo>\n <Typo as=\"p\" variant=\"subtitle\" weight=\"bold\">\n {step.label}\n </Typo>\n </Box>\n <Flex align=\"end\" direction=\"column\" gap=\"1\" style={{ flexShrink: 0 }}>\n {scoreText !== null ? (\n <Typo\n as=\"span\"\n mono\n style={{ color: qv.fg }}\n variant=\"subtitle\"\n weight=\"bold\"\n >\n {scoreText}\n </Typo>\n ) : null}\n {gradeLabel !== null ? (\n <Typo\n as=\"span\"\n mono\n style={{\n display: 'inline-block',\n borderRadius: 'var(--radius-2)',\n border: `1px solid ${qv.border}`,\n background: qv.bg,\n color: qv.fg,\n padding: '1px 8px',\n }}\n variant=\"body\"\n weight=\"medium\"\n >\n {gradeLabel}\n </Typo>\n ) : null}\n </Flex>\n </Flex>\n\n {ratio !== null ? (\n <Box mb=\"3\" mt=\"2\">\n <Progress color={stepColor(step)} size=\"2\" value={ratio * 100} />\n </Box>\n ) : null}\n\n {step.description ? (\n <Box mb=\"3\" mt={ratio !== null ? '0' : '2'} style={{ maxWidth: '65ch' }}>\n <Typo as=\"p\" color=\"gray\" variant=\"body\">\n {step.description}\n </Typo>\n </Box>\n ) : null}\n\n <Flex direction=\"column\" gap=\"0\">\n {step.basis || step.issue ? (\n <Box pb=\"3\" style={{ borderBottom: '1px solid var(--gray-a4)' }}>\n <Flex direction=\"column\" gap=\"3\">\n {step.basis ? <RubricField label=\"근거\" value={step.basis} /> : null}\n {step.issue ? <RubricField label=\"아쉬운 점\" value={step.issue} /> : null}\n </Flex>\n </Box>\n ) : null}\n\n {step.improve || step.example ? (\n <Box pt=\"3\">\n <Flex direction=\"column\" gap=\"3\">\n {step.improve ? <RubricField label=\"개선점\" value={step.improve} /> : null}\n {step.example ? (\n <Box\n p=\"2\"\n style={{\n borderRadius: 'var(--radius-2)',\n background: 'var(--accent-a2)',\n }}\n >\n <Typo\n as=\"p\"\n style={{ color: 'var(--accent-11)' }}\n variant=\"body\"\n weight=\"medium\"\n >\n 예시 스크립트\n </Typo>\n <Box mt=\"1\" style={{ maxWidth: '65ch' }}>\n <Typo as=\"p\" style={{ color: 'var(--accent-11)' }} variant=\"body\">\n {step.example}\n </Typo>\n </Box>\n </Box>\n ) : null}\n </Flex>\n </Box>\n ) : null}\n </Flex>\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -123,9 +123,6 @@ import {
|
|
|
123
123
|
DatePicker
|
|
124
124
|
} from "./chunk-VVWQZK5L.js";
|
|
125
125
|
import "./chunk-2ISIAPFS.js";
|
|
126
|
-
import {
|
|
127
|
-
TrainingInfoGuideline
|
|
128
|
-
} from "./chunk-AHYOAFOU.js";
|
|
129
126
|
import {
|
|
130
127
|
LearningPost
|
|
131
128
|
} from "./chunk-CUS3ORMD.js";
|
|
@@ -163,20 +160,18 @@ import {
|
|
|
163
160
|
getTimeOptions,
|
|
164
161
|
parseTimeOption
|
|
165
162
|
} from "./chunk-NWJSLIQ3.js";
|
|
163
|
+
import {
|
|
164
|
+
TrainingInfoGuideline
|
|
165
|
+
} from "./chunk-AHYOAFOU.js";
|
|
166
166
|
import {
|
|
167
167
|
DynamicFormEditor
|
|
168
|
-
} from "./chunk-
|
|
169
|
-
import "./chunk-V7KAHLW2.js";
|
|
168
|
+
} from "./chunk-NEJCZABQ.js";
|
|
170
169
|
import {
|
|
171
170
|
DynamicFormResponseItem
|
|
172
171
|
} from "./chunk-77H5BUYO.js";
|
|
173
172
|
import {
|
|
174
173
|
getDynamicFormDisplayValue
|
|
175
174
|
} from "./chunk-K7LTEKQS.js";
|
|
176
|
-
import {
|
|
177
|
-
DynamicForm,
|
|
178
|
-
createYupValidation
|
|
179
|
-
} from "./chunk-SQ3FYBJT.js";
|
|
180
175
|
import {
|
|
181
176
|
EmptyState
|
|
182
177
|
} from "./chunk-2EPKY2VT.js";
|
|
@@ -186,9 +181,6 @@ import {
|
|
|
186
181
|
import {
|
|
187
182
|
GhostPost
|
|
188
183
|
} from "./chunk-PAUEQXYG.js";
|
|
189
|
-
import {
|
|
190
|
-
AutocompleteTextfield
|
|
191
|
-
} from "./chunk-OOM522XP.js";
|
|
192
184
|
import {
|
|
193
185
|
DescriptionJsonRender
|
|
194
186
|
} from "./chunk-N3FMP27I.js";
|
|
@@ -202,13 +194,21 @@ import {
|
|
|
202
194
|
import {
|
|
203
195
|
DownloadCard
|
|
204
196
|
} from "./chunk-C6HO3IGE.js";
|
|
205
|
-
import {
|
|
206
|
-
DynamicFormField
|
|
207
|
-
} from "./chunk-NK6S7ZMB.js";
|
|
208
197
|
import "./chunk-3DZIX4CE.js";
|
|
209
198
|
import "./chunk-CBYIPRND.js";
|
|
210
199
|
import "./chunk-Z7WNKARH.js";
|
|
211
200
|
import "./chunk-D4U2ZV2A.js";
|
|
201
|
+
import "./chunk-V7KAHLW2.js";
|
|
202
|
+
import {
|
|
203
|
+
DynamicForm,
|
|
204
|
+
createYupValidation
|
|
205
|
+
} from "./chunk-SQ3FYBJT.js";
|
|
206
|
+
import {
|
|
207
|
+
DynamicFormField
|
|
208
|
+
} from "./chunk-NK6S7ZMB.js";
|
|
209
|
+
import {
|
|
210
|
+
AutocompleteTextfield
|
|
211
|
+
} from "./chunk-OOM522XP.js";
|
|
212
212
|
import {
|
|
213
213
|
DynamicFormProvider,
|
|
214
214
|
useDynamicForm
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DynamicFormEditor
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-V7KAHLW2.js";
|
|
5
|
-
import "../chunk-SQ3FYBJT.js";
|
|
6
|
-
import "../chunk-NK6S7ZMB.js";
|
|
3
|
+
} from "../chunk-NEJCZABQ.js";
|
|
7
4
|
import "../chunk-3DZIX4CE.js";
|
|
8
5
|
import "../chunk-CBYIPRND.js";
|
|
9
6
|
import "../chunk-Z7WNKARH.js";
|
|
10
7
|
import "../chunk-D4U2ZV2A.js";
|
|
8
|
+
import "../chunk-V7KAHLW2.js";
|
|
9
|
+
import "../chunk-SQ3FYBJT.js";
|
|
10
|
+
import "../chunk-NK6S7ZMB.js";
|
|
11
11
|
import "../chunk-FAL6S2XK.js";
|
|
12
12
|
import "../chunk-AELKCD6B.js";
|
|
13
13
|
import "../chunk-5XYPLDI5.js";
|
package/dist/molecules/index.js
CHANGED
|
@@ -51,9 +51,6 @@ import {
|
|
|
51
51
|
DatePicker
|
|
52
52
|
} from "../chunk-VVWQZK5L.js";
|
|
53
53
|
import "../chunk-2ISIAPFS.js";
|
|
54
|
-
import {
|
|
55
|
-
TrainingInfoGuideline
|
|
56
|
-
} from "../chunk-AHYOAFOU.js";
|
|
57
54
|
import {
|
|
58
55
|
LearningPost
|
|
59
56
|
} from "../chunk-CUS3ORMD.js";
|
|
@@ -81,18 +78,16 @@ import "../chunk-BXX3B3E4.js";
|
|
|
81
78
|
import "../chunk-NRPDVI76.js";
|
|
82
79
|
import "../chunk-2BPFXK4L.js";
|
|
83
80
|
import "../chunk-NWJSLIQ3.js";
|
|
81
|
+
import {
|
|
82
|
+
TrainingInfoGuideline
|
|
83
|
+
} from "../chunk-AHYOAFOU.js";
|
|
84
84
|
import {
|
|
85
85
|
DynamicFormEditor
|
|
86
|
-
} from "../chunk-
|
|
87
|
-
import "../chunk-V7KAHLW2.js";
|
|
86
|
+
} from "../chunk-NEJCZABQ.js";
|
|
88
87
|
import {
|
|
89
88
|
DynamicFormResponseItem
|
|
90
89
|
} from "../chunk-77H5BUYO.js";
|
|
91
90
|
import "../chunk-K7LTEKQS.js";
|
|
92
|
-
import {
|
|
93
|
-
DynamicForm,
|
|
94
|
-
createYupValidation
|
|
95
|
-
} from "../chunk-SQ3FYBJT.js";
|
|
96
91
|
import {
|
|
97
92
|
EmptyState
|
|
98
93
|
} from "../chunk-2EPKY2VT.js";
|
|
@@ -102,9 +97,6 @@ import {
|
|
|
102
97
|
import {
|
|
103
98
|
GhostPost
|
|
104
99
|
} from "../chunk-PAUEQXYG.js";
|
|
105
|
-
import {
|
|
106
|
-
AutocompleteTextfield
|
|
107
|
-
} from "../chunk-OOM522XP.js";
|
|
108
100
|
import {
|
|
109
101
|
DescriptionJsonRender
|
|
110
102
|
} from "../chunk-N3FMP27I.js";
|
|
@@ -115,13 +107,21 @@ import {
|
|
|
115
107
|
import {
|
|
116
108
|
DownloadCard
|
|
117
109
|
} from "../chunk-C6HO3IGE.js";
|
|
118
|
-
import {
|
|
119
|
-
DynamicFormField
|
|
120
|
-
} from "../chunk-NK6S7ZMB.js";
|
|
121
110
|
import "../chunk-3DZIX4CE.js";
|
|
122
111
|
import "../chunk-CBYIPRND.js";
|
|
123
112
|
import "../chunk-Z7WNKARH.js";
|
|
124
113
|
import "../chunk-D4U2ZV2A.js";
|
|
114
|
+
import "../chunk-V7KAHLW2.js";
|
|
115
|
+
import {
|
|
116
|
+
DynamicForm,
|
|
117
|
+
createYupValidation
|
|
118
|
+
} from "../chunk-SQ3FYBJT.js";
|
|
119
|
+
import {
|
|
120
|
+
DynamicFormField
|
|
121
|
+
} from "../chunk-NK6S7ZMB.js";
|
|
122
|
+
import {
|
|
123
|
+
AutocompleteTextfield
|
|
124
|
+
} from "../chunk-OOM522XP.js";
|
|
125
125
|
import "../chunk-FAL6S2XK.js";
|
|
126
126
|
import "../chunk-AELKCD6B.js";
|
|
127
127
|
import "../chunk-5XYPLDI5.js";
|
package/package.json
CHANGED
|
@@ -12,6 +12,8 @@ export interface HeaderProps {
|
|
|
12
12
|
rawUrl: string,
|
|
13
13
|
options: { disposition: 'inline' | 'attachment' }
|
|
14
14
|
) => string | Promise<string>;
|
|
15
|
+
/** '영상' 버튼 우측에 렌더되는 소비자 정의 액션 슬롯. */
|
|
16
|
+
actions?: React.ReactNode;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
function PdfIcon(): React.ReactElement {
|
|
@@ -59,6 +61,7 @@ export function Header({
|
|
|
59
61
|
hasScript,
|
|
60
62
|
onOpenReplay,
|
|
61
63
|
onResolveMediaUrl,
|
|
64
|
+
actions,
|
|
62
65
|
}: HeaderProps): React.ReactElement {
|
|
63
66
|
// PDF 산출물은 embedLink(AI 리포트 PDF). trainingLogURL 은 대화 스크립트 JSON 이므로 PDF 가 아니다.
|
|
64
67
|
const pdfHref = detail.embedLink;
|
|
@@ -162,6 +165,7 @@ export function Header({
|
|
|
162
165
|
<span style={{ whiteSpace: 'nowrap' }}>영상</span>
|
|
163
166
|
</Button>
|
|
164
167
|
) : null}
|
|
168
|
+
{actions ?? null}
|
|
165
169
|
</Flex>
|
|
166
170
|
</Flex>
|
|
167
171
|
</Box>
|
|
@@ -114,7 +114,7 @@ export function StepDetail({
|
|
|
114
114
|
</Box>
|
|
115
115
|
) : null}
|
|
116
116
|
|
|
117
|
-
{step.improve || step.example
|
|
117
|
+
{step.improve || step.example ? (
|
|
118
118
|
<Box pt="3">
|
|
119
119
|
<Flex direction="column" gap="3">
|
|
120
120
|
{step.improve ? <RubricField label="개선점" value={step.improve} /> : null}
|
|
@@ -141,29 +141,6 @@ export function StepDetail({
|
|
|
141
141
|
</Box>
|
|
142
142
|
</Box>
|
|
143
143
|
) : null}
|
|
144
|
-
{step.idealExample ? (
|
|
145
|
-
<Box
|
|
146
|
-
p="2"
|
|
147
|
-
style={{
|
|
148
|
-
borderRadius: 'var(--radius-2)',
|
|
149
|
-
background: 'var(--gray-a2)',
|
|
150
|
-
}}
|
|
151
|
-
>
|
|
152
|
-
<Typo as="p" color="gray" variant="body" weight="medium">
|
|
153
|
-
모범 예시
|
|
154
|
-
</Typo>
|
|
155
|
-
<Box mt="1" style={{ maxWidth: '65ch' }}>
|
|
156
|
-
<Typo
|
|
157
|
-
as="p"
|
|
158
|
-
color="gray"
|
|
159
|
-
style={{ whiteSpace: 'pre-line' }}
|
|
160
|
-
variant="body"
|
|
161
|
-
>
|
|
162
|
-
{step.idealExample}
|
|
163
|
-
</Typo>
|
|
164
|
-
</Box>
|
|
165
|
-
</Box>
|
|
166
|
-
) : null}
|
|
167
144
|
</Flex>
|
|
168
145
|
</Box>
|
|
169
146
|
) : null}
|
|
@@ -22,6 +22,8 @@ export interface RpSessionDetailProps {
|
|
|
22
22
|
) => string | Promise<string>;
|
|
23
23
|
onError?: (error: unknown, context: Record<string, unknown>) => void;
|
|
24
24
|
sectionScrollMarginTop?: string;
|
|
25
|
+
/** 헤더 액션 행(PDF 다운로드·영상)의 '영상' 버튼 우측에 렌더되는 소비자 정의 액션 슬롯(예: website 공유하기 버튼). */
|
|
26
|
+
headerActions?: React.ReactNode;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
/* ───────────────────────── Skeleton ───────────────────────── */
|
|
@@ -118,6 +120,7 @@ export function RpSessionDetail({
|
|
|
118
120
|
onResolveMediaUrl,
|
|
119
121
|
onError: _onError,
|
|
120
122
|
sectionScrollMarginTop = '120px',
|
|
123
|
+
headerActions,
|
|
121
124
|
}: RpSessionDetailProps): React.ReactElement {
|
|
122
125
|
const [replayOpen, setReplayOpen] = useState(false);
|
|
123
126
|
|
|
@@ -143,6 +146,7 @@ export function RpSessionDetail({
|
|
|
143
146
|
<Box py="6">
|
|
144
147
|
<Flex direction="column" gap={{ initial: '5', md: '7' }}>
|
|
145
148
|
<Header
|
|
149
|
+
actions={headerActions}
|
|
146
150
|
detail={detail}
|
|
147
151
|
hasScript={hasScript}
|
|
148
152
|
onOpenReplay={() => {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/roleplay/rp-session-detail.tsx"],"sourcesContent":["'use client';\n\nimport React, { useMemo, useState } from 'react';\nimport { Box, Card, Flex, Heading, Progress, Skeleton, Typo } from '../../atoms';\nimport type { RpSessionDetailData, RpSessionHistoryItem, RpSessionScript } from './types';\nimport { parseReportData } from './utils/report-parse';\nimport { computeSpeechShare } from './utils/session-utils';\nimport { Content } from './parts/content';\nimport { Header } from './parts/header';\nimport { SessionReplayDialog } from './parts/session-replay-dialog';\n\n/* ───────────────────────── Public contract ───────────────────────── */\n\nexport interface RpSessionDetailProps {\n detail: RpSessionDetailData;\n history: RpSessionHistoryItem[];\n isLoading?: boolean;\n script?: RpSessionScript | null;\n onResolveMediaUrl?: (\n rawUrl: string,\n options: { disposition: 'inline' | 'attachment' }\n ) => string | Promise<string>;\n onError?: (error: unknown, context: Record<string, unknown>) => void;\n sectionScrollMarginTop?: string;\n}\n\n/* ───────────────────────── Skeleton ───────────────────────── */\n\nfunction RpSessionDetailSkeleton(): React.ReactElement {\n return (\n <Box py=\"6\">\n <Flex direction=\"column\" gap=\"6\">\n <Box>\n <Skeleton>\n <Heading size=\"7\">롤플레잉 세션 제목 로딩 중</Heading>\n </Skeleton>\n <Box mt=\"2\">\n <Skeleton>\n <Typo as=\"p\" variant=\"body\">\n 날짜 · 소요 시간이 로딩되는 영역입니다\n </Typo>\n </Skeleton>\n </Box>\n </Box>\n <section>\n <Skeleton>\n <Heading size=\"5\">종합 점수</Heading>\n </Skeleton>\n <Box mt=\"3\">\n <Card variant=\"surface\">\n <Flex align=\"center\" direction=\"column\" gap=\"2\" py=\"3\">\n <Skeleton>\n <Heading size=\"7\">00</Heading>\n </Skeleton>\n </Flex>\n </Card>\n </Box>\n </section>\n <section>\n <Skeleton>\n <Heading size=\"5\">평가 지표 요약</Heading>\n </Skeleton>\n <Box mt=\"3\">\n <Flex direction=\"column\" gap=\"3\">\n {[0, 1, 2].map((i) => (\n <Skeleton key={i}>\n <Typo as=\"p\" variant=\"body\">\n 평가 지표 항목이 로딩되는 중입니다\n </Typo>\n </Skeleton>\n ))}\n </Flex>\n </Box>\n </section>\n </Flex>\n </Box>\n );\n}\n\n/* ───────────────────────── Analyzing state ───────────────────────── */\n\nfunction AnalyzingState(): React.ReactElement {\n return (\n <Flex\n align=\"center\"\n direction=\"column\"\n justify=\"center\"\n style={{\n border: '1px dashed var(--gray-6)',\n borderRadius: 'var(--radius-3)',\n background: 'var(--gray-a1)',\n padding: '40px 24px',\n textAlign: 'center',\n }}\n >\n <Heading size={{ initial: '4', md: '5' }} weight=\"bold\">\n AI 분석 중입니다\n </Heading>\n <Box mt=\"2\" style={{ maxWidth: '480px' }}>\n <Typo as=\"p\" variant=\"body\">\n 대화와 산출물은 저장되었고, AI가 지표별 근거와 코칭을 생성하는 중입니다.\n </Typo>\n </Box>\n <Box mt=\"4\" style={{ width: '100%', maxWidth: '280px' }}>\n <Progress size=\"2\" value={66} />\n </Box>\n </Flex>\n );\n}\n\n/* ───────────────────────── Main component ───────────────────────── */\n\nexport function RpSessionDetail({\n detail,\n history,\n isLoading = false,\n script,\n onResolveMediaUrl,\n onError: _onError,\n sectionScrollMarginTop = '120px',\n}: RpSessionDetailProps): React.ReactElement {\n const [replayOpen, setReplayOpen] = useState(false);\n\n // script 미전달 시 발화량 표시 생략. 전달 시 script로 계산.\n const speechShare = useMemo(\n () => (script !== null && script !== undefined ? computeSpeechShare(script.items) : null),\n [script],\n );\n\n const report = useMemo(\n () => parseReportData(detail.reportData, detail.guideline, detail.displayMeta),\n [detail.reportData, detail.guideline, detail.displayMeta],\n );\n\n const hasScript = script !== null && script !== undefined;\n const isAnalyzing = detail.status === 'analyzing';\n\n if (isLoading) {\n return <RpSessionDetailSkeleton />;\n }\n\n return (\n <Box py=\"6\">\n <Flex direction=\"column\" gap={{ initial: '5', md: '7' }}>\n <Header\n detail={detail}\n hasScript={hasScript}\n onOpenReplay={() => {\n setReplayOpen(true);\n }}\n onResolveMediaUrl={onResolveMediaUrl}\n />\n\n {isAnalyzing ? (\n <AnalyzingState />\n ) : (\n <Content\n detail={detail}\n history={history}\n report={report}\n scrollMarginTop={sectionScrollMarginTop}\n speechShare={speechShare}\n />\n )}\n </Flex>\n\n <SessionReplayDialog\n detail={detail}\n onOpenChange={setReplayOpen}\n onResolveMediaUrl={onResolveMediaUrl}\n open={replayOpen}\n script={script}\n />\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/roleplay/parts/step-detail.tsx"],"sourcesContent":["'use client';\n\nimport { Box, Flex, Progress, Typo } from '../../../atoms';\nimport type { RpReportStep } from '../utils/report-parse';\nimport {\n stepCode,\n stepColor,\n stepGradeLabel,\n stepRatio,\n stepScoreText,\n stepVars,\n} from '../utils/session-utils';\n\nexport interface StepDetailProps {\n step: RpReportStep;\n scrollMarginTop?: string;\n}\n\nfunction RubricField({\n label,\n value,\n}: {\n label: string;\n value: string;\n}): React.ReactElement {\n return (\n <Box>\n <Typo as=\"p\" variant=\"body\" weight=\"medium\">\n {label}\n </Typo>\n <Box mt=\"1\" style={{ maxWidth: '65ch' }}>\n <Typo as=\"p\" variant=\"body\">\n {value}\n </Typo>\n </Box>\n </Box>\n );\n}\n\nexport function StepDetail({\n step,\n scrollMarginTop = '120px',\n}: StepDetailProps): React.ReactElement {\n const qv = stepVars(step);\n const ratio = stepRatio(step);\n const scoreText = stepScoreText(step);\n const gradeLabel = stepGradeLabel(step);\n\n return (\n <Box id={`step-${step.key}`} style={{ scrollMarginTop }}>\n <Flex align=\"center\" gap=\"2\" justify=\"between\" mb=\"1\">\n <Box style={{ minWidth: 0 }}>\n <Typo as=\"span\" color=\"gray\" mono variant=\"body\">\n {stepCode(step)}\n </Typo>\n <Typo as=\"p\" variant=\"subtitle\" weight=\"bold\">\n {step.label}\n </Typo>\n </Box>\n <Flex align=\"end\" direction=\"column\" gap=\"1\" style={{ flexShrink: 0 }}>\n {scoreText !== null ? (\n <Typo\n as=\"span\"\n mono\n style={{ color: qv.fg }}\n variant=\"subtitle\"\n weight=\"bold\"\n >\n {scoreText}\n </Typo>\n ) : null}\n {gradeLabel !== null ? (\n <Typo\n as=\"span\"\n mono\n style={{\n display: 'inline-block',\n borderRadius: 'var(--radius-2)',\n border: `1px solid ${qv.border}`,\n background: qv.bg,\n color: qv.fg,\n padding: '1px 8px',\n }}\n variant=\"body\"\n weight=\"medium\"\n >\n {gradeLabel}\n </Typo>\n ) : null}\n </Flex>\n </Flex>\n\n {ratio !== null ? (\n <Box mb=\"3\" mt=\"2\">\n <Progress color={stepColor(step)} size=\"2\" value={ratio * 100} />\n </Box>\n ) : null}\n\n {step.description ? (\n <Box mb=\"3\" mt={ratio !== null ? '0' : '2'} style={{ maxWidth: '65ch' }}>\n <Typo as=\"p\" color=\"gray\" variant=\"body\">\n {step.description}\n </Typo>\n </Box>\n ) : null}\n\n <Flex direction=\"column\" gap=\"0\">\n {step.basis || step.issue ? (\n <Box pb=\"3\" style={{ borderBottom: '1px solid var(--gray-a4)' }}>\n <Flex direction=\"column\" gap=\"3\">\n {step.basis ? <RubricField label=\"근거\" value={step.basis} /> : null}\n {step.issue ? <RubricField label=\"아쉬운 점\" value={step.issue} /> : null}\n </Flex>\n </Box>\n ) : null}\n\n {step.improve || step.example || step.idealExample ? (\n <Box pt=\"3\">\n <Flex direction=\"column\" gap=\"3\">\n {step.improve ? <RubricField label=\"개선점\" value={step.improve} /> : null}\n {step.example ? (\n <Box\n p=\"2\"\n style={{\n borderRadius: 'var(--radius-2)',\n background: 'var(--accent-a2)',\n }}\n >\n <Typo\n as=\"p\"\n style={{ color: 'var(--accent-11)' }}\n variant=\"body\"\n weight=\"medium\"\n >\n 예시 스크립트\n </Typo>\n <Box mt=\"1\" style={{ maxWidth: '65ch' }}>\n <Typo as=\"p\" style={{ color: 'var(--accent-11)' }} variant=\"body\">\n {step.example}\n </Typo>\n </Box>\n </Box>\n ) : null}\n {step.idealExample ? (\n <Box\n p=\"2\"\n style={{\n borderRadius: 'var(--radius-2)',\n background: 'var(--gray-a2)',\n }}\n >\n <Typo as=\"p\" color=\"gray\" variant=\"body\" weight=\"medium\">\n 모범 예시\n </Typo>\n <Box mt=\"1\" style={{ maxWidth: '65ch' }}>\n <Typo\n as=\"p\"\n color=\"gray\"\n style={{ whiteSpace: 'pre-line' }}\n variant=\"body\"\n >\n {step.idealExample}\n </Typo>\n </Box>\n </Box>\n ) : null}\n </Flex>\n </Box>\n ) : null}\n </Flex>\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/roleplay/parts/header.tsx"],"sourcesContent":["'use client';\n\nimport { Badge, Box, Button, Flex, Heading, Typo } from '../../../atoms';\nimport type { RpSessionDetailData } from '../types';\nimport { formatDate, formatDuration, statusLabelOf } from '../utils/session-utils';\n\nexport interface HeaderProps {\n detail: RpSessionDetailData;\n hasScript: boolean;\n onOpenReplay: () => void;\n onResolveMediaUrl?: (\n rawUrl: string,\n options: { disposition: 'inline' | 'attachment' }\n ) => string | Promise<string>;\n}\n\nfunction PdfIcon(): React.ReactElement {\n return (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height=\"13\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"13\"\n >\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 3v5h5\" />\n <path d=\"M12 12v5\" />\n <path d=\"M9.5 14.5 12 17l2.5-2.5\" />\n </svg>\n );\n}\n\nfunction VideoIcon(): React.ReactElement {\n return (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height=\"13\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"13\"\n >\n <rect height=\"12\" rx=\"2\" width=\"13\" x=\"2\" y=\"6\" />\n <path d=\"m15 10 6-3v10l-6-3z\" />\n </svg>\n );\n}\n\nexport function Header({\n detail,\n hasScript,\n onOpenReplay,\n onResolveMediaUrl,\n}: HeaderProps): React.ReactElement {\n // PDF 산출물은 embedLink(AI 리포트 PDF). trainingLogURL 은 대화 스크립트 JSON 이므로 PDF 가 아니다.\n const pdfHref = detail.embedLink;\n const hasReplayMedia = Boolean(\n detail.trainingVideoURL || detail.trainingAudioURL\n );\n\n const handlePdfClick = (): void => {\n if (!pdfHref || !onResolveMediaUrl) return;\n void Promise.resolve(\n onResolveMediaUrl(pdfHref, { disposition: 'attachment' })\n ).then((url) => {\n window.open(url, '_blank');\n });\n };\n\n const replayActive = hasScript && hasReplayMedia;\n\n return (\n <Box>\n <Flex\n align={{ md: 'start' }}\n direction={{ initial: 'column', md: 'row' }}\n gap=\"4\"\n justify=\"between\"\n >\n <Box style={{ minWidth: 0 }}>\n <Flex align=\"center\" gap=\"2\" mb=\"2\" wrap=\"wrap\">\n <Badge color=\"neutral\" size=\"small\" variant=\"soft\">\n {statusLabelOf(detail.status)}\n </Badge>\n <Typo as=\"span\" color=\"gray\" variant=\"body\">\n {detail.trainingSessionNum}회차\n {detail.characterTitle ? ` · ${detail.characterTitle}` : ''}\n </Typo>\n </Flex>\n <Heading\n size={{ initial: '5', md: '7' }}\n style={{ textWrap: 'balance' }}\n weight=\"bold\"\n >\n {detail.scenarioTitle ?? '롤플레잉 세션'}\n </Heading>\n <Typo as=\"p\" color=\"gray\" mono mt=\"1\" variant=\"body\">\n {formatDate(detail.createdAt)} · {formatDuration(detail.trainingTime)}\n </Typo>\n </Box>\n <Flex\n gap=\"2\"\n justify={{ initial: 'start', md: 'end' }}\n style={{ flexShrink: 0 }}\n wrap=\"wrap\"\n >\n {onResolveMediaUrl ? (\n <Button\n color=\"gray\"\n disabled={!pdfHref}\n onClick={pdfHref ? handlePdfClick : undefined}\n size={{ initial: 'small', md: 'medium' }}\n title={pdfHref ? undefined : '산출물 없음'}\n type=\"button\"\n variant=\"outline\"\n >\n <PdfIcon />\n <span style={{ whiteSpace: 'nowrap' }}>PDF 다운로드</span>\n </Button>\n ) : (\n <Button\n asChild={Boolean(pdfHref)}\n color=\"gray\"\n disabled={!pdfHref}\n size={{ initial: 'small', md: 'medium' }}\n title={pdfHref ? undefined : '산출물 없음'}\n type=\"button\"\n variant=\"outline\"\n >\n {pdfHref ? (\n <a href={pdfHref} rel=\"noopener noreferrer\" target=\"_blank\">\n <PdfIcon />\n <span style={{ whiteSpace: 'nowrap' }}>PDF 다운로드</span>\n </a>\n ) : (\n <span>\n <PdfIcon />\n <span style={{ whiteSpace: 'nowrap' }}>PDF 다운로드</span>\n </span>\n )}\n </Button>\n )}\n {hasScript ? (\n <Button\n color=\"gray\"\n disabled={!replayActive}\n onClick={onOpenReplay}\n size={{ initial: 'small', md: 'medium' }}\n title={replayActive ? undefined : '다시보기 없음'}\n type=\"button\"\n variant=\"outline\"\n >\n <VideoIcon />\n <span style={{ whiteSpace: 'nowrap' }}>영상</span>\n </Button>\n ) : null}\n </Flex>\n </Flex>\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|
|
File without changes
|