@edu-tosel/design 1.0.265 → 1.0.267
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/asset/SVG.d.ts +4 -0
- package/asset/SVG.js +4 -0
- package/asset/SVG.tsx +4 -0
- package/asset/svg/MiniClose.d.ts +4 -0
- package/asset/svg/MiniClose.js +4 -0
- package/asset/svg/MiniClose.tsx +19 -0
- package/asset/svg/Search.d.ts +1 -0
- package/asset/svg/Search.js +4 -0
- package/asset/svg/Search.tsx +24 -0
- package/board/design/Header.design.d.ts +1 -1
- package/board/design/Header.design.js +12 -3
- package/board/template/CanvasBoard.js +1 -1
- package/globals.css +14 -2
- package/interface/Board.d.ts +11 -1
- package/interface/Shelf.d.ts +1 -0
- package/interface/domain/Tag.d.ts +1 -1
- package/interface/domain/Tag.js +2 -1
- package/interface/widget/Carousel.d.ts +1 -1
- package/layout/design/Shelf.design.js +2 -2
- package/layout/index.d.ts +0 -9
- package/layout/index.js +0 -9
- package/layout/template/Ticket/Extension.js +2 -2
- package/layout/template/home/Promotion.js +1 -0
- package/layout/template/home/Service.js +1 -0
- package/layout/template/home/layout/Carousel.js +27 -8
- package/layout/template/home/layout/Navigation.js +117 -22
- package/package.json +2 -2
- package/util/createSearch.d.ts +5 -0
- package/util/createSearch.js +235 -0
- package/util/handlePrint.d.ts +1 -1
- package/util/handlePrint.js +1 -1
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/version.txt +1 -1
- package/widget/template/Input/index.js +8 -0
- package/layout/template/About/SectionA.d.ts +0 -1
- package/layout/template/About/SectionA.js +0 -51
- package/layout/template/About/SectionB.d.ts +0 -2
- package/layout/template/About/SectionB.js +0 -55
- package/layout/template/About/SectionC.d.ts +0 -1
- package/layout/template/About/SectionC.js +0 -35
- package/layout/template/About/SectionCCards.d.ts +0 -13
- package/layout/template/About/SectionCCards.js +0 -13
- package/layout/template/About/SectionCD.d.ts +0 -1
- package/layout/template/About/SectionCD.js +0 -15
- package/layout/template/About/SectionCLeaf.d.ts +0 -15
- package/layout/template/About/SectionCLeaf.js +0 -104
- package/layout/template/About/SectionD.d.ts +0 -1
- package/layout/template/About/SectionD.js +0 -131
- package/layout/template/About/SectionE.d.ts +0 -1
- package/layout/template/About/SectionE.js +0 -7
- package/layout/template/About/SectionECards.d.ts +0 -1
- package/layout/template/About/SectionECards.js +0 -79
- package/layout/template/About/SectionF.d.ts +0 -1
- package/layout/template/About/SectionF.js +0 -4
- package/layout/template/About/SectionG.d.ts +0 -10
- package/layout/template/About/SectionG.js +0 -27
- package/layout/template/About/index.d.ts +0 -19
- package/layout/template/About/index.js +0 -19
- package/layout/template/Books/Books.layout.d.ts +0 -1
- package/layout/template/Books/Books.layout.js +0 -13
- package/layout/template/Books/SectionA.d.ts +0 -2
- package/layout/template/Books/SectionA.js +0 -430
- package/layout/template/Books/index.d.ts +0 -5
- package/layout/template/Books/index.js +0 -5
- package/layout/template/MonthlyProgressReport/Layout.d.ts +0 -4
- package/layout/template/MonthlyProgressReport/Layout.js +0 -52
- package/layout/template/MonthlyProgressReport/Report.d.ts +0 -46
- package/layout/template/MonthlyProgressReport/Report.js +0 -124
- package/layout/template/MonthlyProgressReport/index.d.ts +0 -8
- package/layout/template/MonthlyProgressReport/index.js +0 -7
- package/layout/template/Olympiad/Banner.d.ts +0 -1
- package/layout/template/Olympiad/Banner.js +0 -31
- package/layout/template/Olympiad/Conditions.d.ts +0 -1
- package/layout/template/Olympiad/Conditions.js +0 -168
- package/layout/template/Olympiad/Features.d.ts +0 -1
- package/layout/template/Olympiad/Features.js +0 -44
- package/layout/template/Olympiad/Olympiad.layout.d.ts +0 -1
- package/layout/template/Olympiad/Olympiad.layout.js +0 -19
- package/layout/template/Olympiad/Prizes.d.ts +0 -1
- package/layout/template/Olympiad/Prizes.js +0 -49
- package/layout/template/Olympiad/Sponsors.d.ts +0 -1
- package/layout/template/Olympiad/Sponsors.js +0 -31
- package/layout/template/Olympiad/Videoset.d.ts +0 -1
- package/layout/template/Olympiad/Videoset.js +0 -71
- package/layout/template/Olympiad/index.d.ts +0 -15
- package/layout/template/Olympiad/index.js +0 -15
- package/layout/template/Regexam/Banner.d.ts +0 -1
- package/layout/template/Regexam/Banner.js +0 -183
- package/layout/template/Regexam/Evaluation.d.ts +0 -3
- package/layout/template/Regexam/Evaluation.js +0 -132
- package/layout/template/Regexam/OfflineExam.d.ts +0 -4
- package/layout/template/Regexam/OfflineExam.js +0 -204
- package/layout/template/Regexam/Regexam.layout.d.ts +0 -1
- package/layout/template/Regexam/Regexam.layout.js +0 -13
- package/layout/template/Regexam/Types.d.ts +0 -1
- package/layout/template/Regexam/Types.js +0 -294
- package/layout/template/Regexam/index.d.ts +0 -11
- package/layout/template/Regexam/index.js +0 -11
- package/layout/template/Transcript/Layout.d.ts +0 -6
- package/layout/template/Transcript/Layout.js +0 -52
- package/layout/template/Transcript/design/Transcript.d.ts +0 -228
- package/layout/template/Transcript/design/Transcript.design.d.ts +0 -13
- package/layout/template/Transcript/design/Transcript.design.js +0 -58
- package/layout/template/Transcript/design/Transcript.js +0 -181
- package/layout/template/Transcript/design/TranscriptAdvanced.design.d.ts +0 -5
- package/layout/template/Transcript/design/TranscriptAdvanced.design.js +0 -55
- package/layout/template/Transcript/design/atom/CardTitle.d.ts +0 -5
- package/layout/template/Transcript/design/atom/CardTitle.js +0 -13
- package/layout/template/Transcript/design/atom/CardTitleDivided.d.ts +0 -0
- package/layout/template/Transcript/design/atom/CardTitleDivided.js +0 -1
- package/layout/template/Transcript/design/atom/GetPartDescriptionFromLevel.d.ts +0 -3
- package/layout/template/Transcript/design/atom/GetPartDescriptionFromLevel.js +0 -4
- package/layout/template/Transcript/design/atom/GetPartTitleFromLevel.d.ts +0 -3
- package/layout/template/Transcript/design/atom/GetPartTitleFromLevel.js +0 -4
- package/layout/template/Transcript/design/atom/GetStyleFromLevel.d.ts +0 -2
- package/layout/template/Transcript/design/atom/GetStyleFromLevel.js +0 -4
- package/layout/template/Transcript/design/atom/LevelToPartDescriptionMap.d.ts +0 -6
- package/layout/template/Transcript/design/atom/LevelToPartDescriptionMap.js +0 -95
- package/layout/template/Transcript/design/atom/LevelToPartTitleMap.d.ts +0 -6
- package/layout/template/Transcript/design/atom/LevelToPartTitleMap.js +0 -95
- package/layout/template/Transcript/design/atom/LevelToStyleMap.d.ts +0 -6
- package/layout/template/Transcript/design/atom/LevelToStyleMap.js +0 -42
- package/layout/template/Transcript/design/atom/PrintBoxStyles.d.ts +0 -4
- package/layout/template/Transcript/design/atom/PrintBoxStyles.js +0 -4
- package/layout/template/Transcript/design/molecule/BarGraph.d.ts +0 -11
- package/layout/template/Transcript/design/molecule/BarGraph.js +0 -81
- package/layout/template/Transcript/design/molecule/BarGraphDuo.d.ts +0 -10
- package/layout/template/Transcript/design/molecule/BarGraphDuo.js +0 -6
- package/layout/template/Transcript/design/molecule/BarGraphMulti.d.ts +0 -11
- package/layout/template/Transcript/design/molecule/BarGraphMulti.js +0 -9
- package/layout/template/Transcript/design/molecule/CircularGauge.d.ts +0 -10
- package/layout/template/Transcript/design/molecule/CircularGauge.js +0 -68
- package/layout/template/Transcript/design/molecule/LSWRChart.d.ts +0 -11
- package/layout/template/Transcript/design/molecule/LSWRChart.js +0 -44
- package/layout/template/Transcript/design/molecule/LevelIndex.d.ts +0 -3
- package/layout/template/Transcript/design/molecule/LevelIndex.js +0 -14
- package/layout/template/Transcript/design/molecule/MIChart.d.ts +0 -1
- package/layout/template/Transcript/design/molecule/MIChart.js +0 -51
- package/layout/template/Transcript/design/molecule/OCIChart.d.ts +0 -1
- package/layout/template/Transcript/design/molecule/OCIChart.js +0 -60
- package/layout/template/Transcript/design/molecule/RadarGraph.d.ts +0 -10
- package/layout/template/Transcript/design/molecule/RadarGraph.js +0 -5
- package/layout/template/Transcript/design/organism/BarCardCol.d.ts +0 -8
- package/layout/template/Transcript/design/organism/BarCardCol.js +0 -30
- package/layout/template/Transcript/design/organism/BarCardRow.d.ts +0 -8
- package/layout/template/Transcript/design/organism/BarCardRow.js +0 -30
- package/layout/template/Transcript/design/organism/HonorCard.d.ts +0 -4
- package/layout/template/Transcript/design/organism/HonorCard.js +0 -16
- package/layout/template/Transcript/design/organism/IdCard.d.ts +0 -8
- package/layout/template/Transcript/design/organism/IdCard.js +0 -64
- package/layout/template/Transcript/design/organism/IntelligenceCard.d.ts +0 -12
- package/layout/template/Transcript/design/organism/IntelligenceCard.js +0 -39
- package/layout/template/Transcript/design/organism/NationalPositionCard.d.ts +0 -4
- package/layout/template/Transcript/design/organism/NationalPositionCard.js +0 -14
- package/layout/template/Transcript/design/organism/OCICard.d.ts +0 -4
- package/layout/template/Transcript/design/organism/OCICard.js +0 -17
- package/layout/template/Transcript/design/organism/PerformanceCard.d.ts +0 -5
- package/layout/template/Transcript/design/organism/PerformanceCard.js +0 -25
- package/layout/template/Transcript/design/organism/RadarCard.d.ts +0 -7
- package/layout/template/Transcript/design/organism/RadarCard.js +0 -54
- package/layout/template/Transcript/design/organism/ResultGaugeCard.d.ts +0 -7
- package/layout/template/Transcript/design/organism/ResultGaugeCard.js +0 -19
- package/layout/template/Transcript/design/organism/ScoreCard.d.ts +0 -4
- package/layout/template/Transcript/design/organism/ScoreCard.js +0 -11
- package/layout/template/Transcript/design/organism/SectionRadarCard.d.ts +0 -8
- package/layout/template/Transcript/design/organism/SectionRadarCard.js +0 -42
- package/layout/template/Transcript/index.d.ts +0 -11
- package/layout/template/Transcript/index.js +0 -9
- package/layout/template/Transcript/interface.d.ts +0 -50
- package/layout/template/Transcript/interface.js +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { animated, useTransition } from "react-spring";
|
|
4
4
|
import SVG from "../../../../asset/SVG";
|
|
5
|
-
import { cn, compareDates, convertDateToString } from "../../../../util";
|
|
5
|
+
import { cn, compareDates, convertDateToString, search, } from "../../../../util";
|
|
6
6
|
import { useActionStore } from "../../../../store";
|
|
7
7
|
import { useResponsive } from "../../../../hook";
|
|
8
8
|
export default function Navigation({ browser, calendar, notice, event, }) {
|
|
@@ -14,15 +14,31 @@ export default function Navigation({ browser, calendar, notice, event, }) {
|
|
|
14
14
|
displays: "flex flex-row md:flex-col justify-center gap-x-8 sm:gap-x-12 gap-y-5 items-center",
|
|
15
15
|
sizes: !isOpen ? "h-16 md:h-80 md:rounded-r-xl" : "h-16 md:h-screen",
|
|
16
16
|
widths: !isHidden
|
|
17
|
-
? "w-screen md:w-[56px] duration-
|
|
17
|
+
? "w-screen md:w-[56px] duration-300"
|
|
18
18
|
: "w-0 duration-100",
|
|
19
19
|
backgrounds: "bg-gradient-to-r md:bg-gradient-to-b from-green-dark to-crimson-burgundy",
|
|
20
20
|
};
|
|
21
21
|
const overlayCoverTransition = useTransition(isHidden, {
|
|
22
22
|
from: { width: "0%" },
|
|
23
23
|
enter: { width: "100%" },
|
|
24
|
-
config: { duration:
|
|
24
|
+
config: { duration: 100 },
|
|
25
25
|
});
|
|
26
|
+
// Scroll Lock 처리
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const preventScroll = (e) => e.preventDefault();
|
|
29
|
+
if (isOpen) {
|
|
30
|
+
document.body.style.overflow = "hidden";
|
|
31
|
+
document.addEventListener("touchmove", preventScroll, { passive: false });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
document.body.style.overflow = "";
|
|
35
|
+
document.removeEventListener("touchmove", preventScroll);
|
|
36
|
+
}
|
|
37
|
+
return () => {
|
|
38
|
+
document.body.style.overflow = "";
|
|
39
|
+
document.removeEventListener("touchmove", preventScroll);
|
|
40
|
+
};
|
|
41
|
+
}, [isOpen]);
|
|
26
42
|
useEffect(() => {
|
|
27
43
|
if (isHidden) {
|
|
28
44
|
const timer = setTimeout(() => {
|
|
@@ -41,50 +57,64 @@ export default function Navigation({ browser, calendar, notice, event, }) {
|
|
|
41
57
|
setIsHidden(true);
|
|
42
58
|
return setIsOpen(true);
|
|
43
59
|
};
|
|
44
|
-
const
|
|
45
|
-
positions: "fixed
|
|
46
|
-
sizes: "h-screen w-
|
|
60
|
+
const blurContainer = {
|
|
61
|
+
positions: "fixed inset-0 z-40",
|
|
62
|
+
sizes: "h-screen w-full",
|
|
47
63
|
boundaries: "md:pl-[56px]",
|
|
48
|
-
styles: "bg-black/20
|
|
49
|
-
shadows: "shadow-main
|
|
64
|
+
styles: "bg-black/20 backdrop-blur-sm",
|
|
65
|
+
shadows: "shadow-main",
|
|
66
|
+
animation: isOpen
|
|
67
|
+
? "opacity-100 pointer-events-auto"
|
|
68
|
+
: "opacity-0 pointer-events-none",
|
|
50
69
|
};
|
|
51
70
|
const itemBody = {
|
|
52
71
|
positions: "absolute bottom-16 md:static md:bottom-auto md:flex md:flex-col",
|
|
53
|
-
sizes: "w-full md:w-[400px] h-fit md:h-screen min-h-50",
|
|
72
|
+
sizes: "w-full md:w-[400px] h-fit md:h-screen min-h-50 ",
|
|
54
73
|
styles: "bg-white",
|
|
74
|
+
animation: "duration-300",
|
|
75
|
+
boundaries: "rounded-t-lg rounded-b-none md:rounded-r-lg md:rounded-l-none",
|
|
55
76
|
};
|
|
56
77
|
const iconWrapper = {
|
|
57
78
|
displays: "flex justify-center items-center",
|
|
58
79
|
sizes: "w-8 h-8 rounded-md",
|
|
59
80
|
animations: "hover:bg-white/20",
|
|
60
81
|
};
|
|
82
|
+
const itemsContainer = {
|
|
83
|
+
displays: "relative h-fit md:h-full overflow-hidden duration-300",
|
|
84
|
+
};
|
|
61
85
|
const isMobile = useResponsive("md");
|
|
62
86
|
const overlayPopTransition = useTransition(!isHidden && isOpen, {
|
|
63
|
-
from: { width: "
|
|
64
|
-
enter: { width: "100%" },
|
|
65
|
-
leave: { width: "
|
|
66
|
-
config: { duration:
|
|
87
|
+
from: { width: "100%", opacity: 0, pointerEvent: "none" },
|
|
88
|
+
enter: { width: "100%", opacity: 1, pointerEvent: "auto" },
|
|
89
|
+
leave: { width: "100%", opacity: 0, pointerEvent: "none" },
|
|
90
|
+
config: { duration: 100 },
|
|
91
|
+
delay: 100,
|
|
67
92
|
});
|
|
68
93
|
const scrollTitleWrapper = {
|
|
69
|
-
displays: "
|
|
94
|
+
displays: "relative",
|
|
95
|
+
sizes: "w-full h-fit",
|
|
70
96
|
spacings: "p-5 pb-0",
|
|
71
97
|
};
|
|
72
98
|
const scrollTitle = {
|
|
73
99
|
textStyles: "text-lg font-bold text-green-dark",
|
|
74
100
|
};
|
|
101
|
+
const itemBodyTransition = useTransition(isOpen && !isMobile, {
|
|
102
|
+
from: { transform: "translateY(100%)", opacity: 0 },
|
|
103
|
+
enter: { transform: "translateY(0%)", opacity: 1 },
|
|
104
|
+
leave: { transform: "translateY(100%)", opacity: 0 },
|
|
105
|
+
config: { duration: 300 },
|
|
106
|
+
});
|
|
75
107
|
return (_jsxs(_Fragment, { children: [overlayCoverTransition((styles, item) => item && (_jsx(animated.div, { style: styles, className: "bg-white h-screen fixed top-0 left-0 z-40 flex flex-col justify-center items-center overflow-hidden gap-y-14 ", children: _jsxs("div", { className: "flex flex-col justify-center items-center overflow-hidden gap-y-14 transition-none", children: [_jsx("img", { src: "/images/logos/tosel.png", alt: "tosel", width: 368.56, height: 80.07 }), _jsx("div", { children: "dashboard loading..." })] }) }))), overlayPopTransition((styles, item) => type &&
|
|
76
|
-
item && (_jsx(animated.div, { style: styles, className: cn(
|
|
108
|
+
item && (_jsx(animated.div, { style: styles, className: cn(blurContainer), children: _jsxs("div", { className: cn(itemBody), onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: cn(scrollTitleWrapper), children: [_jsx("div", { className: cn(scrollTitle), children: navigationTypeString[type] }), _jsx("div", { className: "" })] }), _jsx("div", { className: cn(itemsContainer), children: _jsx(NavigationItem, { type: type, calendar: calendar, notice: notice, event: event }) })] }) }))), _jsx("div", { className: "fixed bottom-0 md:top-1/2 md:-translate-y-1/2 flex justify-center items-center z-45", children: _jsxs("div", { onClick: (e) => e.stopPropagation(), className: cn(container), children: [_jsx("div", { className: cn(iconWrapper), onClick: () => handleOpen("calendar"), children: _jsx(SVG.Icon.Calendar, { size: isMobile ? "md" : "lg" }) }), _jsx("div", { className: cn(iconWrapper), onClick: () => handleOpen("notification"), children: _jsx(SVG.Icon.Notification, { size: isMobile ? "md" : "lg" }) }), _jsx("div", { className: cn(iconWrapper), onClick: () => handleOpen("search"), children: _jsx(SVG.Icon.Search, { size: isMobile ? "md" : "lg" }) }), _jsx("div", { className: cn(iconWrapper), onClick: () => handleOpen("browser"), children: _jsx(SVG.Icon.Browser, { size: isMobile ? "md" : "lg" }) }), _jsx("div", { className: cn(iconWrapper), onClick: () => handleOpen("event"), children: _jsx(SVG.Icon.Event, { size: isMobile ? "md" : "lg" }) })] }) })] }));
|
|
77
109
|
}
|
|
78
110
|
const navigationTypeString = {
|
|
79
111
|
calendar: "시험 접수 일정",
|
|
80
112
|
notification: "공지사항",
|
|
81
113
|
event: "이벤트",
|
|
114
|
+
search: "검색하기",
|
|
82
115
|
};
|
|
83
116
|
function NavigationItem({ type, calendar, notice, event, }) {
|
|
84
117
|
//scroll action
|
|
85
|
-
const container = {
|
|
86
|
-
displays: "relative h-full overflow-hidden",
|
|
87
|
-
};
|
|
88
118
|
const scrollWrapper = {
|
|
89
119
|
displays: "flex flex-row md:flex-col",
|
|
90
120
|
sizss: "h-fit md:h-full",
|
|
@@ -154,13 +184,78 @@ function NavigationItem({ type, calendar, notice, event, }) {
|
|
|
154
184
|
setScheduleState(updatedScheduleState);
|
|
155
185
|
}, [currentTime, calendar.schedules]);
|
|
156
186
|
if (type === "calendar")
|
|
157
|
-
return (_jsxs(
|
|
187
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: cn(scrollWrapper), children: calendar.schedules.map(({ applyEnd, testStart, gradeOpen, title, onClick }, index) => {
|
|
158
188
|
const { isBeforeStart, dDayStart, isBeforeEnd, dDayEnd } = scheduleState[index];
|
|
159
189
|
return (_jsxs("div", { onClick: onClick, className: cn(item, "rounded-[8px] p-5 bg-gray-light/30 border-1 border-gray-light"), children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: cn(titleWrapper), children: [_jsx("div", { className: cn(titleText), children: title }), _jsx("div", { children: isBeforeStart ? (_jsxs("div", { className: cn(tag, "bg-red-burgundy"), children: ["\uC811\uC218\uAE4C\uC9C0 ", dDayStart] })) : isBeforeEnd ? (_jsx("div", { className: cn(tag, "bg-green-dark"), children: "\uC811\uC218 \uC911" })) : (_jsx("div", { className: cn(tag, "bg-gray-medium/30"), children: "\uB9C8\uAC10" })) })] }), !isBeforeStart && isBeforeEnd ? (_jsxs("div", { className: "text-xs", children: ["\uC811\uC218 \uB9C8\uAC10\uAE4C\uC9C0 ", dDayEnd] })) : (""), _jsx("div", { className: "w-full h-0.5 bg-gray-medium" })] }), _jsxs("div", { className: "flex flex-col gap-1 w-full h-fit mt-4", children: [_jsxs("div", { className: cn(dateWrapper), children: [_jsxs("svg", { ...svgAttributes, children: [_jsx("path", { "fill-rule": "evenodd", d: "M11.986 3H12a2 2 0 0 1 2 2v6a2 2 0 0 1-1.5 1.937V7A2.5 2.5 0 0 0 10 4.5H4.063A2 2 0 0 1 6 3h.014A2.25 2.25 0 0 1 8.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM10.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z", "clip-rule": "evenodd" }), _jsx("path", { "fill-rule": "evenodd", d: "M2 7a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7Zm6.585 1.08a.75.75 0 0 1 .336 1.005l-1.75 3.5a.75.75 0 0 1-1.16.234l-1.75-1.5a.75.75 0 0 1 .977-1.139l1.02.875 1.321-2.64a.75.75 0 0 1 1.006-.336Z", "clip-rule": "evenodd" })] }), _jsx("div", { className: cn(paragraphText), children: "\uC811\uC218\uB9C8\uAC10" }), _jsx("div", { className: cn(paragraphText), children: convertDateToString(applyEnd) })] }), _jsxs("div", { className: cn(dateWrapper), children: [_jsx("svg", { ...svgAttributes, children: _jsx("path", { "fill-rule": "evenodd", d: "M4 1.75a.75.75 0 0 1 1.5 0V3h5V1.75a.75.75 0 0 1 1.5 0V3a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2V1.75ZM4.5 6a1 1 0 0 0-1 1v4.5a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-7Z", "clip-rule": "evenodd" }) }), _jsx("div", { className: cn(paragraphText), children: "\uC2DC\uD5D8\uC77C\uC790" }), _jsx("div", { className: cn(paragraphText), children: convertDateToString(testStart) })] }), _jsxs("div", { className: cn(dateWrapper), children: [_jsxs("svg", { ...svgAttributes, children: [_jsx("path", { "fill-rule": "evenodd", d: "M10 3a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v9a2 2 0 0 0 2 2h8a2 2 0 0 1-2-2V3ZM4 4h4v2H4V4Zm4 3.5H4V9h4V7.5Zm-4 3h4V12H4v-1.5Z", "clip-rule": "evenodd" }), _jsx("path", { d: "M13 5h-1.5v6.25a1.25 1.25 0 1 0 2.5 0V6a1 1 0 0 0-1-1Z" })] }), _jsx("div", { className: cn(paragraphText), children: "\uC131\uC801\uBC1C\uD45C" }), _jsx("div", { className: cn(paragraphText), children: convertDateToString(gradeOpen) })] })] })] }));
|
|
160
190
|
}) }), _jsx("div", { className: cn(softBox) })] }));
|
|
161
191
|
if (type === "notification")
|
|
162
|
-
return (_jsxs(
|
|
192
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: cn(scrollWrapper), children: notice.announcements.map(({ title, date, description, onClick }) => (_jsxs("div", { onClick: onClick, className: cn(item, "h-fit shadow-main p-5 "), children: [_jsxs("div", { children: [_jsx("div", { className: "text-[15px] text-gray-medium", children: date }), _jsx("div", { className: cn(titleText, "mb-2"), children: title })] }), _jsx("p", { className: cn(paragraphText, "truncate h-fit"), children: description })] }))) }), _jsx("div", { className: cn(softBox) })] }));
|
|
163
193
|
if (type === "event")
|
|
164
|
-
return (_jsxs(
|
|
194
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: cn(scrollWrapper), children: event.events.map(({ title, thumbnail, onClick }) => (_jsx("div", { onClick: onClick, className: cn(item, " shadow-main rounded-[10px] overflow-hidden"), children: _jsx("div", { className: "image-container", children: _jsx("img", { src: thumbnail, alt: title, className: "w-full bg-cover" }) }) }))) }), _jsx("div", { className: cn(softBox) })] }));
|
|
195
|
+
if (type === "search")
|
|
196
|
+
return _jsx(SearchComponent, {});
|
|
165
197
|
return null;
|
|
166
198
|
}
|
|
199
|
+
function SearchComponent() {
|
|
200
|
+
const inputRef = useRef(null);
|
|
201
|
+
useEffect(() => {
|
|
202
|
+
if (inputRef.current) {
|
|
203
|
+
inputRef.current.focus();
|
|
204
|
+
}
|
|
205
|
+
}, []);
|
|
206
|
+
const handleClear = () => {
|
|
207
|
+
setSearchText("");
|
|
208
|
+
if (inputRef.current)
|
|
209
|
+
inputRef.current.focus();
|
|
210
|
+
};
|
|
211
|
+
const [searchText, setSearchText] = useState("");
|
|
212
|
+
const isEmpty = "" === searchText;
|
|
213
|
+
const { choseongMatch, entireMatch } = search(searchText);
|
|
214
|
+
const handleItemClick = (url) => {
|
|
215
|
+
window.location.href = url;
|
|
216
|
+
};
|
|
217
|
+
const scrollWrapper = {
|
|
218
|
+
displays: "flex flex-col",
|
|
219
|
+
sizss: "h-full",
|
|
220
|
+
scrollActions: "scrollbar-hidden overflow-y-scroll snap-none",
|
|
221
|
+
spacings: "py-5 gap-5 scroll-pl-5",
|
|
222
|
+
};
|
|
223
|
+
const softBox = {
|
|
224
|
+
displays: "absolute top-[61px] left-0",
|
|
225
|
+
sizes: "w-full h-5",
|
|
226
|
+
backgrounds: "bg-gradient-to-b from-white to-white/0",
|
|
227
|
+
};
|
|
228
|
+
const searchBarHeader = {
|
|
229
|
+
displays: "relative flex items-center",
|
|
230
|
+
sizes: "w-full h-fit",
|
|
231
|
+
spacings: "gap-4 px-5 py-4",
|
|
232
|
+
boundaries: "border-b-1",
|
|
233
|
+
//debug: "border-red-500 border-2",
|
|
234
|
+
};
|
|
235
|
+
const inputBox = {
|
|
236
|
+
displays: "flex items-center",
|
|
237
|
+
sizes: "w-full h-7 rounded-sm",
|
|
238
|
+
boundaries: "outline-none",
|
|
239
|
+
textStyles: "font-regular",
|
|
240
|
+
placeHolderStyles: "placeholder-slate-300 caret-slate-300",
|
|
241
|
+
//debug: "border-red-500 border-2",
|
|
242
|
+
};
|
|
243
|
+
const linkBox = {
|
|
244
|
+
displays: "flex items-center justify-between",
|
|
245
|
+
sizes: "w-full h-fit",
|
|
246
|
+
spacings: "px-5 py-3",
|
|
247
|
+
backgrounds: "hover:bg-slate-50 active:bg-slate-50",
|
|
248
|
+
};
|
|
249
|
+
//결과없음 이미지
|
|
250
|
+
const noResultWrapper = {
|
|
251
|
+
displays: "flex flex-col justify-center items-center",
|
|
252
|
+
sizes: "w-full h-fit",
|
|
253
|
+
};
|
|
254
|
+
const noResultImg = {
|
|
255
|
+
spacings: "px-10",
|
|
256
|
+
sizes: "w-full max-w-80",
|
|
257
|
+
};
|
|
258
|
+
return (_jsxs("div", { className: "h-[calc(100vh-300px)] md:h-full w-full", children: [_jsxs("header", { className: cn(searchBarHeader), children: [!isEmpty && (_jsx("div", { className: "absolute w-[calc(100%-40px)] flex justify-end text-gray-medium pointer-events-none", children: _jsx("div", { className: "h-fit w-fit p-1 pointer-events-auto cursor-pointer", onClick: handleClear, children: _jsx(SVG.MiniClose, {}) }) })), _jsxs("form", { className: "flex flex-auto gap-4 min-w-0 w-full", children: [_jsx("label", { className: "h-6 w-6 mt-0.5 text-green-dark", children: _jsx(SVG.Search, {}) }), _jsx("input", { type: "text", className: cn(inputBox), placeholder: "\uBB34\uC5C7\uC774\uB4E0 \uCC3E\uC544\uBCF4\uC138\uC694", value: searchText, ref: inputRef, onChange: (e) => {
|
|
259
|
+
setSearchText(e.target.value);
|
|
260
|
+
} })] })] }), _jsx("div", { className: cn(scrollWrapper), children: !isEmpty ? (choseongMatch.length === 0 && entireMatch.length === 0 ? (_jsxs("div", { className: cn(noResultWrapper), children: [_jsx("div", { className: cn(noResultImg), children: _jsx("img", { src: "https://resource.tosel.co.kr/images/images/no-result.png", alt: "\uACB0\uACFC \uC5C6\uC74C" }) }), _jsx("div", { className: "text-sm text-center w-full font-medium text-green-dark", children: "\uC774\uB7F0, \uAC80\uC0C9\uACB0\uACFC\uAC00 \uC5C6\uC5B4\uC694" }), _jsxs("div", { className: "text-sm text-center w-full font-medium text-green-dark", children: ["'", searchText, "'\uC5D0 \uB300\uD55C \uACB0\uACFC\uAC00 \uD544\uC694\uD55C\uAC00\uC694?"] })] })) : (_jsxs("div", { className: "flex flex-col w-full", children: [entireMatch.map((e) => (_jsxs("div", { className: cn(linkBox), onClick: () => handleItemClick(e[0]), children: [_jsxs("div", { className: "w-full flex justify-start items-center gap-2", children: [_jsx("div", { className: "text-base text-gray-dark font-medium", children: e[1] }), _jsxs("div", { className: "text-sm text-green-dark", children: ["\"", e[2], "\""] })] }), _jsx("div", { className: "w-fit rounded-md shrink-0 text-xs bg-green-dark text-white py-1 px-2", children: "\uC815\uD655\uD788 \uC77C\uCE58!" })] }))), choseongMatch.map((e) => (_jsx("div", { className: cn(linkBox), onClick: () => handleItemClick(e[0]), children: _jsxs("div", { className: "w-full flex justify-start items-center gap-2", children: [_jsx("div", { className: "text-base text-gray-dark font-medium", children: e[1] }), _jsx("div", { className: "text-sm text-gray-medium", children: e[2] })] }) })))] }))) : (_jsxs("div", { className: "flex flex-col w-full justify-center items-start px-5", children: [_jsx("div", { className: "w-full text-green-dark text-base", children: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694" }), _jsx("div", { className: "text-green-dark/50 text-sm", children: "\uCD08\uC131\uC73C\uB85C\uB3C4 \uAC80\uC0C9\uD560 \uC218 \uC788\uC5B4\uC694!" })] })) }), _jsx("div", { className: cn(softBox) })] }));
|
|
261
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edu-tosel/design",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.267",
|
|
4
4
|
"description": "UI components for International TOSEL Committee",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jsx",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"react-qr-code": "^2.0.15",
|
|
33
33
|
"react-router-dom": "^6.21.3",
|
|
34
34
|
"react-spring": "^9.7.3",
|
|
35
|
-
"react-to-print": "^
|
|
35
|
+
"react-to-print": "^3.0.4",
|
|
36
36
|
"react-transition-group": "^4.4.5",
|
|
37
37
|
"react-youtube": "^10.1.0",
|
|
38
38
|
"recharts": "^2.11.0",
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { getChoseong } from "es-hangul";
|
|
2
|
+
const defaultRecord = {
|
|
3
|
+
//소개 페이지
|
|
4
|
+
"/about": ["About TOSEL", "About", "토셀소개"],
|
|
5
|
+
"/about#leadership": [
|
|
6
|
+
"리더십",
|
|
7
|
+
"임원",
|
|
8
|
+
"위원장",
|
|
9
|
+
"총재",
|
|
10
|
+
"출제위원장",
|
|
11
|
+
"이기수",
|
|
12
|
+
"김임득",
|
|
13
|
+
"leadership",
|
|
14
|
+
"board",
|
|
15
|
+
],
|
|
16
|
+
"/about#mission": ["Our Mission", "비전", "목표", "미션", "철학", "가치관"],
|
|
17
|
+
"/about#history": ["연혁", "역사", "history", "설립연도"],
|
|
18
|
+
"/about#area": ["분야", "사업분야", "비즈니스", "bussiness"],
|
|
19
|
+
"/about#partner": [
|
|
20
|
+
"협업",
|
|
21
|
+
"파트너",
|
|
22
|
+
"인증",
|
|
23
|
+
"고려대학교",
|
|
24
|
+
"학회인증",
|
|
25
|
+
"partner",
|
|
26
|
+
"이용기관",
|
|
27
|
+
],
|
|
28
|
+
"/about#media": ["보도자료", "미디어", "media", "뉴스", "언론 속의 토셀"],
|
|
29
|
+
//시험소개
|
|
30
|
+
"/exams": ["시험소개", "레벨", "TOSEL"],
|
|
31
|
+
"/exams#evaluation": [
|
|
32
|
+
"평가방식",
|
|
33
|
+
"연령별 인지단계",
|
|
34
|
+
"평가 기준",
|
|
35
|
+
"CALP",
|
|
36
|
+
"BICS",
|
|
37
|
+
"언어능력 평가",
|
|
38
|
+
"PBT",
|
|
39
|
+
"레벨",
|
|
40
|
+
"Level",
|
|
41
|
+
],
|
|
42
|
+
"/exams#offlineExam": [
|
|
43
|
+
"정기시험 안내",
|
|
44
|
+
"시험 구성",
|
|
45
|
+
"연간 일정",
|
|
46
|
+
"당일 일정",
|
|
47
|
+
"Pre-Starter",
|
|
48
|
+
"Starter",
|
|
49
|
+
"Basic",
|
|
50
|
+
"Junior",
|
|
51
|
+
"High Junior",
|
|
52
|
+
"PS",
|
|
53
|
+
"ST",
|
|
54
|
+
"BA",
|
|
55
|
+
"JR",
|
|
56
|
+
"HJ",
|
|
57
|
+
"프리스타터",
|
|
58
|
+
"스타터",
|
|
59
|
+
"베이직",
|
|
60
|
+
"주니어",
|
|
61
|
+
"하이주니어",
|
|
62
|
+
],
|
|
63
|
+
"/exams#types": [
|
|
64
|
+
"시험 종류",
|
|
65
|
+
"고사장시험",
|
|
66
|
+
"가정시험",
|
|
67
|
+
"학원정기",
|
|
68
|
+
"특별기관시험",
|
|
69
|
+
"기관시험",
|
|
70
|
+
"랩 특별시험",
|
|
71
|
+
],
|
|
72
|
+
//게시판
|
|
73
|
+
"/events": ["이벤트", "새로운 소식"],
|
|
74
|
+
"/books": ["교재", "교재안내"],
|
|
75
|
+
//토셀 북스
|
|
76
|
+
"https://smartstore.naver.com/tosel": [
|
|
77
|
+
"토셀북스",
|
|
78
|
+
"책 구매",
|
|
79
|
+
"TOSEL Books",
|
|
80
|
+
"북스토어",
|
|
81
|
+
"교재구입",
|
|
82
|
+
"교재몰",
|
|
83
|
+
"쇼핑",
|
|
84
|
+
"스마트스토어",
|
|
85
|
+
"네이버스토어",
|
|
86
|
+
"구매하기",
|
|
87
|
+
"문제집",
|
|
88
|
+
],
|
|
89
|
+
//토셀북스-시험대비교재
|
|
90
|
+
"https://smartstore.naver.com/tosel/category/3345d808450940f3a81077bb29b95e55?cp=1": ["시험대비교재"],
|
|
91
|
+
"https://smartstore.naver.com/tosel/category/00590516c9ea4041b17bcea6527850ed?cp=1": ["유형분석집"],
|
|
92
|
+
"https://smartstore.naver.com/tosel/category/263ed55441ee47fc994b7e2e7d77c37f?cp=1": ["예상문제집"],
|
|
93
|
+
"https://smartstore.naver.com/tosel/category/50ea23099a1344d99b0902bfb65305aa?cp=1": ["실전문제집"],
|
|
94
|
+
"https://smartstore.naver.com/tosel/category/f3c92dd261b7497aace96620f760aacd?cp=1": ["심화문제집"],
|
|
95
|
+
"https://smartstore.naver.com/tosel/category/20990897bf944d82861c8a4600b56d82?cp=1": ["기출", "기출연습", "기출세트"],
|
|
96
|
+
//토셀북스-학습교재
|
|
97
|
+
"https://smartstore.naver.com/tosel/category/6099b9ce3fec4f2a8111cb5a2fa153c2?cp=1": ["학습교재", "개념학습"],
|
|
98
|
+
"https://smartstore.naver.com/tosel/category/bde68e05417e4db99a86ebbd4aa3e925?cp=1": ["Reading Series", "리딩", "읽기"],
|
|
99
|
+
"https://smartstore.naver.com/tosel/category/2f11488810464cb5bbe77b004965f4ae?cp=1": ["Listening Series", "리스닝", "듣기"],
|
|
100
|
+
"https://smartstore.naver.com/tosel/category/28dc52dc67a3443ea010812d40accb69?cp=1": ["Speaking Series", "스피킹", "말하기"],
|
|
101
|
+
"https://smartstore.naver.com/tosel/category/78551dca50de4636bc212c46543d4137?cp=1": ["VOCA Series", "보카", "영단어", "단어학습"],
|
|
102
|
+
"https://smartstore.naver.com/tosel/category/c88067049a904b8e8d78ada305b2779b?cp=1": ["Grammar Series", "그래머", "영문법", "문법"],
|
|
103
|
+
"https://smartstore.naver.com/tosel/category/cd8df3ab036942f7a3ea6e14a7ab3a9a?cp=1": ["Story Series", "스토리", "읽기"],
|
|
104
|
+
//토셀북스-레벨별교재
|
|
105
|
+
"https://smartstore.naver.com/tosel/category/637c92ebd5af435b98c89926ebdcf4d5?cp=1": ["Cocoon 교재", "Cocoon", "코쿤"],
|
|
106
|
+
"https://smartstore.naver.com/tosel/category/b0fc9b0937854a8baffb9a2bd8c35d0f?cp=1": ["Pre-Starter 교재", "Pre-Starter", "프리스타터", "PS", "초등"],
|
|
107
|
+
"https://smartstore.naver.com/tosel/category/3db386ace57846d2a52bb95b21b47954?cp=1": ["Starter 교재", "Starter", "스타터", "ST", "초등"],
|
|
108
|
+
"https://smartstore.naver.com/tosel/category/cd2d05f9b3014ead8b6da998eff17c9b?cp=1": ["Basic 교재", "Basic", "베이직", "BA", "초등"],
|
|
109
|
+
"https://smartstore.naver.com/tosel/category/52cdb446f4ae45c7a865401f14d3cd6b?cp=1": ["Junior 교재", "Junior", "주니어", "JR", "중등"],
|
|
110
|
+
"https://smartstore.naver.com/tosel/category/abb1a40e47754d8ebd229daa3d7a0fe9?cp=1": ["High Junior 교재", "하이주니어", "HJ", "고등"],
|
|
111
|
+
"https://smartstore.naver.com/tosel/category/216102719f724819a9d55f40ab032be5?cp=1": ["Advanced 교재", "어드밴스트", "성인"],
|
|
112
|
+
//토셀북스-굿즈
|
|
113
|
+
"https://smartstore.naver.com/tosel/category/19e0ceb5c1d84b09a3b4b8110edb1803?cp=1": ["굿즈", "책받침", "볼펜", "다이어리", "캘린더", "오답노트", "단어장"],
|
|
114
|
+
// 올림피아드 랜딩페이지
|
|
115
|
+
"/olympiad": ["올림피아드", "보카", "VOCA", "단어"],
|
|
116
|
+
"/olympiad#features": [
|
|
117
|
+
"올림피아드 특징",
|
|
118
|
+
"특징",
|
|
119
|
+
"올림피아드",
|
|
120
|
+
"보카",
|
|
121
|
+
"VOCA",
|
|
122
|
+
],
|
|
123
|
+
// 토셀랩 랜딩페이지
|
|
124
|
+
"https://labentry.tosel.co.kr/": ["토셀 랩", "토셀 랩 심사신청", "Lab", "랩"],
|
|
125
|
+
"/dashboard/academy/students": [
|
|
126
|
+
"학생 관리",
|
|
127
|
+
"학생 추가",
|
|
128
|
+
"원생관리",
|
|
129
|
+
"원생 삭제",
|
|
130
|
+
"원생 아이디",
|
|
131
|
+
],
|
|
132
|
+
// 고객센터
|
|
133
|
+
"https://connect.tosel.co.kr/": [
|
|
134
|
+
"고객센터",
|
|
135
|
+
"CS",
|
|
136
|
+
"홈",
|
|
137
|
+
"Customer",
|
|
138
|
+
"문의하기",
|
|
139
|
+
],
|
|
140
|
+
"https://connect.tosel.co.kr/agencies": [
|
|
141
|
+
"지역본부 정보",
|
|
142
|
+
"본부장",
|
|
143
|
+
"영업코드",
|
|
144
|
+
"전화",
|
|
145
|
+
],
|
|
146
|
+
"https://tosel-faq.notion.site/": [
|
|
147
|
+
"TOSEL 이용 가이드",
|
|
148
|
+
"FAQ",
|
|
149
|
+
"Q&A",
|
|
150
|
+
"질문",
|
|
151
|
+
"help center",
|
|
152
|
+
"헬프 센터",
|
|
153
|
+
"안내",
|
|
154
|
+
"도움말",
|
|
155
|
+
],
|
|
156
|
+
"https://tosel-faq.notion.site/150de6b860e280f4a30fe49d8c300584": [
|
|
157
|
+
"정기시험 관리규정",
|
|
158
|
+
],
|
|
159
|
+
"/dashboard/user/applications": ["접수하기", "정기시험"],
|
|
160
|
+
"http://localhost:5174/olympiad#features": ["올림피아드 안내"],
|
|
161
|
+
};
|
|
162
|
+
function createSearch({ record, } = {}) {
|
|
163
|
+
record = record ?? defaultRecord;
|
|
164
|
+
const recordEntries = Object.entries(record);
|
|
165
|
+
const isHangul = (str) => /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/.test(str);
|
|
166
|
+
const entries = recordEntries
|
|
167
|
+
.map(([key, values]) => values.map((value) => [key, value]))
|
|
168
|
+
.flat();
|
|
169
|
+
const choseongEntries = entries.map(([key, value]) => [
|
|
170
|
+
key,
|
|
171
|
+
isHangul(value)
|
|
172
|
+
? getChoseong(value).replace(/ /g, "")
|
|
173
|
+
: value.toLowerCase(),
|
|
174
|
+
]);
|
|
175
|
+
const calculateMatchScore = (value, query) => {
|
|
176
|
+
const queryIndex = value.indexOf(query);
|
|
177
|
+
if (queryIndex === -1)
|
|
178
|
+
return 0;
|
|
179
|
+
// 일치율 = (검색어 길이 / 전체 단어 길이) * 100
|
|
180
|
+
const matchRatio = (query.length / value.length) * 100;
|
|
181
|
+
// 점수 계산: 앞에 있을수록 + 검색어 비율이 높을수록 가산점
|
|
182
|
+
return 100 - queryIndex * 5 + matchRatio * 2;
|
|
183
|
+
};
|
|
184
|
+
const search = (query) => {
|
|
185
|
+
const lowerQuery = query.toLowerCase();
|
|
186
|
+
const isHangulQuery = isHangul(query);
|
|
187
|
+
const queryChoseong = isHangulQuery ? getChoseong(query) : "";
|
|
188
|
+
// **정확한 일치 (Exact Match)**
|
|
189
|
+
const entireMatch = entries
|
|
190
|
+
.filter(([_, value]) => {
|
|
191
|
+
const normalizedValue = value.toLowerCase();
|
|
192
|
+
return (normalizedValue === lowerQuery ||
|
|
193
|
+
new RegExp(`\\b${lowerQuery}`).test(normalizedValue));
|
|
194
|
+
})
|
|
195
|
+
.map(([key, value]) => [
|
|
196
|
+
key,
|
|
197
|
+
record[key]?.[0] ?? value, // 첫 번째 키워드가 없을 경우 value를 기본값으로 사용
|
|
198
|
+
value,
|
|
199
|
+
]);
|
|
200
|
+
// **초성 매칭 (Choseong Match)**
|
|
201
|
+
const choseongMatch = isHangulQuery
|
|
202
|
+
? choseongEntries
|
|
203
|
+
.map((value, index) => ({ index, value }))
|
|
204
|
+
.filter(({ value: [_, value] }) => value.includes(queryChoseong))
|
|
205
|
+
.map(({ index }) => {
|
|
206
|
+
const key = entries[index][0];
|
|
207
|
+
return [
|
|
208
|
+
key,
|
|
209
|
+
record[key]?.[0] ?? entries[index][1], // 첫 번째 키워드가 없을 경우 대체
|
|
210
|
+
entries[index][1],
|
|
211
|
+
];
|
|
212
|
+
})
|
|
213
|
+
: [];
|
|
214
|
+
// **중복 제거 (EntireMatch에 포함된 키 제거)**
|
|
215
|
+
const entireMatchKeys = new Set(entireMatch.map(([key]) => key));
|
|
216
|
+
const filteredChoseongMatch = choseongMatch.filter(([key]) => !entireMatchKeys.has(key));
|
|
217
|
+
// **가장 유사한 결과를 먼저 정렬**
|
|
218
|
+
const sortResults = (results) => {
|
|
219
|
+
return results
|
|
220
|
+
.map((item) => ({
|
|
221
|
+
data: item,
|
|
222
|
+
score: calculateMatchScore(item[2], query), // 검색어 포함도 계산
|
|
223
|
+
}))
|
|
224
|
+
.sort((a, b) => b.score - a.score) // 높은 점수순으로 정렬
|
|
225
|
+
.map((item) => item.data);
|
|
226
|
+
};
|
|
227
|
+
return {
|
|
228
|
+
entireMatch: sortResults(entireMatch),
|
|
229
|
+
choseongMatch: sortResults(filteredChoseongMatch),
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
return { search };
|
|
233
|
+
}
|
|
234
|
+
const { search } = createSearch();
|
|
235
|
+
export default search;
|
package/util/handlePrint.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const handlePrint: (ref: React.RefObject<HTMLDivElement>) => (
|
|
1
|
+
declare const handlePrint: (ref: React.RefObject<HTMLDivElement>) => import("react-to-print").UseReactToPrintFn;
|
|
2
2
|
export default handlePrint;
|
package/util/handlePrint.js
CHANGED
package/util/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { default as copyToClipboard } from "./copyToClipboard";
|
|
|
11
11
|
export { default as createRecord } from "./createRecord";
|
|
12
12
|
export { default as formatMobileNum } from "./formatPhoneNumberToE164";
|
|
13
13
|
export { default as formatKorPhoneNum } from "./formatKoreanPhoneNumber";
|
|
14
|
+
export { default as search } from "./createSearch";
|
|
14
15
|
export * from "../style/colors";
|
|
15
16
|
export * from "./pattern";
|
|
16
17
|
export * from "./shape";
|
package/util/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export { default as copyToClipboard } from "./copyToClipboard";
|
|
|
11
11
|
export { default as createRecord } from "./createRecord";
|
|
12
12
|
export { default as formatMobileNum } from "./formatPhoneNumberToE164";
|
|
13
13
|
export { default as formatKorPhoneNum } from "./formatKoreanPhoneNumber";
|
|
14
|
+
export { default as search } from "./createSearch";
|
|
14
15
|
export * from "../style/colors";
|
|
15
16
|
export * from "./pattern";
|
|
16
17
|
export * from "./shape";
|
package/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.267
|
|
@@ -3,6 +3,8 @@ import { useId, useRef, useState } from "react";
|
|
|
3
3
|
import { cn } from "../../../util";
|
|
4
4
|
import Obstacle from "../Obstacle";
|
|
5
5
|
import Form from "./Form";
|
|
6
|
+
import { useResponsive } from "../../../hook";
|
|
7
|
+
import Label from "../Label";
|
|
6
8
|
const widthSize = {
|
|
7
9
|
xs: "w-28",
|
|
8
10
|
sm: "w-48",
|
|
@@ -13,6 +15,7 @@ const widthSize = {
|
|
|
13
15
|
full: "w-full",
|
|
14
16
|
};
|
|
15
17
|
function Input({ state, onKeyDown, placeholder, option }) {
|
|
18
|
+
const isSm = useResponsive("sm");
|
|
16
19
|
const { width, disabled } = option ?? {};
|
|
17
20
|
const [value, setValue] = state;
|
|
18
21
|
const ref = useRef(null);
|
|
@@ -42,6 +45,11 @@ function Input({ state, onKeyDown, placeholder, option }) {
|
|
|
42
45
|
styles: "focus:outline-none bg-transparent",
|
|
43
46
|
pointers: "cursor-default",
|
|
44
47
|
};
|
|
48
|
+
if (!isSm)
|
|
49
|
+
return (_jsx(Label.Button, { title: "\uAC80\uC0C9", option: {
|
|
50
|
+
width: "3xs",
|
|
51
|
+
height: "2xs",
|
|
52
|
+
} }));
|
|
45
53
|
return (_jsx("div", { className: cn(container), children: _jsxs("div", { className: cn(body), onClick: () => ref.current?.focus(), children: [_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "25", height: "25", viewBox: "0 0 25 25", fill: "none", children: _jsx("path", { d: "M21.8758 21.8748L16.4623 16.4613M16.4623 16.4613C17.9275 14.9961 18.7506 13.0089 18.7506 10.9368C18.7506 8.86474 17.9275 6.87752 16.4623 5.41234C14.9971 3.94715 13.0099 3.12402 10.9378 3.12402C8.86571 3.12402 6.8785 3.94715 5.41331 5.41234C3.94813 6.87752 3.125 8.86474 3.125 10.9368C3.125 13.0089 3.94813 14.9961 5.41331 16.4613C6.8785 17.9265 8.86571 18.7496 10.9378 18.7496C13.0099 18.7496 14.9971 17.9265 16.4623 16.4613Z", stroke: "#105652", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }) }), _jsx("input", { id: id, ref: ref, className: cn(inputBox), type: "text", value: value, onFocus: () => setIsFocus(true), onBlur: () => setIsFocus(false), placeholder: typeof placeholder === "function"
|
|
46
54
|
? placeholder()
|
|
47
55
|
: placeholder ?? "입력해주세요", onKeyDown: onKeyDown && ((e) => onKeyDown(e, value ?? "")), onChange: (e) => setValue(e.target.value) }), _jsx(Obstacle, { disabled: disabled })] }) }));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function SectionA(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect } from "react";
|
|
3
|
-
import { cn } from "../../../util";
|
|
4
|
-
import { useVisibilityObserver } from "../../../hook";
|
|
5
|
-
export default function SectionA() {
|
|
6
|
-
const [isHidden, setIsHidden] = useState(false);
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
const handleScroll = () => {
|
|
9
|
-
if (window.scrollY > 50) {
|
|
10
|
-
setIsHidden(true);
|
|
11
|
-
}
|
|
12
|
-
else {
|
|
13
|
-
setIsHidden(false);
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
window.addEventListener("scroll", handleScroll);
|
|
17
|
-
return () => {
|
|
18
|
-
window.removeEventListener("scroll", handleScroll);
|
|
19
|
-
};
|
|
20
|
-
}, []);
|
|
21
|
-
const handleScroll = () => {
|
|
22
|
-
window.scrollBy({
|
|
23
|
-
top: window.innerHeight,
|
|
24
|
-
behavior: "smooth",
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
const scrollGuideWrapper = {
|
|
28
|
-
display: "absolute hidden md:flex flex-col justify-center items-center z-10",
|
|
29
|
-
sizes: "w-full",
|
|
30
|
-
spacings: "bottom-0 mb-10",
|
|
31
|
-
scrollAction: `transition-opacity duration-500 ${isHidden ? "opacity-0" : "opacity-100"}`,
|
|
32
|
-
};
|
|
33
|
-
const scrollGuideText = {
|
|
34
|
-
sizes: "w-full",
|
|
35
|
-
textstyles: "font-medium text-white text-base",
|
|
36
|
-
spacings: "text-center",
|
|
37
|
-
};
|
|
38
|
-
const scrollGuideButton = {
|
|
39
|
-
sizes: "w-10 h-10 mt-10",
|
|
40
|
-
other: "animate-bounce p-1 w-10 h-10 ring-1 ring-slate-900/5 shadow-lg rounded-full flex items-center justify-center",
|
|
41
|
-
};
|
|
42
|
-
const titleWrapper = {
|
|
43
|
-
displays: "flex flex-col justify-center items-center md:items-start",
|
|
44
|
-
sizes: "w-[1200px] h-full",
|
|
45
|
-
spacings: "gap-8",
|
|
46
|
-
textstyles: "text-white",
|
|
47
|
-
animation: "transform transition-all duration-1000 delay-0 ease-in-out",
|
|
48
|
-
};
|
|
49
|
-
const { isVisible, elementRef } = useVisibilityObserver(0.1, true);
|
|
50
|
-
return (_jsxs("div", { className: "relative w-full h-screen bg-[url('/images/aboutus/bg/img-aboutus-cover-min.png')] flex py-55 justify-center bg-cover bg-center px-5 z-0", children: [_jsxs("div", { className: cn(scrollGuideWrapper), children: [_jsx("div", { className: cn(scrollGuideText), children: "\uC790\uC138\uD55C \uB0B4\uC6A9\uC744 \uBCF4\uB824\uBA74 \uC544\uB798\uB85C \uC2A4\uD06C\uB864 \uD574\uBCF4\uC138\uC694" }), _jsx("div", { className: cn(scrollGuideButton), onClick: handleScroll, children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "1.5", stroke: "currentColor", className: "size-6 text-white", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m19.5 8.25-7.5 7.5-7.5-7.5" }) }) })] }), _jsx("div", { className: "absolute h-screen w-full bg-gradient-to-b from-black/0 to-black z-0 top-0" }), _jsxs("div", { className: cn(titleWrapper, isVisible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"), children: [_jsx("div", { className: "text-lg md:text-xl z-10", ref: elementRef, children: "30,000\uC5EC\uAC1C\uC758 \uD559\uAD50\uC640 \uD559\uC6D0\uC758 \uC120\uD0DD" }), _jsxs("div", { className: "text-[32px] md:text-6xl font-bold text-center md:text-left z-10", children: ["\uB300\uD55C\uBBFC\uAD6D\uC744 \uB300\uD45C\uD558\uB294", _jsx("br", {}), "\uC601\uC5B4\uC778\uC99D\uC2DC\uD5D8"] }), _jsx("img", { src: "/images/aboutus/p1-min.png", alt: "", className: "object-fit w-70 z-10" })] })] }));
|
|
51
|
-
}
|