@edu-tosel/design 1.0.184 → 1.0.185
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/_test/asset/mock/academies.d.ts +5 -0
- package/_test/asset/mock/academies.js +52 -0
- package/_test/asset/mock/academy.d.ts +28 -0
- package/_test/asset/mock/academy.js +419 -0
- package/_test/asset/mock/chartData.d.ts +6 -0
- package/_test/asset/mock/chartData.js +104 -0
- package/_test/asset/mock/index.d.ts +3 -0
- package/_test/asset/mock/index.js +3 -0
- package/_test/interface/Exam.d.ts +56 -0
- package/_test/interface/Exam.js +55 -0
- package/_test/interface/Property.d.ts +3 -0
- package/_test/interface/Property.js +9 -0
- package/_test/interface/index.d.ts +2 -0
- package/_test/interface/index.js +2 -0
- package/asset/SVG.d.ts +2 -0
- package/asset/SVG.js +2 -0
- package/asset/SVG.tsx +2 -0
- package/asset/svg/HallofFame.d.ts +4 -0
- package/asset/svg/HallofFame.js +4 -0
- package/asset/svg/HallofFame.tsx +179 -0
- package/hook/index.d.ts +1 -0
- package/hook/index.js +1 -0
- package/hook/usePageLoaded.d.ts +4 -0
- package/hook/usePageLoaded.js +21 -0
- package/layout/template/Archive/Header.js +4 -0
- package/layout/template/Ticket/Layout.d.ts +4 -1
- package/layout/template/Ticket/Layout.js +4 -3
- package/layout/template/Ticket/Ticket.js +2 -2
- package/layout/template/Ticket/academy/Academy.d.ts +19 -0
- package/layout/template/Ticket/academy/Academy.js +129 -0
- package/layout/template/Ticket/academy/AcademyTicket.d.ts +20 -0
- package/layout/template/Ticket/academy/AcademyTicket.js +55 -0
- package/layout/template/Ticket/index.d.ts +5 -0
- package/layout/template/Ticket/index.js +4 -0
- package/layout/template/Transcript/design/Transcript.d.ts +6 -0
- package/layout/template/Transcript/design/Transcript.design.js +199 -13
- package/package.json +2 -1
- package/style/size.js +1 -1
- package/tailwind.config.ts +6 -0
- package/util/copyToClipboard.d.ts +1 -0
- package/util/copyToClipboard.js +16 -0
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/version.txt +1 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import moment from "moment-timezone";
|
|
3
|
+
import { LevelString } from "../../../../_test/interface";
|
|
4
|
+
import GroupTicket from "./AcademyTicket";
|
|
5
|
+
import React, { useRef, useState } from "react";
|
|
6
|
+
import { Label, Row, TableCard } from "@edu-tosel/design";
|
|
7
|
+
import { cn } from "../../../../util";
|
|
8
|
+
import { HiOutlinePrinter } from "react-icons/hi2";
|
|
9
|
+
import { HiOutlineTableCells } from "react-icons/hi2";
|
|
10
|
+
import { useReactToPrint } from "react-to-print";
|
|
11
|
+
export default function Academy({ applicationsData, examDate, examName, }) {
|
|
12
|
+
const container = {
|
|
13
|
+
displays: "flex items-center justify-center gap-6",
|
|
14
|
+
};
|
|
15
|
+
const btn = {
|
|
16
|
+
displays: "flex items-center justify-center gap-2",
|
|
17
|
+
rounded: "rounded-lg",
|
|
18
|
+
backgrounds: "bg-white/50",
|
|
19
|
+
texts: " text-green-dark font-semibold",
|
|
20
|
+
shadows: "shadow-main",
|
|
21
|
+
sizes: "w-1/3 h-full px-2.5",
|
|
22
|
+
cursors: "cursor-pointer",
|
|
23
|
+
};
|
|
24
|
+
const [selectedStudent, setSelectedStudent] = useState(null);
|
|
25
|
+
const formattedData = Object.values(applicationsData ?? {})
|
|
26
|
+
.filter((app) => app.applicationId !== null)
|
|
27
|
+
.slice(0, -1);
|
|
28
|
+
const handleSelectStudent = (student) => {
|
|
29
|
+
setSelectedStudent(toRender(student));
|
|
30
|
+
};
|
|
31
|
+
const ref = useRef(null);
|
|
32
|
+
const allTicketsRef = useRef(null);
|
|
33
|
+
const handlePrint = useReactToPrint({
|
|
34
|
+
content: () => ref.current,
|
|
35
|
+
});
|
|
36
|
+
const ticketRefs = useRef(formattedData.map(() => React.createRef()));
|
|
37
|
+
const printAllTickets = useReactToPrint({
|
|
38
|
+
content: () => allTicketsRef.current,
|
|
39
|
+
});
|
|
40
|
+
console.log(allTicketsRef.current);
|
|
41
|
+
return (_jsx(_Fragment, { children: _jsx("div", { className: "w-full min-h-screen flex items-center justify-center bg-gray-light", children: _jsxs("div", { className: cn(container), children: [_jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "w-full h-15 bg-green-dark rounded-lg flex justify-between items-center p-5 text-white text-md shadow-main", children: [_jsx("div", { className: "font-semibold", children: examName }), _jsx("div", { children: "\uACE0\uC0AC\uC7A5 \uC2DC\uD5D8" })] }), _jsx(TableCard, { dataField: dataField, dataSet: {
|
|
42
|
+
items: formattedData ?? [],
|
|
43
|
+
renderItem: (application) => (_jsx(Row.Card, { item: toRender(application), dataField: dataField, onClick: () => handleSelectStudent(application) })),
|
|
44
|
+
} }), _jsxs("div", { className: "flex w-full h-12 gap-3", children: [_jsxs("div", { className: cn(btn), onClick: printAllTickets, children: [_jsx(HiOutlinePrinter, { className: "text-2xl" }), _jsx("div", { className: "text-center", children: "\uC804\uCCB4 \uC218\uD5D8\uD45C \uCD9C\uB825" })] }), _jsxs("div", { className: cn(btn), onClick: handlePrint, children: [_jsx(HiOutlinePrinter, { className: "text-2xl" }), _jsx("div", { className: "text-center", children: "\uD604\uC7AC \uD559\uC0DD \uCD9C\uB825" })] }), _jsxs("div", { className: cn(btn), children: [_jsx(HiOutlineTableCells, { className: "text-2xl" }), _jsx("div", { className: "text-center", children: "\uC5D1\uC140 \uB2E4\uC6B4\uB85C\uB4DC" })] })] })] }), _jsx("div", { ref: allTicketsRef, className: "opacity-0", children: formattedData.map((student, index) => (_jsx(GroupTicket, { ref: ticketRefs.current[index], props: {
|
|
45
|
+
exam: {
|
|
46
|
+
title: examName,
|
|
47
|
+
hall: student.examHallName ?? "",
|
|
48
|
+
room: student.examHallRoomName ?? "",
|
|
49
|
+
date: examDate,
|
|
50
|
+
address: "",
|
|
51
|
+
startedAt: moment(new Date()).unix(),
|
|
52
|
+
endedAt: moment(new Date()).unix(),
|
|
53
|
+
},
|
|
54
|
+
name: student.name ?? "",
|
|
55
|
+
birthday: student.birthday ?? "",
|
|
56
|
+
profileImageUrl: "",
|
|
57
|
+
level: LevelString[student.level ?? "PS"],
|
|
58
|
+
code: student.code ?? "",
|
|
59
|
+
} }, student.applicationId))) }), _jsx(GroupTicket, { ref: ref, props: {
|
|
60
|
+
exam: {
|
|
61
|
+
title: examName,
|
|
62
|
+
hall: selectedStudent?.examHallName ?? "",
|
|
63
|
+
room: selectedStudent?.examHallRoomName ?? "",
|
|
64
|
+
date: examDate,
|
|
65
|
+
address: "",
|
|
66
|
+
startedAt: moment(new Date()).unix(),
|
|
67
|
+
endedAt: moment(new Date()).unix(),
|
|
68
|
+
},
|
|
69
|
+
name: selectedStudent?.name ?? "",
|
|
70
|
+
birthday: selectedStudent?.birthday ?? "",
|
|
71
|
+
profileImageUrl: "",
|
|
72
|
+
level: LevelString[selectedStudent?.level ?? "PS"],
|
|
73
|
+
code: selectedStudent?.code ?? "",
|
|
74
|
+
} }), _jsxs("div", { className: "relative w-48 flex flex-row md:flex-col md:h-[700px] gap-4 h-full justify-start mt-5 items-center", children: [_jsxs("div", { className: "sm:absolute hidden sm:flex flex-col gap-4 left-0 top-36", children: [_jsxs("div", { className: "flex-col font-pretendard-var flex", children: [_jsxs("div", { className: "flex flex-row font-bold text-base leading-tight", children: [_jsx("div", { className: "text-crimson-burgundy", children: "OMR \uC791\uC131" }), _jsx("div", { className: "text-gray-dark", children: ", \uC5F0\uC2B5\uD558\uC168\uB098\uC694?" })] }), _jsx("div", { className: "text-gray-dark font-medium text-xs break-keep", children: "\uB9C8\uD0B9\uD39C\uC73C\uB85C \uC791\uC131\uBC95\uC744 \uBBF8\uB9AC \uC5F0\uC2B5\uD574\uBCF4\uC138\uC694!" })] }), _jsx(Label.Button, { title: "OMR \uC778\uC1C4", onClick: () => { }, option: {
|
|
75
|
+
width: "sm",
|
|
76
|
+
height: "xs",
|
|
77
|
+
background: "bg-green-dark",
|
|
78
|
+
text: "text-white font-pretendard-var font-medium",
|
|
79
|
+
} })] }), _jsxs("div", { className: "sm:absolute flex flex-col gap-4 left-0 top-80", children: [_jsxs("div", { className: "flex-col font-pretendard-var hidden sm:flex", children: [_jsxs("div", { className: "flex flex-row font-bold text-base leading-tight", children: [_jsx("div", { className: "text-crimson-burgundy", children: "\uACE0\uC0AC\uC7A5 \uC704\uCE58" }), _jsx("div", { className: "text-gray-dark", children: "\uB97C \uD655\uC778\uD574\uC8FC\uC138\uC694" })] }), _jsx("div", { className: "text-gray-dark font-medium text-xs break-keep", children: selectedStudent?.examHallName })] }), _jsx(Label.Button, { title: "\uC9C0\uB3C4\uC5D0\uC11C \uBCF4\uAE30", onClick: () => {
|
|
80
|
+
window.open(`https://map.kakao.com/?map_type=TYPE_MAP&itemId=168362793&q=${selectedStudent?.examHallName}&urlLevel=3&urlX=507920&urlY=1136302`);
|
|
81
|
+
}, option: {
|
|
82
|
+
width: "sm",
|
|
83
|
+
height: "xs",
|
|
84
|
+
background: "bg-green-dark",
|
|
85
|
+
text: "text-white font-pretendard-var font-medium",
|
|
86
|
+
} })] }), _jsxs("div", { className: "sm:absolute flex flex-col gap-4 left-0 top-128", children: [_jsxs("div", { className: "flex-col font-pretendard-var hidden sm:flex", children: [_jsxs("div", { className: "flex flex-row font-bold text-base leading-tight", children: [_jsx("div", { className: "text-crimson-burgundy", children: "\uC900\uBE44\uBB3C" }), _jsx("div", { className: "text-gray-dark", children: "\uB3C4 \uD655\uC778\uD574\uC8FC\uC138\uC694" })] }), _jsx("div", { className: "text-gray-dark font-medium text-xs break-keep", children: "\uB9C8\uD0B9\uD39C\uC73C\uB85C \uC791\uC131\uBC95\uC744 \uBBF8\uB9AC \uC5F0\uC2B5\uD574\uBCF4\uC138\uC694!" })] }), _jsx(Label.Button, { title: "\uC2DC\uD5D8 \uADDC\uC815 \uD655\uC778", onClick: () => { }, option: {
|
|
87
|
+
width: "sm",
|
|
88
|
+
height: "xs",
|
|
89
|
+
background: "bg-green-dark",
|
|
90
|
+
text: "text-white font-pretendard-var font-medium",
|
|
91
|
+
} })] })] })] }) }) }));
|
|
92
|
+
}
|
|
93
|
+
function toRender(obj) {
|
|
94
|
+
return {
|
|
95
|
+
...obj,
|
|
96
|
+
levelString: LevelString[obj.level ?? "PS"],
|
|
97
|
+
formattedBirthday: formatDateToYYMMDD(obj.birthday),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function formatDateToYYMMDD(dateString) {
|
|
101
|
+
if (!dateString) {
|
|
102
|
+
console.error("Invalid date string provided");
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
105
|
+
const [year, month, day] = dateString.split("-");
|
|
106
|
+
return year.slice(2) + month + day;
|
|
107
|
+
}
|
|
108
|
+
const dataField = {
|
|
109
|
+
name: {
|
|
110
|
+
title: "이름",
|
|
111
|
+
size: 20,
|
|
112
|
+
},
|
|
113
|
+
formattedBirthday: {
|
|
114
|
+
title: "생년월일",
|
|
115
|
+
size: 25,
|
|
116
|
+
},
|
|
117
|
+
levelString: {
|
|
118
|
+
title: "레벨",
|
|
119
|
+
size: 30,
|
|
120
|
+
},
|
|
121
|
+
code: {
|
|
122
|
+
title: "수험번호",
|
|
123
|
+
size: 30,
|
|
124
|
+
},
|
|
125
|
+
examHallRoomName: {
|
|
126
|
+
title: "고사실",
|
|
127
|
+
size: 20,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface TicketProps {
|
|
2
|
+
exam: {
|
|
3
|
+
title: string;
|
|
4
|
+
hall: string;
|
|
5
|
+
room: string;
|
|
6
|
+
date: string;
|
|
7
|
+
address: string;
|
|
8
|
+
startedAt: number;
|
|
9
|
+
endedAt: number;
|
|
10
|
+
};
|
|
11
|
+
name: string;
|
|
12
|
+
profileImageUrl?: string;
|
|
13
|
+
birthday: string;
|
|
14
|
+
level: string;
|
|
15
|
+
code: string;
|
|
16
|
+
}
|
|
17
|
+
declare const _default: import("react").ForwardRefExoticComponent<{
|
|
18
|
+
props: TicketProps;
|
|
19
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
20
|
+
export default _default;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { cn } from "../../../../util";
|
|
4
|
+
import moment from "moment-timezone";
|
|
5
|
+
function AcademyTicket({ props }, ref) {
|
|
6
|
+
const { title, date, hall, room, startedAt, endedAt } = props.exam;
|
|
7
|
+
//수험번호 섹션 디자인을 위한 배열
|
|
8
|
+
const numberArray = props.code.split("").map(Number);
|
|
9
|
+
numberArray.splice(3, 0, null);
|
|
10
|
+
numberArray.splice(7, 0, null);
|
|
11
|
+
const container = {
|
|
12
|
+
sizes: "w-full max-w-[340px] xs:w-[340px] h-[700px] flex flex-col justify-start",
|
|
13
|
+
spacings: "p-5 print:m-10",
|
|
14
|
+
boundaries: "border-1 border-gray-medium shadow-main",
|
|
15
|
+
backgrounds: "bg-white",
|
|
16
|
+
};
|
|
17
|
+
const logoWrapper = {
|
|
18
|
+
displays: "flex flex-row justify-between w-full mb-3",
|
|
19
|
+
};
|
|
20
|
+
const svgController = {
|
|
21
|
+
sizes: "h-8",
|
|
22
|
+
};
|
|
23
|
+
const titleDivider = {
|
|
24
|
+
sizes: "w-full h-0.5",
|
|
25
|
+
backgrounds: "bg-gradient-to-r from-crimson-burgundy to-green-dark",
|
|
26
|
+
};
|
|
27
|
+
const cellWrapper = {
|
|
28
|
+
displays: "flex flex-row",
|
|
29
|
+
sizes: "w-full",
|
|
30
|
+
boundaries: "border-1 border-gray-medium",
|
|
31
|
+
};
|
|
32
|
+
const cellTitleLarge = {
|
|
33
|
+
displays: "flex justify-center items-center shrink-0",
|
|
34
|
+
sizes: "w-21 h-6",
|
|
35
|
+
textstyles: "text-2xs font-medium",
|
|
36
|
+
backgrounds: "bg-gray-light",
|
|
37
|
+
};
|
|
38
|
+
const cellTitleSmall = {
|
|
39
|
+
displays: "flex justify-center items-center shrink-0",
|
|
40
|
+
sizes: "w-16 h-6",
|
|
41
|
+
textstyles: "text-2xs font-medium",
|
|
42
|
+
backgrounds: "bg-gray-light",
|
|
43
|
+
};
|
|
44
|
+
const cellText = {
|
|
45
|
+
sizes: "w-full",
|
|
46
|
+
displays: "flex justify-center items-center",
|
|
47
|
+
textstyles: "text-2xs font-medium text-black",
|
|
48
|
+
};
|
|
49
|
+
return (_jsxs("div", { ref: ref, className: cn(container), children: [_jsxs("div", { className: cn(logoWrapper), children: [_jsx("img", { className: cn(svgController), src: "/images/logos/logo-itc-main.svg", alt: "" }), _jsx("img", { className: cn(svgController), src: "/images/logos/logo-tosel-main.svg", alt: "" })] }), _jsxs("div", { className: "flex flex-col w-full gap-2.5", children: [_jsx("div", { className: cn(titleDivider) }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("div", { className: "text-lg font-bold leading-none", children: "\uC218 \uD5D8 \uD45C" }), _jsx("div", { className: "text-sm font-medium leading-none", children: title })] }), _jsx("div", { className: cn(titleDivider) })] }), _jsxs("div", { className: "flex flex-col gap-5 mt-5", children: [_jsxs("div", { className: "flex flex-col gap-0", children: [_jsxs("div", { className: cn(cellWrapper), children: [_jsx("div", { className: cn(cellTitleLarge), children: "\uC218\uD5D8\uBC88\uD638" }), _jsx("div", { className: "w-full flex flex-row divide-x-[1px] divide-dashed divide-gray-medium/50", children: numberArray.map((num, index) => (_jsx("div", { className: `flex justify-center items-center text-xs font-medium ${num === null
|
|
50
|
+
? "w-2.5 shrink-0 bg-gray-light"
|
|
51
|
+
: "w-full bg-white"}`, children: num !== null ? num : "" }, index))) })] }), _jsxs("div", { className: "font-medium text-2xs", children: ["*OMR (1)\uBC88 \uD56D\uBAA9\uC5D0 \uD574\uB2F9\uBC88\uD638\uB97C \uB530\uB77C\uC11C \uC368\uC8FC\uC138\uC694.", " "] })] }), _jsxs("div", { className: cn(cellWrapper), children: [_jsx("div", { className: cn(cellTitleLarge), children: "\uB808\uBCA8" }), _jsx("div", { className: cn(cellText), children: props.level })] }), _jsxs("div", { className: "flex flex-row gap-2", children: [_jsxs("div", { className: "flex flex-col gap-0 h-full w-21 border-1 border-gray-medium shrink-0", children: [_jsx("div", { className: "h-full w-full bg-cover", style: {
|
|
52
|
+
backgroundImage: `url(${props.profileImageUrl ?? ""})`,
|
|
53
|
+
} }), _jsx("div", { className: cn(cellTitleLarge, "w-full"), children: "\uC0AC\uC9C4" })] }), _jsxs("div", { className: "flex flex-col gap-2 w-full", children: [_jsxs("div", { className: "flex flex-col gap-0", children: [_jsxs("div", { className: cn(cellWrapper), children: [_jsx("div", { className: cn(cellTitleSmall), children: "\uC774\uB984" }), _jsx("div", { className: cn(cellText), children: props.name })] }), _jsxs("div", { className: cn(cellWrapper, "border-t-0"), children: [_jsx("div", { className: cn(cellTitleSmall), children: "\uC0DD\uB144\uC6D4\uC77C" }), _jsx("div", { className: cn(cellText), children: props.birthday })] })] }), _jsxs("div", { className: "flex flex-col gap-0", children: [_jsxs("div", { className: cn(cellWrapper), children: [_jsx("div", { className: cn(cellTitleSmall), children: "\uACE0\uC0AC\uC7A5" }), _jsx("div", { className: cn(cellText), children: hall })] }), _jsxs("div", { className: cn(cellWrapper, "border-t-0"), children: [_jsx("div", { className: cn(cellTitleSmall), children: "\uACE0\uC0AC\uC2E4" }), _jsx("div", { className: cn(cellText), children: room })] })] })] })] }), _jsxs("div", { className: "flex flex-col gap-0", children: [_jsxs("div", { className: cn(cellWrapper), children: [_jsx("div", { className: cn(cellTitleLarge, "bg-green-dark/10"), children: "\uC2DC\uD5D8\uC77C\uC790" }), _jsx("div", { className: cn(cellText), children: props.exam.date })] }), _jsxs("div", { className: cn(cellWrapper, "border-t-0"), children: [_jsx("div", { className: cn(cellTitleLarge, "bg-green-dark/10"), children: "\uC785\uC2E4 \uC644\uB8CC\uC2DC\uAC04" }), _jsx("div", { className: cn(cellText), children: moment.unix(startedAt).format("HH시 mm분") })] }), _jsxs("div", { className: cn(cellWrapper, "border-t-0"), children: [_jsx("div", { className: cn(cellTitleLarge, "bg-green-dark/10"), children: "\uC885\uB8CC\uC2DC\uAC04" }), _jsx("div", { className: cn(cellText), children: moment.unix(endedAt).format("HH시 mm분") })] }), _jsxs("div", { className: "flex flex-col mt-1", children: [_jsx("div", { className: "font-medium text-2xs leading-tight", children: "*\uC785\uC2E4\uC2DC\uAC04 \uC774\uD6C4\uC5D0\uB294 \uC785\uC2E4\uC774 \uC81C\uD55C\uB429\uB2C8\uB2E4." }), _jsx("div", { className: "font-medium text-2xs leading-tight", children: "*\uACE0\uC0AC\uC7A5 \uC5EC\uAC74\uC5D0 \uB530\uB77C \uD1F4\uC2E4\uC2DC\uAC04\uC740 \uC870\uAE08\uC529 \uC0C1\uC774\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4." })] })] }), _jsx("div", { className: "w-full border-b-1 border-dashed border-gray-medium" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("div", { className: "font-bold text-sm leading-tight", children: "\uC751\uC2DC\uC790 \uC720\uC758\uC0AC\uD56D" }), _jsxs("ul", { className: "list-outside list-decimal ml-4 font-medium text-2xs", children: [_jsxs("li", { className: "mb-1", children: ["\uB2E4\uC74C\uC758 \uBB3C\uD488\uC744 \uAF2D \uC900\uBE44\uD574\uC8FC\uC138\uC694:", _jsx("br", {}), " \uCEF4\uD4E8\uD130\uC6A9 \uC0AC\uC778\uD39C / \uC218\uC815 \uD14C\uC774\uD504 / \uC218\uD5D8\uD45C / \uAC80\uC815 \uBCFC\uD39C"] }), _jsxs("li", { className: "mb-1", children: ["\uACE0\uC0AC\uC7A5 \uC704\uCE58\uB97C \uBBF8\uB9AC \uD655\uC778\uD574\uC8FC\uC138\uC694:", _jsx("br", {}), " \uC218\uD5D8\uD45C\uC5D0 \uAE30\uC7AC\uB41C \uACE0\uC0AC\uC7A5, \uACE0\uC0AC\uC2E4 \uC815\uBCF4\uB97C \uD655\uC778\uD574\uC8FC\uC138\uC694."] }), _jsxs("li", { children: ["\uD559\uBD80\uBAA8 \uCD9C\uC785 \uD1B5\uC81C:", _jsx("br", {}), "\uACE0\uC0AC\uC2E4 \uB0B4\uBD80\uC5D0\uB294 \uD559\uBD80\uBAA8\uC758 \uCD9C\uC785\uC774 \uC5C4\uACA9\uD788 \uD1B5\uC81C\uB429\uB2C8\uB2E4."] })] })] })] })] }));
|
|
54
|
+
}
|
|
55
|
+
export default forwardRef(AcademyTicket);
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import Layout from "./Layout";
|
|
2
|
+
import Academy from "./academy/Academy";
|
|
2
3
|
declare const Ticket: {
|
|
4
|
+
Academy: typeof Academy;
|
|
5
|
+
Paper: import("react").ForwardRefExoticComponent<{
|
|
6
|
+
props: import("./Ticket").TicketProps;
|
|
7
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
3
8
|
Layout: typeof Layout;
|
|
4
9
|
};
|
|
5
10
|
export default Ticket;
|
|
@@ -5,6 +5,8 @@ export interface TranscriptProps {
|
|
|
5
5
|
name: string;
|
|
6
6
|
nickname?: string;
|
|
7
7
|
imgSrc?: string;
|
|
8
|
+
qrSrc?: string;
|
|
9
|
+
sharedSrc?: string;
|
|
8
10
|
code: string;
|
|
9
11
|
birthday: string;
|
|
10
12
|
examName: string;
|
|
@@ -36,6 +38,10 @@ export interface TranscriptProps {
|
|
|
36
38
|
section1: number;
|
|
37
39
|
section2: number;
|
|
38
40
|
};
|
|
41
|
+
ageAverage: {
|
|
42
|
+
section1: number;
|
|
43
|
+
section2: number;
|
|
44
|
+
};
|
|
39
45
|
"10percentageAverage": number;
|
|
40
46
|
"30percentageAverage": number;
|
|
41
47
|
};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef } from "react";
|
|
2
|
+
import { forwardRef, useEffect, useState } from "react";
|
|
3
|
+
import QRCode from "react-qr-code";
|
|
3
4
|
import { paperSize } from "../../../../style/size";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { LineBreaks } from "../../../../text";
|
|
6
|
+
import { cn, copyToClipboard } from "../../../../util";
|
|
7
|
+
import SVG from "../../../../asset/SVG";
|
|
8
|
+
import { useResponsive, usePageLoaded } from "../../../../hook";
|
|
6
9
|
import { ResponsiveContainer, PieChart, Pie, Cell, } from "recharts";
|
|
7
10
|
const examTypeMap = {
|
|
8
11
|
REG: "정기시험",
|
|
@@ -49,6 +52,10 @@ const LevelToStyleMap = {
|
|
|
49
52
|
textcolor: "text-gray-dark",
|
|
50
53
|
},
|
|
51
54
|
};
|
|
55
|
+
const printBoxStyles = {
|
|
56
|
+
shadow: "print:shadow-none",
|
|
57
|
+
colors: "print:bg-white print:border print:border-gray-medium/70",
|
|
58
|
+
};
|
|
52
59
|
function getStylefromLevel(level, field) {
|
|
53
60
|
return LevelToStyleMap[level]?.[field] || "Unknown";
|
|
54
61
|
}
|
|
@@ -57,9 +64,8 @@ function TranscriptDesign({ props }, ref) {
|
|
|
57
64
|
const container = {
|
|
58
65
|
printSize: paperSize.a4,
|
|
59
66
|
backgrounds: "print:bg-white",
|
|
60
|
-
sizes: "w-full
|
|
67
|
+
sizes: "w-full max-w-[210mm]",
|
|
61
68
|
textStyles: "break-keep",
|
|
62
|
-
// test: "border-2 border-red-500",
|
|
63
69
|
};
|
|
64
70
|
const headerBox = {
|
|
65
71
|
display: "flex flex-row flex-wrap justify-between items-center",
|
|
@@ -67,20 +73,74 @@ function TranscriptDesign({ props }, ref) {
|
|
|
67
73
|
spacings: "px-5 py-2",
|
|
68
74
|
backgrounds: "bg-gradient-to-r from-crimson-burgundy to-green-dark",
|
|
69
75
|
};
|
|
76
|
+
return (_jsxs("div", { ref: ref, className: cn(container), children: [_jsxs("div", { className: cn(headerBox), children: [_jsx("img", { src: "images/logos/logo-tosel-white.svg", alt: "", className: "h-10" }), _jsxs("div", { className: "text-white font-bold text-base", children: [getStringfromType(info.examType), " \uC131\uC801\uD45C"] })] }), _jsx(IdCard, { info: info }), _jsxs("div", { className: "flex flex-col gap-5 xs:flex-row mt-5 items-stretch", children: [_jsx(ResultCard, { result: result }), _jsx(HonorCard, { result: result })] }), _jsx(PerformanceCard, { data: data }), _jsx(ScoreCard, { data: data }), _jsx(SectionBarCard, { data: data })] }));
|
|
77
|
+
}
|
|
78
|
+
export default forwardRef(TranscriptDesign);
|
|
79
|
+
function IdCard({ info }) {
|
|
80
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
81
|
+
const togglecard = () => setIsExpanded(!isExpanded);
|
|
82
|
+
//반응형 info 카드 height 문제로 눌러서 자세히 보기 차후 구현 예정
|
|
83
|
+
const isXS = useResponsive("xs");
|
|
84
|
+
const cardWrapper = {
|
|
85
|
+
displays: "flex flex-col self-auto overflow-hidden",
|
|
86
|
+
sizes: "w-full rounded-lg h-fit",
|
|
87
|
+
backgrounds: "bg-white shadow-main",
|
|
88
|
+
spacings: "p-3",
|
|
89
|
+
printOptions: "print:bg-white print:shadow-none",
|
|
90
|
+
};
|
|
91
|
+
const imgBox = {
|
|
92
|
+
displays: "relative shrink-0 overflow-hidden",
|
|
93
|
+
sizes: "h-30 aspect-7/9 rounded-lg",
|
|
94
|
+
backgrounds: info.imgSrc ?? "bg-jr-blue-light",
|
|
95
|
+
outlines: "border-2 border-slate-200",
|
|
96
|
+
};
|
|
97
|
+
const qrBox = {
|
|
98
|
+
displays: "shrink-0 hidden sm:block relative overflow-hidden",
|
|
99
|
+
sizes: "h-30 p-2 aspect-square rounded-lg",
|
|
100
|
+
textStyles: "text-jr-blue",
|
|
101
|
+
backgrounds: "bg-white",
|
|
102
|
+
groupAction: "group duration-300 hover:scale-110",
|
|
103
|
+
};
|
|
104
|
+
const copyButtonWrapper = {
|
|
105
|
+
display: "absolute flex justify-center items-center",
|
|
106
|
+
positions: "top-0 left-0",
|
|
107
|
+
sizes: "h-full w-full backdrop-blur-sm",
|
|
108
|
+
graphics: "opacity-0 bg-white/80 ",
|
|
109
|
+
animations: "duration-300 group-hover:opacity-100",
|
|
110
|
+
};
|
|
111
|
+
const copyButton = {
|
|
112
|
+
displays: "flex justify-center items-center",
|
|
113
|
+
sizes: "w-20 h-8 rounded-lg",
|
|
114
|
+
colors: "bg-green-light border border-green-dark",
|
|
115
|
+
textStyles: "text-xs text-green-dark font-medium text-center",
|
|
116
|
+
animations: "hover:bg-green-dark hover:text-white duration-300 cursor-pointer",
|
|
117
|
+
};
|
|
70
118
|
const levelTag = {
|
|
71
119
|
display: "flex justify-center items-center",
|
|
72
|
-
textStyles: "text-center
|
|
120
|
+
textStyles: "text-center",
|
|
73
121
|
variableStyle: `text-center text-xs font-bold ${getStylefromLevel(info.level, "textcolor")}`,
|
|
74
122
|
backgrounds: getStylefromLevel(info.level, "bgcolor"),
|
|
75
|
-
sizes:
|
|
76
|
-
|
|
123
|
+
sizes: isXS
|
|
124
|
+
? "rounded-md w-fit h-fit px-2 py-1"
|
|
125
|
+
: "rounded-md w-full h-full",
|
|
126
|
+
printOptions: "print:w-fit print:h-fit print:px-2 print:py-1",
|
|
77
127
|
};
|
|
78
|
-
|
|
79
|
-
return (_jsxs("div", { ref: ref, className: cn(container), children: [_jsxs("div", { className: cn(headerBox), children: [_jsx("img", { src: "images/logos/logo-tosel-white.svg", alt: "", className: "h-10" }), _jsxs("div", { className: "text-white font-medium text-base", children: [getStringfromType(info.examType), " \uC131\uC801\uD45C"] })] }), _jsx(ResultCard, { result: result })] }));
|
|
128
|
+
return (_jsxs("div", { className: "flex flex-row w-full h-fit mt-5 gap-5", children: [_jsxs("div", { className: cn(cardWrapper), children: [_jsxs("div", { className: "flex flex-row justify-between items-center pb-1 w-full h-fit border-b-2 border-green-dark", children: [_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex flex-[3] text-sm truncate font-bold text-green-dark", children: [info.name, " ", info.nickname && _jsxs("span", { children: [" \u00A0/ ", info.nickname] })] }), _jsx("div", { className: "flex flex-[1] text-sm", children: info.birthday })] }), _jsx("div", { className: "w-fit h-full xs:block hidden", children: _jsx("div", { className: cn(levelTag), children: getStylefromLevel(info.level, "name") }) })] }), _jsx("div", {}), _jsxs("div", { className: "flex flex-col xs:flex-row w-full h-fit mt-2", children: [_jsxs("div", { className: "flex flex-[3] text-sm truncate", children: [_jsx("div", { className: "flex flex-[2] text-green-dark", children: "\uC218\uD5D8\uBC88\uD638:" }), _jsx("div", { className: "flex flex-[3]", children: info.code })] }), _jsxs("div", { className: "flex flex-[3] text-sm truncate", children: [_jsx("div", { className: "flex flex-[2] text-green-dark", children: "\uC2DC\uD5D8\uC77C:" }), _jsx("div", { className: "flex flex-[3]", children: info.examDate })] })] }), _jsxs("div", { className: "flex flex-col xs:flex-row w-full h-fit", children: [_jsxs("div", { className: "flex flex-[3] text-sm truncate", children: [_jsx("div", { className: "flex flex-[2] text-green-dark", children: "\uC720\uD6A8\uAE30\uAC04:" }), _jsx("div", { className: "flex flex-[3]", children: info.examValidAt })] }), _jsxs("div", { className: "flex flex-[3] text-sm truncate", children: [_jsx("div", { className: "flex flex-[2] text-green-dark", children: "\uC218\uD5D8\uBC88\uD638:" }), _jsx("div", { className: "flex flex-[3]", children: info.examDate })] })] })] }), _jsxs("div", { className: cn(qrBox), children: [info.qrSrc && _jsx(QRCode, { value: info.qrSrc, className: "w-full h-full" }), _jsx("div", { className: "absolute top-0 left-0 w-full h-full flex justify-center items-center ", children: _jsx("img", { src: "/images/img-favicon-main.png", alt: "", className: "size-8" }) }), info.qrSrc && (_jsx("div", { className: cn(copyButtonWrapper), children: _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("div", { className: "flex justify-center items-center ", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", className: "size-6 stroke-green-dark", children: _jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" }) }) }), _jsx("div", { className: cn(copyButton), onClick: () => copyToClipboard(info.qrSrc), children: "\uACF5\uC720\uD558\uAE30" })] }) }))] }), _jsxs("div", { className: "flex flex-col shrink-0", children: [_jsxs("div", { className: cn(imgBox), children: [_jsx("img", { src: info.imgSrc, alt: "", className: "object-cover w-full h-auto" }), _jsx("div", { className: "absolute w-full h-full flex items-center justify-center", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", className: "size-6 stroke-jr-blue/50", children: _jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" }) }) })] }), !isXS && (_jsx("div", { className: "w-full h-full mt-3 flex", children: _jsx("div", { className: "w-full h-full block xs:hidden", children: _jsx("div", { className: cn(levelTag), children: getStylefromLevel(info.level, "name") }) }) }))] })] }));
|
|
80
129
|
}
|
|
81
|
-
export default forwardRef(TranscriptDesign);
|
|
82
130
|
function ResultCard({ result }) {
|
|
83
|
-
|
|
131
|
+
const cardWrapper = {
|
|
132
|
+
displays: "flex flex-col self-auto flex-[2] md:flex-[1] overflow-hidden",
|
|
133
|
+
sizes: "w-full h-fit rounded-lg",
|
|
134
|
+
backgrounds: "bg-white shadow-main",
|
|
135
|
+
// animations: "duration-300 hover:scale-105 hover:shadow-green",
|
|
136
|
+
};
|
|
137
|
+
const cardTitle = {
|
|
138
|
+
display: "flex flex-row justify-center items-center",
|
|
139
|
+
sizes: "h-7 w-full",
|
|
140
|
+
bg: "bg-green-dark",
|
|
141
|
+
textStyles: "text-white font-medium text-sm",
|
|
142
|
+
};
|
|
143
|
+
return (_jsxs("div", { className: cn(cardWrapper, printBoxStyles), children: [_jsxs("div", { className: cn(cardTitle), children: [_jsx("div", { className: "w-full text-center h-full flex justify-center items-center", children: "\uCDE8\uB4DD \uC810\uC218" }), _jsx("div", { className: "w-0.5 h-7 bg-white" }), _jsx("div", { className: "w-full text-center h-full flex justify-center items-center", children: "\uC778\uC99D \uB4F1\uAE09" })] }), _jsxs("div", { className: "flex flex-row gap-10 p-5", children: [_jsx(CircularGauge, { score: result.score, maxScore: 100, isGrade: false }), _jsx(CircularGauge, { score: result.grade, maxScore: 9, isGrade: true })] })] }));
|
|
84
144
|
}
|
|
85
145
|
const CircularGauge = ({ score, maxScore, isGrade }) => {
|
|
86
146
|
const pieStyles = {
|
|
@@ -100,6 +160,7 @@ const CircularGauge = ({ score, maxScore, isGrade }) => {
|
|
|
100
160
|
positions: "top-0 left-0",
|
|
101
161
|
sizes: "w-full h-full",
|
|
102
162
|
textStyles: "font-bold text-gray-medium text-2xl",
|
|
163
|
+
printOptions: "print:text-gray-dark",
|
|
103
164
|
};
|
|
104
165
|
const preparePieChartData = () => {
|
|
105
166
|
const mainScore = score;
|
|
@@ -118,5 +179,130 @@ const CircularGauge = ({ score, maxScore, isGrade }) => {
|
|
|
118
179
|
}
|
|
119
180
|
};
|
|
120
181
|
return (_jsxs("div", { className: "w-full aspect-ratio-1/1 flex items-center justify-center relative", children: [_jsx("div", { className: "absolute top-0 left-0 w-full aspect-ratio-1/1", children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", aspect: 1, children: _jsx(PieChart, { children: _jsx(Pie, { data: [{ name: "Background", value: 100 }], cx: "50%", cy: "50%", innerRadius: "70%", outerRadius: "90%", fill: "rgba(128, 128, 128, 0.2)" // 회색 배경 색상
|
|
121
|
-
, dataKey: "value", stroke: "rgb(255,255,255,0)", animationDuration: 0 }) }) }) }), _jsx(ResponsiveContainer, { width: "100%", height: "100%", aspect: 1, children: _jsx(PieChart, { children: _jsxs(Pie, { data: preparePieChartData(), ...pieStyles, children: [_jsx(Cell, { fill: "#105652", ...cellStyles
|
|
182
|
+
, dataKey: "value", stroke: "rgb(255,255,255,0)", animationDuration: 0 }) }) }) }), _jsx("div", { className: "absolute top-0 left-0 w-full aspect-ratio-1/1 opacity-0 print:opacity-100", children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", aspect: 1, children: _jsx(PieChart, { children: _jsxs(Pie, { data: preparePieChartData(), ...pieStyles, animationDuration: 0, children: [_jsx(Cell, { fill: "#105652", ...cellStyles, style: {
|
|
183
|
+
filter: "drop-shadow(0px 3px 5px rgba(16, 86, 82, 0.38))",
|
|
184
|
+
} }), _jsx(Cell, { fill: "rgba(255, 255, 255, 0)", ...cellStyles })] }) }) }) }), _jsx(ResponsiveContainer, { width: "100%", height: "100%", aspect: 1, children: _jsx(PieChart, { children: _jsxs(Pie, { data: preparePieChartData(), ...pieStyles, children: [_jsx(Cell, { fill: "#105652", ...cellStyles, style: {
|
|
185
|
+
filter: "drop-shadow(0px 3px 5px rgba(16, 86, 82, 0.38))",
|
|
186
|
+
} }), _jsx(Cell, { fill: "rgba(255, 255, 255, 0)", ...cellStyles })] }) }) }), _jsx("div", { className: cn(scoreText), children: score })] }));
|
|
122
187
|
};
|
|
188
|
+
function HonorCard({ result }) {
|
|
189
|
+
const cardWrapper = {
|
|
190
|
+
displays: "flex flex-col self-stretch flex-[1] relative",
|
|
191
|
+
sizes: "w-full rounded-lg overflow-hidden",
|
|
192
|
+
backgrounds: "bg-white shadow-main",
|
|
193
|
+
animations: "duration-300 hover:scale-105 hover:shadow-green",
|
|
194
|
+
};
|
|
195
|
+
const cardTitle = {
|
|
196
|
+
display: "flex flex-row justify-center items-center",
|
|
197
|
+
sizes: "h-7 shrink-0 w-full",
|
|
198
|
+
bg: "bg-green-light",
|
|
199
|
+
textStyles: "text-green-dark font-medium text-sm",
|
|
200
|
+
};
|
|
201
|
+
return (_jsxs("div", { className: cn(cardWrapper, printBoxStyles), onClick: () => (window.location.href = `https://www.tosel.org/HallofFame/main`), children: [_jsx("div", { className: cn(cardTitle), children: _jsx("div", { className: "w-full text-center h-fit", children: "\uBA85\uC608\uC758 \uC804\uB2F9" }) }), _jsxs("div", { className: "w-full h-full flex flex-row px-5 gap-x-5", children: [_jsxs("div", { className: "flex flex-[1] flex-col w-full justify-center items-center xs:hidden md:flex", children: [_jsx("div", { className: "text-gray-dark font-bold text-xl", children: "\uBA85\uC608\uC758 \uC804\uB2F9" }), _jsx("div", { className: "text-gray-medium font-medium text-sm", children: "Hall of Fame" })] }), _jsx("div", { className: "flex w-full flex-[1] py-4 xs:py-0", children: _jsx(SVG.HallofFame, { isHonor: result.isHonor }) })] }), _jsx("div", { className: "pb-3 px-5 text-center text-xs", children: result.isHonor
|
|
202
|
+
? "축하합니다! 명예의 전당에 등재되었습니다"
|
|
203
|
+
: "아쉽게도 명예의 전당에 오르지 못했습니다." })] }));
|
|
204
|
+
}
|
|
205
|
+
function ScoreCard({ data }) {
|
|
206
|
+
const cellAnimation = {
|
|
207
|
+
animations: "hover:bg-green-light/50 hover:text-green-dark duration-300",
|
|
208
|
+
};
|
|
209
|
+
return (_jsx("div", { className: "overflow-auto w-full scrollbar-hidden rounded-lg mt-5 print:border print:border-gray-medium/70 cursor-default shadow-main print:shadow-none", children: _jsxs("div", { className: "min-w-[172mm] w-full", children: [_jsxs("div", { className: "flex bg-gradient-to-r from-green-dark to-crimson-burgundy text-white font-medium text-sm", children: [_jsx("div", { className: "text-center print:static sticky left-0 bg-green-dark p-2 flex-[3] font-black", children: "\uC131\uC801\uD45C" }), _jsx("div", { className: "p-2 flex-[2] text-center", children: "\uCD1D\uC810" }), _jsx("div", { className: "p-2 flex-[2] text-center", children: "\uB0B4 \uC810\uC218" }), _jsx("div", { className: "p-2 flex-[3] text-center", children: "\uC804\uAD6D\uD3C9\uADE0" }), _jsx("div", { className: "p-2 flex-[3] text-center", children: "\uC9C0\uC5ED\uD3C9\uADE0" }), _jsx("div", { className: "p-2 flex-[3] text-center", children: "\uB3D9\uC77C\uD559\uB144" }), _jsx("div", { className: "p-2 flex-[3] text-center", children: "10% \uD3C9\uADE0" }), _jsx("div", { className: "p-2 flex-[3] text-center", children: "30% \uD3C9\uADE0" })] }), _jsxs("div", { className: "flex bg-white/60 font-medium text-sm text-gray-medium ", children: [_jsx("div", { className: "sticky left-0 bg-white/90 p-2 flex-[3] text-center text-gray-dark border-green-dark border-r-1", children: "Section1" }), _jsx("div", { className: cn("p-2 flex-[2] text-center", cellAnimation), children: data.analysis.total.section1.toFixed(1) }), _jsx("div", { className: "p-2 flex-[2] text-center text-green-dark font-bold bg-green-light", children: data.analysis.user.section1.toFixed(1) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: data.analysis.nationalAverage.section1.toFixed(2) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: data.analysis.localAverage.section1.toFixed(2) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: data.analysis.ageAverage.section1.toFixed(2) }), _jsx("div", { className: "p-2 flex-[3] text-center border-green-dark border-l-1" }), _jsx("div", { className: "p-2 flex-[3] text-center" })] }), _jsxs("div", { className: "flex bg-white/60 font-medium text-sm text-gray-medium ", children: [_jsx("div", { className: "sticky left-0 bg-white/90 p-2 flex-[3] text-center text-gray-dark border-green-dark border-r-1", children: "Section2" }), _jsx("div", { className: cn("p-2 flex-[2] text-center", cellAnimation), children: data.analysis.total.section2.toFixed(1) }), _jsx("div", { className: "p-2 flex-[2] text-center text-green-dark font-bold bg-green-light", children: data.analysis.user.section2.toFixed(1) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: data.analysis.nationalAverage.section2.toFixed(2) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: data.analysis.localAverage.section2.toFixed(2) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: data.analysis.ageAverage.section2.toFixed(2) }), _jsx("div", { className: "p-2 flex-[3] text-center border-green-dark border-l-1 font-bold", children: data.analysis["10percentageAverage"].toFixed(2) }), _jsx("div", { className: "p-2 flex-[3] text-center font-bold", children: data.analysis["30percentageAverage"].toFixed(2) })] }), _jsxs("div", { className: "flex bg-white/60 font-medium text-sm text-gray-medium ", children: [_jsx("div", { className: "sticky left-0 bg-white/90 p-2 flex-[3] text-center text-gray-dark border-green-dark border-r-1", children: "total" }), _jsx("div", { className: cn("p-2 flex-[2] text-center", cellAnimation), children: (data.analysis.total.section1 + data.analysis.total.section2).toFixed(1) }), _jsx("div", { className: "p-2 flex-[2] text-center text-green-dark font-bold bg-green-light", children: (data.analysis.user.section1 + data.analysis.user.section2).toFixed(1) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: (data.analysis.nationalAverage.section1 +
|
|
210
|
+
data.analysis.nationalAverage.section2).toFixed(2) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: (data.analysis.localAverage.section1 +
|
|
211
|
+
data.analysis.localAverage.section2).toFixed(2) }), _jsx("div", { className: cn("p-2 flex-[3] text-center", cellAnimation), children: (data.analysis.ageAverage.section1 +
|
|
212
|
+
data.analysis.ageAverage.section2).toFixed(2) }), _jsx("div", { className: "p-2 flex-[3] text-center border-green-dark border-l-1" }), _jsx("div", { className: "p-2 flex-[3] text-center " })] })] }) }));
|
|
213
|
+
}
|
|
214
|
+
function PerformanceCard({ data }) {
|
|
215
|
+
const cardWrapper = {
|
|
216
|
+
displays: "flex flex-col relative",
|
|
217
|
+
sizes: "w-full rounded-lg overflow-hidden",
|
|
218
|
+
backgrounds: "bg-white shadow-main",
|
|
219
|
+
sapcings: "mt-5",
|
|
220
|
+
};
|
|
221
|
+
const cardTitle = {
|
|
222
|
+
display: "flex flex-row justify-center items-center",
|
|
223
|
+
sizes: "h-7 shrink-0 w-full",
|
|
224
|
+
bg: "bg-green-light",
|
|
225
|
+
textStyles: "text-green-dark font-medium text-sm",
|
|
226
|
+
};
|
|
227
|
+
const scriptStyling = {
|
|
228
|
+
display: "justify-start items-start",
|
|
229
|
+
sizes: "w-full h-fit",
|
|
230
|
+
spacings: "p-5",
|
|
231
|
+
textStyles: "text-xs font-medium text-black break-keep",
|
|
232
|
+
};
|
|
233
|
+
return (_jsxs("div", { className: cn(cardWrapper, printBoxStyles), children: [_jsx("div", { className: cn(cardTitle), children: _jsx("div", { className: "w-full text-center h-fit", children: "Performance Evaluation" }) }), _jsxs("div", { className: "w-full h-full flex flex-col md:flex-row gap-5", children: [_jsx("div", { className: "flex flex-col flex-[3]", children: _jsx(LineBreaks, { texts: data.script.performanceEvaluation, className: cn(scriptStyling) }) }), _jsx("div", { className: "flex flex-col flex-[2] justify-center items-center" })] })] }));
|
|
234
|
+
}
|
|
235
|
+
function SectionBarCard({ data }) {
|
|
236
|
+
const cardWrapper = {
|
|
237
|
+
displays: "flex flex-col relative",
|
|
238
|
+
sizes: "w-full rounded-lg overflow-hidden",
|
|
239
|
+
backgrounds: "bg-white shadow-main",
|
|
240
|
+
sapcings: "mt-5",
|
|
241
|
+
};
|
|
242
|
+
const cardTitle = {
|
|
243
|
+
display: "flex flex-row justify-center items-center",
|
|
244
|
+
sizes: "h-7 shrink-0 w-full",
|
|
245
|
+
bg: "bg-green-light",
|
|
246
|
+
textStyles: "text-green-dark font-medium text-sm",
|
|
247
|
+
};
|
|
248
|
+
return (_jsxs("div", { className: cn(cardWrapper, printBoxStyles), children: [_jsx("div", { className: cn(cardTitle), children: "Grade and Average Score" }), _jsxs("div", { className: "flex flex-col sm:mt-0 mt-5", children: [_jsx(SectionBarSet, { title: "section1", score: data.analysis.user.section1, total: 50, subScore: data.analysis.nationalAverage.section1, script: data.script.section1, scale: 10 }), _jsx(SectionBarSet, { title: "section2", score: data.analysis.user.section2, total: 50, subScore: data.analysis.nationalAverage.section2, script: data.script.section2, scale: 10 })] })] }));
|
|
249
|
+
}
|
|
250
|
+
function SectionBarSet({ score, subScore, total, title, script, scale, }) {
|
|
251
|
+
const isLoaded = usePageLoaded();
|
|
252
|
+
const [currentWidth, setCurrentWidth] = useState(0);
|
|
253
|
+
const widthPercentage = (score / total) * 100;
|
|
254
|
+
const subScorePercentage = subScore ? (subScore / total) * 100 : undefined;
|
|
255
|
+
useEffect(() => {
|
|
256
|
+
if (isLoaded) {
|
|
257
|
+
let width = 0;
|
|
258
|
+
const interval = setInterval(() => {
|
|
259
|
+
width += 1;
|
|
260
|
+
if (width >= widthPercentage) {
|
|
261
|
+
clearInterval(interval);
|
|
262
|
+
setCurrentWidth(widthPercentage);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
setCurrentWidth(width);
|
|
266
|
+
}
|
|
267
|
+
}, 10); // 속도 조정 가능
|
|
268
|
+
}
|
|
269
|
+
}, [isLoaded, widthPercentage]);
|
|
270
|
+
const setWrapper = {
|
|
271
|
+
displays: "flex flex-col sm:flex-row justify-center items-center",
|
|
272
|
+
sizes: "w-full h-fit",
|
|
273
|
+
spacings: "p-5 gap-5",
|
|
274
|
+
};
|
|
275
|
+
const bar = {
|
|
276
|
+
displays: "relative flex flex-row justify-start",
|
|
277
|
+
sizes: "w-full h-4 rounded-full",
|
|
278
|
+
backgroudns: "bg-gray-light print:bg-gray-medium/80 ",
|
|
279
|
+
spacings: "my-auto",
|
|
280
|
+
};
|
|
281
|
+
const barFill = {
|
|
282
|
+
sizes: "h-full rounded-full",
|
|
283
|
+
animations: "transition-all duration-500 ease-out",
|
|
284
|
+
backgrounds: "bg-gradient-to-r from-crimson-burgundy to-green-dark shadow-green",
|
|
285
|
+
printOptions: "print:shadow-none",
|
|
286
|
+
};
|
|
287
|
+
const scoreTag = {
|
|
288
|
+
sizes: "h-5 w-10 rounded-md",
|
|
289
|
+
position: "-translate-x-14 -translate-y-2",
|
|
290
|
+
backgrounds: "bg-white border-2 border-green-dark",
|
|
291
|
+
textStyles: "font-bold text-xs text-center text-green-dark",
|
|
292
|
+
};
|
|
293
|
+
const subScoreTag = {
|
|
294
|
+
sizes: "h-5 w-fit rounded-md flex flex-row gap-2",
|
|
295
|
+
position: "-translate-x-30 translate-y-6",
|
|
296
|
+
};
|
|
297
|
+
// 눈금 배열 생성
|
|
298
|
+
const scaleTicks = Array.from({ length: total / scale + 1 }, (_, index) => index * scale);
|
|
299
|
+
return (_jsxs("div", { className: cn(setWrapper), children: [_jsxs("div", { className: "relative w-full h-20 flex flex-[1] justify-center items-center px-5 pt-8 pb-2 overflow-visible", children: [_jsxs("div", { className: cn(bar), children: [_jsx("div", { className: "absolute top-0 left-0 w-full h-full flex", children: _jsx("div", { className: cn(barFill, "duration-0 opacity-0 print:opacity-100"), style: {
|
|
300
|
+
width: `${widthPercentage}%`,
|
|
301
|
+
} }) }), _jsx("div", { className: cn(barFill, "opacity-100 print:opacity-0"), style: {
|
|
302
|
+
width: `${currentWidth}%`,
|
|
303
|
+
} }), _jsx("div", { className: "absolute w-full text-green-dark -translate-y-12 font-bold text-sm h-fit text-center", children: title })] }), _jsx("div", { className: "absolute flex w-full h-full justify-between items-center p-5 text-sm text-gray-medium -translate-y-5", children: scaleTicks.map((tick) => (_jsx("div", { children: tick }, tick))) }), _jsx("div", { className: "absolute flex w-full h-full justify-start items-center", style: {
|
|
304
|
+
transform: `translateX(${widthPercentage}%)`,
|
|
305
|
+
}, children: _jsx("div", { className: cn(scoreTag), children: score.toFixed(1) }) }), subScore && (_jsx("div", { className: "absolute flex w-full h-full justify-start items-center", style: {
|
|
306
|
+
transform: `translateX(${subScorePercentage}%)`,
|
|
307
|
+
}, children: _jsxs("div", { className: cn(subScoreTag), children: [_jsx("div", { className: "font-medium text-xs text-center text-gray-dark", children: "\uC804\uCCB4\uD3C9\uADE0:" }), _jsx("div", { className: "font-medium text-xs text-center text-gray-dark", children: subScore.toFixed(2) }), _jsx("div", { className: "text-green-dark", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "size-4", children: _jsx("path", { fillRule: "evenodd", d: "M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm.53 5.47a.75.75 0 0 0-1.06 0l-3 3a.75.75 0 1 0 1.06 1.06l1.72-1.72v5.69a.75.75 0 0 0 1.5 0v-5.69l1.72 1.72a.75.75 0 1 0 1.06-1.06l-3-3Z", clipRule: "evenodd" }) }) })] }) }))] }), _jsx("div", { className: "w-full h-full flex-[1] text-sm sm:text-xs", children: script })] }));
|
|
308
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edu-tosel/design",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.185",
|
|
4
4
|
"description": "UI components for International TOSEL Committee",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jsx",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"react-dom": "^18.2.0",
|
|
29
29
|
"react-icons": "^5.0.1",
|
|
30
30
|
"react-lottie-player": "^1.5.6",
|
|
31
|
+
"react-qr-code": "^2.0.15",
|
|
31
32
|
"react-router-dom": "^6.21.3",
|
|
32
33
|
"react-spring": "^9.7.3",
|
|
33
34
|
"react-to-print": "^2.15.1",
|
package/style/size.js
CHANGED
package/tailwind.config.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function copyToClipboard(value: string | undefined): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default function copyToClipboard(value) {
|
|
2
|
+
const textToCopy = value ?? "";
|
|
3
|
+
if (textToCopy) {
|
|
4
|
+
navigator.clipboard
|
|
5
|
+
.writeText(textToCopy)
|
|
6
|
+
.then(() => {
|
|
7
|
+
alert(`클립보드에 복사되었습니다.`); // 복사된 값을 alert로 출력
|
|
8
|
+
})
|
|
9
|
+
.catch((err) => {
|
|
10
|
+
console.error("복사에 실패했습니다:", err);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
alert("복사할 값이 없습니다."); // 값이 없을 경우 alert로 알림
|
|
15
|
+
}
|
|
16
|
+
}
|
package/util/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { default as checkPathMatch } from "./checkPathMatch";
|
|
|
7
7
|
export { default as createSetter } from "./createSetter";
|
|
8
8
|
export { default as compareDates } from "./compareDates";
|
|
9
9
|
export { default as convertDateToString } from "./convertDateToString";
|
|
10
|
+
export { default as copyToClipboard } from "./copyToClipboard";
|
|
10
11
|
export * from "../style/colors";
|
|
11
12
|
export * from "./pattern";
|
|
12
13
|
export * from "./shape";
|
package/util/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { default as checkPathMatch } from "./checkPathMatch";
|
|
|
7
7
|
export { default as createSetter } from "./createSetter";
|
|
8
8
|
export { default as compareDates } from "./compareDates";
|
|
9
9
|
export { default as convertDateToString } from "./convertDateToString";
|
|
10
|
+
export { default as copyToClipboard } from "./copyToClipboard";
|
|
10
11
|
export * from "../style/colors";
|
|
11
12
|
export * from "./pattern";
|
|
12
13
|
export * from "./shape";
|
package/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.185
|