@edu-tosel/design 1.0.261 → 1.0.263
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/board/design/Board.design.js +6 -5
- package/board/design/Header.design.js +3 -7
- package/board/template/CanvasBoard.js +6 -3
- package/card/design/NavCard.design.js +3 -2
- package/card/design/StickCard.design.d.ts +2 -0
- package/card/design/StickCard.design.js +40 -0
- package/card/index.d.ts +1 -0
- package/card/index.js +1 -0
- package/card/template/NavCard.js +2 -1
- package/card/template/ProgressCard/Large.js +15 -10
- package/card/template/StickCard.d.ts +3 -0
- package/card/template/StickCard.js +6 -0
- package/hook/index.d.ts +1 -0
- package/hook/index.js +1 -0
- package/hook/useBussinessHours.d.ts +2 -0
- package/hook/useBussinessHours.js +26 -0
- package/interface/Card.d.ts +7 -0
- package/interface/Layout.d.ts +1 -0
- package/interface/Shelf.d.ts +5 -5
- package/layout/design/Shelf.design.d.ts +1 -1
- package/layout/design/Shelf.design.js +5 -3
- package/layout/template/Contact/Contact.d.ts +13 -0
- package/layout/template/Contact/Contact.js +16 -0
- package/layout/template/Contact/ContactAgency.d.ts +7 -0
- package/layout/template/Contact/ContactAgency.js +162 -0
- package/layout/template/Contact/ContactMain.d.ts +7 -0
- package/layout/template/Contact/ContactMain.js +66 -0
- package/layout/template/Contact/Header.d.ts +3 -0
- package/layout/template/Contact/Header.js +37 -0
- package/layout/template/Contact/index.d.ts +7 -0
- package/layout/template/Contact/index.js +7 -0
- package/layout/template/Gallery.js +6 -3
- package/layout/template/Shelf.d.ts +6 -4
- package/layout/template/Shelf.js +33 -5
- package/layout/template/Tab.js +7 -7
- package/layout/template/dashboard/Header.d.ts +1 -1
- package/layout/template/dashboard/Header.js +43 -17
- package/layout/template/dashboard/Layout.js +11 -6
- package/layout/template/dashboard/Navigation.d.ts +2 -1
- package/layout/template/dashboard/Navigation.js +20 -3
- package/layout/template/dashboard/buttonClassNames.js +2 -2
- package/layout/template/dashboard/style.js +2 -1
- package/package.json +2 -1
- package/tailwind.config.ts +13 -1
- package/util/copyToClipboard.d.ts +1 -1
- package/util/copyToClipboard.js +4 -3
- package/util/formatPhoneNumberToE164.d.ts +1 -0
- package/util/formatPhoneNumberToE164.js +18 -0
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/version.txt +1 -1
|
@@ -15,25 +15,26 @@ const heightSize = {
|
|
|
15
15
|
xs: "h-20",
|
|
16
16
|
sm: "h-24",
|
|
17
17
|
md: "h-28",
|
|
18
|
-
lg: "h-full xl:h-
|
|
19
|
-
xl: "h-full xl:h-
|
|
18
|
+
lg: "h-full xl:h-full",
|
|
19
|
+
xl: "h-full xl:h-full",
|
|
20
20
|
"2xl": "h-40",
|
|
21
|
-
full: "min-h-
|
|
21
|
+
full: "min-h-auto h-full",
|
|
22
22
|
auto: "h-auto",
|
|
23
23
|
};
|
|
24
24
|
export function Board({ children, action, option, debug, buttons, }) {
|
|
25
25
|
const { shows } = action ?? {};
|
|
26
26
|
const { width, height, isRounded, className, noMobile, background, boundary, } = option ?? {};
|
|
27
27
|
const container = {
|
|
28
|
-
positions: "relative",
|
|
28
|
+
positions: "relative flex-col justify-start",
|
|
29
29
|
width: widthSize[width ?? "full"],
|
|
30
30
|
noMobile: noMobile && "hidden xl:block",
|
|
31
31
|
debug: debug && isDebug(`border-2 border-${debug}`),
|
|
32
|
+
height: "h-[calc(100%-56px)]",
|
|
32
33
|
};
|
|
33
34
|
const body = {
|
|
34
35
|
positions: "relative",
|
|
35
36
|
sizes: `w-full ${heightSize[height ?? "xl"]}`,
|
|
36
|
-
background: `${background ?? "bg-white"} `,
|
|
37
|
+
background: `${background ?? "bg-white/50"} `,
|
|
37
38
|
styles: "text-black overflow-hidden",
|
|
38
39
|
rounded: `rounded-none ${isRounded ? "xl:rounded-xl" : ""}`,
|
|
39
40
|
boundary: boundary ?? "border-0",
|
|
@@ -6,17 +6,13 @@ export default function BoardHeader({ titles, tag, option, }) {
|
|
|
6
6
|
const { selects, inputs } = tag ?? {};
|
|
7
7
|
const { background, text, boundary } = option ?? {};
|
|
8
8
|
const container = {
|
|
9
|
-
positions: "
|
|
9
|
+
positions: "top-0 left-0 z-30 relative flex items-center",
|
|
10
10
|
paddings: "px-7.5",
|
|
11
11
|
backgrounds: background ?? "bg-white",
|
|
12
12
|
texts: text ?? "text-black",
|
|
13
|
-
sizes: "w-full h-
|
|
13
|
+
sizes: "w-full h-15",
|
|
14
14
|
boundary: boundary ?? "border-b-2 border-green-dark ",
|
|
15
15
|
rounded: "xl:rounded-t-xl",
|
|
16
16
|
};
|
|
17
|
-
|
|
18
|
-
displays: "xl:hidden block ",
|
|
19
|
-
sizes: "w-full h-19",
|
|
20
|
-
};
|
|
21
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: cn(container), children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [icon && _jsx("img", { src: icon, className: "fill-blue-500" }), _jsx("div", { className: `text-2xl font-pretendard-bold ${titleColor}`, children: title })] }), _jsxs("div", { className: "relative flex items-center ml-auto gap-4", children: [selects?.map(({ selectOptions, option, state }) => (_jsx(Select, { option: option, selectOptions: selectOptions, state: state }, title))), inputs?.map((prop, index) => (_jsx(Input, { ...prop }, index)))] })] }), _jsx("div", { className: cn(block) })] }));
|
|
17
|
+
return (_jsx(_Fragment, { children: _jsxs("div", { className: cn(container), children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [icon && _jsx("img", { src: icon, className: "fill-blue-500" }), _jsx("div", { className: `text-2xl font-pretendard-bold ${titleColor}`, children: title })] }), _jsxs("div", { className: "relative flex items-center ml-auto gap-4", children: [selects?.map(({ selectOptions, option, state }) => (_jsx(Select, { option: option, selectOptions: selectOptions, state: state }, title))), inputs?.map((prop, index) => (_jsx(Input, { ...prop }, index)))] })] }) }));
|
|
22
18
|
}
|
|
@@ -4,11 +4,14 @@ import { cn } from "../../util";
|
|
|
4
4
|
import { Board } from "../design/Board.design";
|
|
5
5
|
import BoardHeader from "../design/Header.design";
|
|
6
6
|
export default function CanvasBoard({ header, children, action, buttons, option, }) {
|
|
7
|
+
const scrollWrapper = {
|
|
8
|
+
sizes: "w-full",
|
|
9
|
+
};
|
|
7
10
|
const body = {
|
|
8
11
|
displays: "flex flex-col lg:flex-row lg:flex-wrap gap-7.5",
|
|
9
|
-
sizes: "h-
|
|
10
|
-
paddings: `${header ? "pb-
|
|
11
|
-
|
|
12
|
+
sizes: "h-[calc(100%-60px)]",
|
|
13
|
+
paddings: `${header ? "pb-5" : "pb-36 xl:pb-6"} px-2 xs:px-4 xl:px-7.5 pt-2 xs:pt-4 xl:pt-7.5`,
|
|
14
|
+
scrollStyles: "overflow-y-scroll scrollbar-hidden",
|
|
12
15
|
classNames: option?.className,
|
|
13
16
|
};
|
|
14
17
|
return (_jsxs(Board, { action: action, buttons: buttons, option: { ...option, className: "", isRounded: true }, children: [header && _jsx(BoardHeader, { ...header }), _jsx(Action.Replace, { actions: action?.replaces, children: _jsx("div", { className: cn(body), children: children }) })] }));
|
|
@@ -9,8 +9,9 @@ export default function NavCardDesign({ titles, option }) {
|
|
|
9
9
|
const flag = !buttonInLay && width === "xl";
|
|
10
10
|
const textBox = {
|
|
11
11
|
container: {
|
|
12
|
-
positons: `absolute z-10 ${flag ? "
|
|
12
|
+
positons: `absolute z-10 top-0 left-0 ${flag ? "p-0 pl-12" : "p-7.5"}`,
|
|
13
13
|
sizes: flag && "h-full",
|
|
14
|
+
width: "w-full",
|
|
14
15
|
displays: `flex flex-col ${flag ? "gap-7.5 justify-center" : "gap-2.5"}`,
|
|
15
16
|
styles: `${color ?? "text-gray-dim"}`,
|
|
16
17
|
},
|
|
@@ -30,7 +31,7 @@ export default function NavCardDesign({ titles, option }) {
|
|
|
30
31
|
className: image?.className,
|
|
31
32
|
};
|
|
32
33
|
return (_jsxs(Card, { option: option, children: [_jsxs("div", { className: cn(textBox.container), children: [_jsx("div", { className: cn(textBox.title), children: title }), _jsx(LineBreaks, { className: cn(textBox.subtitle), texts: subtitle ?? "" })] }), buttonInLay && (_jsx(Label.Button, { title: buttonInLay.title, onClick: buttonInLay.onClick, option: {
|
|
33
|
-
className: "absolute bottom-7.5
|
|
34
|
+
className: "absolute bottom-7.5 right-7.5",
|
|
34
35
|
disabled: buttonInLay.disabled,
|
|
35
36
|
background: buttonInLay?.background,
|
|
36
37
|
text: buttonInLay?.text,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../util";
|
|
3
|
+
import { useResponsive } from "../../hook";
|
|
4
|
+
export default function StickCardDesign({ titles, buttonInLay, option, }) {
|
|
5
|
+
const { title, subtitle, color, titleColor, subtitleColor } = titles;
|
|
6
|
+
const { background } = option ?? {};
|
|
7
|
+
const isXS = useResponsive("xs");
|
|
8
|
+
const container = {
|
|
9
|
+
display: "flex justify-between items-center ",
|
|
10
|
+
sizes: "w-full h-15 rounded-xl",
|
|
11
|
+
backgrounds: background ?? "bg-white",
|
|
12
|
+
shadow: "shadow-main",
|
|
13
|
+
spacings: "px-2 md:px-5",
|
|
14
|
+
cursor: "cursor-default",
|
|
15
|
+
};
|
|
16
|
+
const titleWrapper = {
|
|
17
|
+
display: "flex flex-shrink justify-start items-center",
|
|
18
|
+
sizes: "w-full h-full",
|
|
19
|
+
spacings: "gap-2 md:gap-5",
|
|
20
|
+
//debug: "bg-green-500",
|
|
21
|
+
};
|
|
22
|
+
const titleText = {
|
|
23
|
+
sizes: "w-fit shrink-0",
|
|
24
|
+
mainstyle: "font-bold",
|
|
25
|
+
optional: titleColor ?? "text-green-dark",
|
|
26
|
+
};
|
|
27
|
+
const subtitleText = {
|
|
28
|
+
sizes: "w-full",
|
|
29
|
+
mainstyle: "font-medium truncate",
|
|
30
|
+
optional: subtitleColor ?? "text-gray-dark",
|
|
31
|
+
};
|
|
32
|
+
const buttonStyles = {
|
|
33
|
+
display: "flex justify-start items-center",
|
|
34
|
+
sizes: "w-fit h-8 rounded-md shrink-0 px-4",
|
|
35
|
+
textStyles: "text-center text-xs text-white",
|
|
36
|
+
backgrounds: buttonInLay?.background ?? "bg-green-dark",
|
|
37
|
+
cursor: "cursor-pointer",
|
|
38
|
+
};
|
|
39
|
+
return (_jsxs("div", { className: cn(container), children: [_jsxs("div", { className: cn(titleWrapper), children: [_jsx("div", { className: cn(titleText), children: title }), isXS && _jsx("div", { className: cn(subtitleText), children: subtitle })] }), buttonInLay && (_jsx("div", { className: cn(buttonStyles), children: buttonInLay.title }))] }));
|
|
40
|
+
}
|
package/card/index.d.ts
CHANGED
|
@@ -9,3 +9,4 @@ export { default as ProgressCard } from "./template/ProgressCard";
|
|
|
9
9
|
export { default as RollCard } from "./template/RollCard";
|
|
10
10
|
export { default as TableCard } from "./template/TableCard";
|
|
11
11
|
export { default as SubmitCard } from "./template/SubmitCard";
|
|
12
|
+
export { default as StickCard } from "./template/StickCard";
|
package/card/index.js
CHANGED
|
@@ -9,3 +9,4 @@ export { default as ProgressCard } from "./template/ProgressCard";
|
|
|
9
9
|
export { default as RollCard } from "./template/RollCard";
|
|
10
10
|
export { default as TableCard } from "./template/TableCard";
|
|
11
11
|
export { default as SubmitCard } from "./template/SubmitCard";
|
|
12
|
+
export { default as StickCard } from "./template/StickCard";
|
package/card/template/NavCard.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import NavCardDesign from "../design/NavCard.design";
|
|
3
|
+
import { StickCard } from "..";
|
|
3
4
|
function Banner({ titles, option }) {
|
|
4
5
|
return (_jsx(NavCardDesign, { titles: titles, option: {
|
|
5
6
|
...option,
|
|
@@ -41,7 +42,7 @@ function BannerAndButtonInLay({ banner, buttonInLay, }) {
|
|
|
41
42
|
...buttonInLay,
|
|
42
43
|
option: { ...buttonInLay.option, noShadow: true },
|
|
43
44
|
};
|
|
44
|
-
return (_jsxs("div", { className: "flex w-full", children: [_jsx("div", { className: "
|
|
45
|
+
return (_jsxs("div", { className: "flex md:flex-row flex-col w-full", children: [_jsx("div", { className: "rounded-xl w-full", children: _jsx(Banner, { ...bannerProps }) }), _jsx("div", { className: "rounded-xl md:block hidden", children: _jsx(ButtonInLay, { ...buttonInLayProps }) }), _jsx("div", { className: "rounded-xl block md:hidden", children: _jsx(StickCard, { buttonInLay: buttonInLay.buttonInLay, titles: buttonInLay.titles, option: buttonInLay.option }) })] }));
|
|
45
46
|
}
|
|
46
47
|
const NavCard = {
|
|
47
48
|
Banner,
|
|
@@ -16,9 +16,14 @@ const text = {
|
|
|
16
16
|
blue: "text-blue-navy",
|
|
17
17
|
};
|
|
18
18
|
export default function ProgressCardLG({ titles, checks, displays, theme, option, }) {
|
|
19
|
+
const contentsWrapper = {
|
|
20
|
+
displays: "flex flex-col justify-center items-center",
|
|
21
|
+
sizes: "w-full h-full",
|
|
22
|
+
spacings: "gap-5",
|
|
23
|
+
};
|
|
19
24
|
const progressBox = {
|
|
20
|
-
positions: "absolute top-7.5 left-7.5",
|
|
21
|
-
displays: "hidden
|
|
25
|
+
positions: "px-5 xl:p-0 xl:absolute top-7.5 left-7.5",
|
|
26
|
+
displays: "hidden sm:flex justify-start items-center",
|
|
22
27
|
sizes: "w-150 h-19",
|
|
23
28
|
};
|
|
24
29
|
const stepBox = (flag) => ({
|
|
@@ -29,16 +34,16 @@ export default function ProgressCardLG({ titles, checks, displays, theme, option
|
|
|
29
34
|
texts: flag ? "text-gray-dark" : "text-gray-medium",
|
|
30
35
|
});
|
|
31
36
|
const titleBox = {
|
|
32
|
-
positions: "absolute top-7.5 md:top-12 right-4 md:right-12",
|
|
33
|
-
displays: "flex flex-col items-end gap-y-3",
|
|
37
|
+
positions: " xl:absolute top-7.5 md:top-12 right-4 md:right-12",
|
|
38
|
+
displays: "flex flex-col sm:flex-row gap-x-5 xl:flex-col items-center xl:items-end gap-y-3",
|
|
34
39
|
};
|
|
35
40
|
const occupied = Math.round((checks.filter((value) => !!value).length / displays.length) * 100);
|
|
36
|
-
return (
|
|
41
|
+
return (_jsx(CardDesign, { option: {
|
|
37
42
|
...option,
|
|
38
|
-
width: "
|
|
43
|
+
width: "full",
|
|
39
44
|
height: "2xs",
|
|
40
|
-
}, children: [_jsx("div", { className: cn(progressBox), children: displays.map(({ title }, index) => (_jsxs("div", { className: cn(stepBox(checks[index])), children: [_jsx("div", { children: title }), _jsx(SVG.Operation.Checked, { flag: checks[index], size: 25, theme: theme })] }, title))) }), _jsxs("div", { className: cn(titleBox), children: [_jsx("div", { className: `text-xl leading-none font-pretendard-bold ${text[theme ?? "green"]}`, children: titles.title }), _jsxs("div", { className: "flex gap-x-3", children: [_jsx("div", { className: "text-base leading-none", children: titles.subtitle }), titles && titles.link && (_jsx("div", { onClick: () => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
}, children: _jsxs("div", { className: cn(contentsWrapper), children: [_jsx("div", { className: cn(progressBox), children: displays.map(({ title }, index) => (_jsxs("div", { className: cn(stepBox(checks[index])), children: [_jsx("div", { children: title }), _jsx(SVG.Operation.Checked, { flag: checks[index], size: 25, theme: theme })] }, title))) }), _jsxs("div", { className: cn(titleBox), children: [_jsx("div", { className: `text-xl leading-none font-pretendard-bold ${text[theme ?? "green"]}`, children: titles.title }), _jsxs("div", { className: "flex gap-x-3", children: [_jsx("div", { className: "text-base leading-none", children: titles.subtitle }), titles && titles.link && (_jsx("div", { onClick: () => {
|
|
46
|
+
if (titles.link)
|
|
47
|
+
window.location.href = titles.link.path;
|
|
48
|
+
}, className: "text-base leading-none underline text-gray-medium", children: titles.link.title }))] })] }), _jsx("div", { className: "absolute bottom-0 left-0 bg-gray-light w-full h-2.5", children: _jsx("div", { className: `h-full ${widthSizes[occupied]} ${bg[theme ?? "green"]}` }) })] }) }));
|
|
44
49
|
}
|
package/hook/index.d.ts
CHANGED
|
@@ -6,3 +6,4 @@ export { default as useScroll } from "./useScroll";
|
|
|
6
6
|
export { default as useSmoothScroll } from "./useSmoothScroll";
|
|
7
7
|
export { default as useVisibilityObserver } from "./useVisibilityObserver";
|
|
8
8
|
export { default as usePageLoaded } from "./usePageLoaded";
|
|
9
|
+
export { default as useBussinessHours } from "./useBussinessHours";
|
package/hook/index.js
CHANGED
|
@@ -6,3 +6,4 @@ export { default as useScroll } from "./useScroll";
|
|
|
6
6
|
export { default as useSmoothScroll } from "./useSmoothScroll";
|
|
7
7
|
export { default as useVisibilityObserver } from "./useVisibilityObserver";
|
|
8
8
|
export { default as usePageLoaded } from "./usePageLoaded";
|
|
9
|
+
export { default as useBussinessHours } from "./useBussinessHours";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
function useBusinessHours() {
|
|
3
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
function checkBusinessHours() {
|
|
6
|
+
// 한국 표준시 (KST) 기준 현재 시간 가져오기
|
|
7
|
+
const now = new Date();
|
|
8
|
+
const kstTime = new Date(now.toLocaleString("en-US", { timeZone: "Asia/Seoul" }));
|
|
9
|
+
const dayOfWeek = kstTime.getDay(); // 0: 일요일, 1: 월요일, ..., 6: 토요일
|
|
10
|
+
const hour = kstTime.getHours(); // 0 - 23 시
|
|
11
|
+
const isCurrentlyOpen = dayOfWeek >= 1 && dayOfWeek <= 5 && hour >= 10 && hour < 17;
|
|
12
|
+
console.log("현재 KST:", kstTime.toString());
|
|
13
|
+
console.log("요일 (0=일요일):", dayOfWeek);
|
|
14
|
+
console.log("시간 (0-23):", hour);
|
|
15
|
+
console.log("영업 여부:", isCurrentlyOpen);
|
|
16
|
+
setIsOpen(isCurrentlyOpen);
|
|
17
|
+
}
|
|
18
|
+
// 처음에 한 번 실행하고, 1분마다 체크
|
|
19
|
+
checkBusinessHours();
|
|
20
|
+
const intervalId = setInterval(checkBusinessHours, 60000);
|
|
21
|
+
// 컴포넌트 언마운트 시 인터벌 정리
|
|
22
|
+
return () => clearInterval(intervalId);
|
|
23
|
+
}, []);
|
|
24
|
+
return isOpen;
|
|
25
|
+
}
|
|
26
|
+
export default useBusinessHours;
|
package/interface/Card.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { ButtonWidgetOption, SelectSwitchWidgetOption, SelectToggleWidgetOption
|
|
|
6
6
|
import { ReactNode } from "react";
|
|
7
7
|
import { ActionProps } from "./Action";
|
|
8
8
|
import { LabelWidget } from "./widget";
|
|
9
|
+
import { Level } from "../_test/interface";
|
|
9
10
|
interface CardOption {
|
|
10
11
|
className?: string;
|
|
11
12
|
boundary?: string;
|
|
@@ -79,6 +80,12 @@ export interface NavCardProps extends Omit<CardProps, "children"> {
|
|
|
79
80
|
image?: NavCardImage;
|
|
80
81
|
};
|
|
81
82
|
}
|
|
83
|
+
export interface StickCardProps {
|
|
84
|
+
titles: Titles;
|
|
85
|
+
level?: Level;
|
|
86
|
+
buttonInLay?: ButtonInLay;
|
|
87
|
+
option?: CardOption;
|
|
88
|
+
}
|
|
82
89
|
export interface NavCardBannerProps extends NavCardProps {
|
|
83
90
|
}
|
|
84
91
|
export interface NavCardButtonProps extends NavCardProps {
|
package/interface/Layout.d.ts
CHANGED
package/interface/Shelf.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Button, Titles } from "./Property";
|
|
2
2
|
import { ActionProps } from "./Action";
|
|
3
|
-
interface Option
|
|
3
|
+
interface Option {
|
|
4
4
|
titleSize?: string;
|
|
5
5
|
subtitleSize?: string;
|
|
6
6
|
overflowScroll?: boolean;
|
|
7
|
-
width?:
|
|
8
|
-
height?:
|
|
7
|
+
width?: string;
|
|
8
|
+
height?: string;
|
|
9
9
|
gap?: "xy" | "x" | "y" | "none";
|
|
10
10
|
isSize?: boolean;
|
|
11
11
|
}
|
|
12
|
-
export interface ShelfProps
|
|
12
|
+
export interface ShelfProps {
|
|
13
13
|
children: React.ReactNode;
|
|
14
14
|
action?: ActionProps & {
|
|
15
15
|
tabs?: Button[];
|
|
@@ -17,6 +17,6 @@ export interface ShelfProps<T> {
|
|
|
17
17
|
titles?: Titles;
|
|
18
18
|
debug?: string;
|
|
19
19
|
className?: string;
|
|
20
|
-
option?: Option
|
|
20
|
+
option?: Option;
|
|
21
21
|
}
|
|
22
22
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ShelfProps } from "../../interface";
|
|
2
|
-
export default function Shelf
|
|
2
|
+
export default function Shelf({ children, className, option, titles, debug, }: ShelfProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,10 +3,12 @@ import { LineBreaks } from "../../text";
|
|
|
3
3
|
import { cn, isDebug } from "../../util";
|
|
4
4
|
export default function Shelf({ children, className, option, titles, debug, }) {
|
|
5
5
|
const { title, titleColor } = titles ?? {};
|
|
6
|
-
const { titleSize, subtitleSize, isSize } = option ?? {};
|
|
6
|
+
const { titleSize, subtitleSize, isSize, width, height } = option ?? {};
|
|
7
7
|
const container = {
|
|
8
8
|
displays: "flex flex-col gap-6",
|
|
9
|
-
|
|
9
|
+
optionHeight: width ?? "w-full",
|
|
10
|
+
optionWidth: height ?? "h-fit",
|
|
11
|
+
sizes: isSize && "w-full h-fit",
|
|
10
12
|
debug: debug && isDebug(`border-2 ${debug}`),
|
|
11
13
|
};
|
|
12
14
|
const titleBox = {
|
|
@@ -21,7 +23,7 @@ export default function Shelf({ children, className, option, titles, debug, }) {
|
|
|
21
23
|
},
|
|
22
24
|
};
|
|
23
25
|
const childrenBox = {
|
|
24
|
-
sizes: "w-full h-
|
|
26
|
+
sizes: "w-full h-fit",
|
|
25
27
|
className,
|
|
26
28
|
};
|
|
27
29
|
return (_jsxs("div", { className: cn(container), children: [titles && (_jsxs("div", { className: cn(titleBox.container), children: [_jsx("div", { className: cn(titleBox.title), children: title }), _jsx(LineBreaks, { className: cn(titleBox.subtitle), texts: titles?.subtitle })] })), _jsx("div", { className: cn(childrenBox), children: children })] }));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface RegionalInfo {
|
|
2
|
+
headquarterName: string;
|
|
3
|
+
assignedCities: string[];
|
|
4
|
+
}
|
|
5
|
+
export interface AgencyInfoProps {
|
|
6
|
+
manager: string;
|
|
7
|
+
positionTitle?: string;
|
|
8
|
+
managerCode?: string;
|
|
9
|
+
phoneNumber: string;
|
|
10
|
+
officeAddress: string;
|
|
11
|
+
regions: RegionalInfo[];
|
|
12
|
+
}
|
|
13
|
+
export declare const exampleAgencyInfo: AgencyInfoProps;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//예시데이터
|
|
2
|
+
export const exampleAgencyInfo = {
|
|
3
|
+
manager: "John Doe",
|
|
4
|
+
phoneNumber: "010-1234-5678",
|
|
5
|
+
officeAddress: "123 Gangnam-daero, Gangnam-gu, Seoul, Korea",
|
|
6
|
+
regions: [
|
|
7
|
+
{
|
|
8
|
+
headquarterName: "Seoul HQ",
|
|
9
|
+
assignedCities: ["Seoul", "Incheon"],
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
headquarterName: "Busan HQ",
|
|
13
|
+
assignedCities: ["Busan", "Ulsan"],
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AgencyInfoProps } from "./Contact";
|
|
2
|
+
interface AgencyListProps {
|
|
3
|
+
agencies: AgencyInfoProps[];
|
|
4
|
+
}
|
|
5
|
+
export default function ContactAgencies({ agencies }: AgencyListProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function AgencyList({ agencies }: AgencyListProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn, formatMobileNum, copyToClipboard } from "../../../util";
|
|
3
|
+
import Header from "./Header";
|
|
4
|
+
import { useResponsive, useBussinessHours } from "../../../hook";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { getChoseong } from "es-hangul";
|
|
7
|
+
import Action from "../Action";
|
|
8
|
+
export default function ContactAgencies({ agencies }) {
|
|
9
|
+
const isXXXS = useResponsive("xxxs");
|
|
10
|
+
const isOpen = useBussinessHours();
|
|
11
|
+
// const isOpen = true;
|
|
12
|
+
const container = {
|
|
13
|
+
display: "relative flex flex-col justify-start items-center",
|
|
14
|
+
sizes: "w-full h-screen",
|
|
15
|
+
text: "break-keep",
|
|
16
|
+
cursor: "cursor-default",
|
|
17
|
+
};
|
|
18
|
+
const contentsWrapper = {
|
|
19
|
+
displays: "flex flex-col justify-start items-center",
|
|
20
|
+
sizes: "w-full max-w-[1200px] h-full min-h-fit",
|
|
21
|
+
spacings: "px-2 pt-20 pb-5 md:px-5",
|
|
22
|
+
};
|
|
23
|
+
const titleWrapper = {
|
|
24
|
+
displays: "flex flex-col justify-center items-center",
|
|
25
|
+
sizes: "w-full h-fit",
|
|
26
|
+
spacings: "mb-10",
|
|
27
|
+
};
|
|
28
|
+
const titleStyling = {
|
|
29
|
+
textStyles: "font-bold text-2xl text-gray-dark text-center",
|
|
30
|
+
};
|
|
31
|
+
const subtitleStyling = {
|
|
32
|
+
textStyles: "font-medium text-sm text-gray-medium text-center",
|
|
33
|
+
};
|
|
34
|
+
const infoBox = {
|
|
35
|
+
displays: "relative flex flex-col justify-center items-center overflow-hidden",
|
|
36
|
+
sizes: "w-fit h-fit rounded-lg",
|
|
37
|
+
spacings: "gap-2 py-5 px-8 my-5",
|
|
38
|
+
textStyles: "font-medium text-lg",
|
|
39
|
+
};
|
|
40
|
+
return (_jsxs("div", { className: cn(container), children: [_jsx(Header, {}), _jsxs("div", { className: cn(contentsWrapper), children: [_jsx("div", { className: "w-40", children: _jsx("img", { src: "https://resource.tosel.co.kr/images/homepage/img-contact-main-small.png", alt: "" }) }), _jsxs("div", { className: cn(titleWrapper), children: [_jsx("div", { className: cn(titleStyling), children: "\uC9C0\uC5ED\uBCF8\uBD80 \uB2F4\uB2F9\uC790 \uBC0F \uC5F0\uB77D\uCC98" }), _jsxs("div", { className: cn(subtitleStyling), children: ["\uC9C0\uC5ED\uBCC4 \uBCF8\uBD80\uC815\uBCF4\uB97C \uCC3E\uC544\uBCF4\uC138\uC694 ", _jsx("br", {}), " \uCE5C\uC808\uD558\uAC8C \uB3C4\uC640\uB4DC\uB9B4\uAC8C\uC694"] }), isOpen ? (_jsxs("div", { className: cn(infoBox, " text-green-dark"), children: [_jsx("div", { className: "absolute top-0 left-0 w-full h-full animate-pulse bg-green-light z-0" }), _jsxs("div", { className: "w-full text-xs flex flex-row gap-2 justify-center z-10", children: [_jsx("span", { children: "\uC0C1\uB2F4 \uAC00\uB2A5\uD55C \uC2DC\uAC04\uC774\uC5D0\uC694" }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", className: "size-4", children: _jsx("path", { "fill-rule": "evenodd", d: "M1 8c0-3.43 3.262-6 7-6s7 2.57 7 6-3.262 6-7 6c-.423 0-.838-.032-1.241-.094-.9.574-1.941.948-3.06 1.06a.75.75 0 0 1-.713-1.14c.232-.378.395-.804.469-1.26C1.979 11.486 1 9.86 1 8Z", "clip-rule": "evenodd" }) })] }), _jsxs("div", { className: "flex flex-col xxxs:flex-row justify-center items-center gap-2 z-10", children: [_jsx("div", { children: "\uC6D4 ~ \uAE08" }), isXXXS && _jsx("div", { children: "|" }), _jsx("div", { children: "10\uC2DC ~ 17\uC2DC" })] })] })) : (_jsxs("div", { className: cn(infoBox, "bg-gray-dark text-gray-light"), children: [_jsxs("div", { className: "w-full text-xs flex flex-row gap-2", children: [_jsx("span", { children: "\uC9C0\uAE08\uC740 \uC0C1\uB2F4\uC2DC\uAC04\uC774 \uC544\uB2C8\uC5D0\uC694." }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "currentColor", className: "size-4", children: _jsx("path", { d: "M14.438 10.148c.19-.425-.321-.787-.748-.601A5.5 5.5 0 0 1 6.453 2.31c.186-.427-.176-.938-.6-.748a6.501 6.501 0 1 0 8.585 8.586Z" }) })] }), _jsxs("div", { className: "flex flex-col xxxs:flex-row justify-center items-center gap-2", children: [_jsx("div", { children: "\uC6D4 ~ \uAE08" }), isXXXS && _jsx("div", { children: "|" }), _jsx("div", { children: "10\uC2DC ~ 17\uC2DC" })] })] }))] }), _jsx(AgencyList, { agencies: agencies })] })] }));
|
|
41
|
+
}
|
|
42
|
+
export function AgencyList({ agencies }) {
|
|
43
|
+
const [searchTerm, setSearchTerm] = useState(""); // 검색어 상태
|
|
44
|
+
// 한글을 포함한 검색어로 필터링하는 함수
|
|
45
|
+
const filterAgencies = (agencies, searchTerm) => {
|
|
46
|
+
const normalizeText = (text) => {
|
|
47
|
+
return text.replace(/\s+/g, "").toLowerCase(); // 띄어쓰기 제거 및 소문자 변환
|
|
48
|
+
};
|
|
49
|
+
10;
|
|
50
|
+
const isHangul = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/.test(searchTerm); // 검색어에 한글 포함 여부 체크
|
|
51
|
+
const normalizedSearchTerm = normalizeText(searchTerm); // 입력값 정규화
|
|
52
|
+
const normalizedSearchChoseong = isHangul
|
|
53
|
+
? getChoseong(searchTerm).toLowerCase() // 초성 정규화
|
|
54
|
+
: normalizedSearchTerm;
|
|
55
|
+
// 1단계: 정확한 일치 또는 부분 문자열 검색
|
|
56
|
+
const exactMatchFilter = agencies.filter((agency) => {
|
|
57
|
+
const managerMatch = normalizeText(agency.manager).includes(normalizedSearchTerm);
|
|
58
|
+
const regionMatch = agency.regions.some((region) => {
|
|
59
|
+
const headquarterMatch = normalizeText(region.headquarterName).includes(normalizedSearchTerm);
|
|
60
|
+
const cityMatch = region.assignedCities.some((regionName) => normalizeText(regionName).includes(normalizedSearchTerm));
|
|
61
|
+
return headquarterMatch || cityMatch;
|
|
62
|
+
});
|
|
63
|
+
return managerMatch || regionMatch;
|
|
64
|
+
});
|
|
65
|
+
// 2단계: 초성 또는 정규화된 일반 검색 (1단계 결과가 없는 경우 실행)
|
|
66
|
+
if (exactMatchFilter.length > 0) {
|
|
67
|
+
return exactMatchFilter;
|
|
68
|
+
}
|
|
69
|
+
return agencies.filter((agency) => {
|
|
70
|
+
const managerMatch = isHangul
|
|
71
|
+
? getChoseong(agency.manager)
|
|
72
|
+
.toLowerCase()
|
|
73
|
+
.includes(normalizedSearchChoseong)
|
|
74
|
+
: normalizeText(agency.manager).includes(normalizedSearchTerm);
|
|
75
|
+
const regionMatch = agency.regions.some((region) => {
|
|
76
|
+
const headquarterMatch = isHangul
|
|
77
|
+
? getChoseong(region.headquarterName)
|
|
78
|
+
.toLowerCase()
|
|
79
|
+
.includes(normalizedSearchChoseong)
|
|
80
|
+
: normalizeText(region.headquarterName).includes(normalizedSearchTerm);
|
|
81
|
+
const cityMatch = region.assignedCities.some((regionName) => isHangul
|
|
82
|
+
? getChoseong(regionName)
|
|
83
|
+
.toLowerCase()
|
|
84
|
+
.includes(normalizedSearchChoseong)
|
|
85
|
+
: normalizeText(regionName).includes(normalizedSearchTerm));
|
|
86
|
+
return headquarterMatch || cityMatch;
|
|
87
|
+
});
|
|
88
|
+
return managerMatch || regionMatch;
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
const handleKeyDown = (event) => {
|
|
92
|
+
const isComposing = event.nativeEvent.isComposing; // IME 입력 상태 확인
|
|
93
|
+
if (!isComposing && event.key === "Enter") {
|
|
94
|
+
console.log("Enter 키 입력됨");
|
|
95
|
+
event.currentTarget.blur(); // 검색창 포커스 해제
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const filteredAgencies = filterAgencies(agencies, searchTerm);
|
|
99
|
+
//결과없음 이미지
|
|
100
|
+
const noResultWrapper = {
|
|
101
|
+
displays: "flex flex-col justify-center items-center",
|
|
102
|
+
sizes: "w-full h-fit",
|
|
103
|
+
};
|
|
104
|
+
const noResultImg = {
|
|
105
|
+
spacings: "p-10",
|
|
106
|
+
sizes: "w-full max-w-80",
|
|
107
|
+
};
|
|
108
|
+
const container = {
|
|
109
|
+
displays: "flex flex-col justify-start items-center",
|
|
110
|
+
sizes: "w-full h-fit",
|
|
111
|
+
spacings: "gap-2",
|
|
112
|
+
};
|
|
113
|
+
const inputBoxWrapper = {
|
|
114
|
+
displays: "relative flex flex-row w-full justify-center items-center",
|
|
115
|
+
sizes: "w-full h-fit",
|
|
116
|
+
spacings: "px-2",
|
|
117
|
+
};
|
|
118
|
+
const inputBox = {
|
|
119
|
+
sizes: "w-full max-w-100 rounded-md",
|
|
120
|
+
formattedStyle: "outline-none",
|
|
121
|
+
backgrounds: "p-4 focus:border-white border-2 border-gray-300 ",
|
|
122
|
+
placeHolder: "지역 / 본부장명 검색",
|
|
123
|
+
animation: "focus:shadow-green duration-300",
|
|
124
|
+
};
|
|
125
|
+
const chartWrapper = {
|
|
126
|
+
displays: "grid grid-cols-1 md:grid-cols-2",
|
|
127
|
+
sizes: "w-full h-fit",
|
|
128
|
+
spacings: "px-2 py-5 gap-2 md:gap-5",
|
|
129
|
+
};
|
|
130
|
+
const agencyCardWrapper = {
|
|
131
|
+
displays: "relative flex flex-col justify-start items-center",
|
|
132
|
+
sizes: "w-full h-fit md:h-90 rounded-lg",
|
|
133
|
+
spacings: "p-5",
|
|
134
|
+
backgrounds: "bg-gray-light/50",
|
|
135
|
+
animations: "hover:scale-101 duration-300 hover:shadow-green",
|
|
136
|
+
};
|
|
137
|
+
const tag = {
|
|
138
|
+
displays: "flex justify-center items-center",
|
|
139
|
+
sizes: "h-fit w-fit rounded-sm",
|
|
140
|
+
spacings: "px-1",
|
|
141
|
+
textStyles: "font-medium text-sm",
|
|
142
|
+
};
|
|
143
|
+
const cardHeader = {
|
|
144
|
+
displays: "flex flex-col justify-start items-center",
|
|
145
|
+
sizes: "w-full h-fit ",
|
|
146
|
+
textStyles: "font-medium text-gray-medium text-lg",
|
|
147
|
+
};
|
|
148
|
+
const actionButton = {
|
|
149
|
+
displays: "flex items-center justify-center",
|
|
150
|
+
spacings: "py-2 px-3 gap-2",
|
|
151
|
+
sizes: "w-full rounded-lg md:w-fit",
|
|
152
|
+
textStyles: "font-medium text-center",
|
|
153
|
+
basicColor: "bg-none text-gray-medium",
|
|
154
|
+
boundaries: "border-1 border-gray-medium/30",
|
|
155
|
+
};
|
|
156
|
+
return (_jsxs("div", { className: cn(container), children: [_jsx("div", { className: cn(inputBoxWrapper), children: _jsxs("div", { className: "flex justify-center items-center w-full max-w-100 relative", children: [_jsx("input", { type: "text", placeholder: inputBox.placeHolder, value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), onKeyDown: handleKeyDown, className: cn(inputBox) }), _jsx("div", { className: "absolute top-0 right-0 flex justify-end items-center h-full mr-4 text-green-light", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", className: "size-6", children: _jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" }) }) })] }) }), _jsx(Action.Replace, { actions: [
|
|
157
|
+
[
|
|
158
|
+
filteredAgencies.length === 0,
|
|
159
|
+
_jsxs("div", { className: cn(noResultWrapper), children: [_jsx("div", { className: cn(noResultImg), children: _jsx("img", { src: "/images/legacy/img-legacy-noresult.png", alt: "\uACB0\uACFC \uC5C6\uC74C" }) }), _jsx("div", { className: "text-sm text-center w-full font-medium", children: "\uC774\uB7F0, \uAC80\uC0C9\uACB0\uACFC\uAC00 \uC5C6\uC5B4\uC694" })] }),
|
|
160
|
+
],
|
|
161
|
+
], children: _jsx("div", { className: cn(chartWrapper), children: filteredAgencies.map((e, index) => (_jsxs("div", { className: cn(agencyCardWrapper), children: [_jsxs("div", { className: cn(cardHeader), children: [_jsxs("div", { className: "flex flex-col xxs:flex-row justify-start items-start xxs:justify-between xxs:items-center w-full", children: [_jsxs("div", { className: "w-full flex gap-2 items-end", children: [_jsx("span", { className: "text-xl w-fit text-gray-dark font-semibold", children: e.manager }), e.positionTitle ?? ""] }), _jsx("div", { className: "flex md:flex-row flex-wrap gap-2 w-fit shrink-0", children: e.regions.map((f, index) => (_jsx("div", { className: cn(tag, "bg-gray-medium/50 text-white "), children: f.headquarterName }, index))) })] }), _jsxs("div", { className: "flex flex-col justify-start items-center w-full gap-2 leading-tight mt-4", children: [_jsxs("div", { className: "w-full", children: ["\uC8FC\uC18C | ", e.officeAddress] }), _jsxs("div", { className: "w-full", children: ["\uC804\uD654\uBC88\uD638 | ", e.phoneNumber] })] })] }), _jsx("div", { className: "w-full h-0 border-1 bg-gray-light my-5" }), _jsxs("div", { className: "flex flex-col w-full justify-center items-center h-fit", children: [_jsx("div", { className: "flex w-full items-center justify-start text-lg font-medium text-gray-medium", children: "\uB2F4\uB2F9\uC9C0\uC5ED:" }), e.regions.length < 3 ? (_jsx("div", { className: "flex flex-col justify-start items-center w-full gap-3 mt-3", children: e.regions.map((g, index) => (_jsx("div", { className: "flex flex-wrap justify-start items-center w-full gap-1", children: g.assignedCities.map((h, index) => (_jsx("div", { className: cn(tag, "bg-green-light text-green-dark"), children: h }, index))) }, index))) })) : (_jsx("div", { className: "w-full flex flex-wrap gap-1", children: e.regions.map((g) => g.assignedCities.map((h, index) => (_jsx("div", { className: cn(tag, "bg-green-light text-green-dark"), children: h }, index)))) }))] }), _jsxs("div", { className: "flex flex-col w-full h-fit justify-center items-center mt-5 gap-2 md:flex-row md:absolute md:bottom-5 md:right-5 md:justify-end", children: [_jsxs("div", { className: cn(actionButton, "hover:bg-green-dark hover:text-white duration-300"), onClick: () => (window.location.href = `tel:${formatMobileNum(e.phoneNumber)}`), children: [_jsx("span", { children: "\uBB38\uC758\uD558\uAE30" }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "size-4", children: _jsx("path", { "fill-rule": "evenodd", d: "M1.5 4.5a3 3 0 0 1 3-3h1.372c.86 0 1.61.586 1.819 1.42l1.105 4.423a1.875 1.875 0 0 1-.694 1.955l-1.293.97c-.135.101-.164.249-.126.352a11.285 11.285 0 0 0 6.697 6.697c.103.038.25.009.352-.126l.97-1.293a1.875 1.875 0 0 1 1.955-.694l4.423 1.105c.834.209 1.42.959 1.42 1.82V19.5a3 3 0 0 1-3 3h-2.25C8.552 22.5 1.5 15.448 1.5 6.75V4.5Z", "clip-rule": "evenodd" }) })] }), e.managerCode && (_jsxs("div", { className: cn(actionButton, "hover:bg-gray-light hover:text-gray-dark duration-300"), onClick: () => copyToClipboard(e.managerCode, `코드(${e.managerCode})가 복사되었습니다`), children: [_jsx("span", { children: "\uC601\uC5C5\uCF54\uB4DC" }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "size-4", children: _jsx("path", { "fill-rule": "evenodd", d: "M3 4.875C3 3.839 3.84 3 4.875 3h4.5c1.036 0 1.875.84 1.875 1.875v4.5c0 1.036-.84 1.875-1.875 1.875h-4.5A1.875 1.875 0 0 1 3 9.375v-4.5ZM4.875 4.5a.375.375 0 0 0-.375.375v4.5c0 .207.168.375.375.375h4.5a.375.375 0 0 0 .375-.375v-4.5a.375.375 0 0 0-.375-.375h-4.5Zm7.875.375c0-1.036.84-1.875 1.875-1.875h4.5C20.16 3 21 3.84 21 4.875v4.5c0 1.036-.84 1.875-1.875 1.875h-4.5a1.875 1.875 0 0 1-1.875-1.875v-4.5Zm1.875-.375a.375.375 0 0 0-.375.375v4.5c0 .207.168.375.375.375h4.5a.375.375 0 0 0 .375-.375v-4.5a.375.375 0 0 0-.375-.375h-4.5ZM6 6.75A.75.75 0 0 1 6.75 6h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75A.75.75 0 0 1 6 7.5v-.75Zm9.75 0A.75.75 0 0 1 16.5 6h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75ZM3 14.625c0-1.036.84-1.875 1.875-1.875h4.5c1.036 0 1.875.84 1.875 1.875v4.5c0 1.035-.84 1.875-1.875 1.875h-4.5A1.875 1.875 0 0 1 3 19.125v-4.5Zm1.875-.375a.375.375 0 0 0-.375.375v4.5c0 .207.168.375.375.375h4.5a.375.375 0 0 0 .375-.375v-4.5a.375.375 0 0 0-.375-.375h-4.5Zm7.875-.75a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75Zm6 0a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75ZM6 16.5a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75Zm9.75 0a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75Zm-3 3a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75Zm6 0a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 .75.75v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75Z", "clip-rule": "evenodd" }) })] }))] })] }, index))) }) })] }));
|
|
162
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
export default function ContactMain(): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function HelpCard({ title, subtitle, children, }: {
|
|
4
|
+
title: string;
|
|
5
|
+
subtitle: string;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn, copyToClipboard } from "../../../util";
|
|
3
|
+
import Header from "./Header";
|
|
4
|
+
export default function ContactMain() {
|
|
5
|
+
const container = {
|
|
6
|
+
display: "relative flex flex-col justify-start items-center",
|
|
7
|
+
sizes: "w-full h-screen",
|
|
8
|
+
text: "break-keep",
|
|
9
|
+
cursor: "cursor-default",
|
|
10
|
+
};
|
|
11
|
+
const contentsWrapper = {
|
|
12
|
+
displays: "flex flex-col justify-center items-center",
|
|
13
|
+
sizes: "w-full max-w-[1200px] h-full min-h-fit",
|
|
14
|
+
spacings: "px-2 pt-20 pb-5 md:px-5",
|
|
15
|
+
};
|
|
16
|
+
const cardWrapper = {
|
|
17
|
+
displays: "flex flex-col md:flex-row justify-center items-center",
|
|
18
|
+
sizes: "w-full h-fit",
|
|
19
|
+
spacings: "gap-5 px-0 md:mt-0 mt-5",
|
|
20
|
+
};
|
|
21
|
+
const titleWrapper = {
|
|
22
|
+
displays: "flex flex-col justify-center items-center",
|
|
23
|
+
sizes: "w-full h-fit",
|
|
24
|
+
spacings: "mb-20",
|
|
25
|
+
};
|
|
26
|
+
const titleStyling = {
|
|
27
|
+
textStyles: "font-bold text-2xl text-gray-dark text-center",
|
|
28
|
+
};
|
|
29
|
+
const subtitleStyling = {
|
|
30
|
+
textStyles: "font-medium text-sm text-gray-medium text-center",
|
|
31
|
+
};
|
|
32
|
+
const button = {
|
|
33
|
+
display: "flex justify-center items-center shrink-0",
|
|
34
|
+
sizes: "h-10 w-fit rounded-lg",
|
|
35
|
+
spacings: "px-4",
|
|
36
|
+
textStyle: "text-sm font-medium text-center",
|
|
37
|
+
cursor: "cursor-pointer",
|
|
38
|
+
};
|
|
39
|
+
return (_jsxs("div", { className: cn(container), children: [_jsx(Header, { isHome: true }), _jsxs("div", { className: cn(contentsWrapper), children: [_jsx("div", { className: "w-40", children: _jsx("img", { src: "https://resource.tosel.co.kr/images/homepage/img-contact-main-small.png", alt: "" }) }), _jsxs("div", { className: cn(titleWrapper), children: [_jsx("div", { className: cn(titleStyling), children: "\uBB34\uC2A8 \uBB38\uC81C\uAC00 \uC788\uB098\uC694?" }), _jsx("div", { className: cn(subtitleStyling), children: "\uB2E4\uC74C\uACFC \uAC19\uC740 \uBC29\uBC95\uC73C\uB85C \uD574\uACB0\uD574\uBCF4\uC138\uC694" })] }), _jsxs("div", { className: cn(cardWrapper), children: [_jsx(HelpCard, { title: "\uC9C0\uC5ED\uBCF8\uBD80 \uC5F0\uB77D\uCC98", subtitle: "\uC9C0\uC5ED\uBCF8\uBD80\uC5D0 \uC9C1\uC811 \uC5F0\uB77D\uD558\uACE0 \uC2F6\uB2E4\uBA74?", children: _jsxs("div", { className: "flex flex-col justify-center items-center w-full bg-white/80 rounded-lg h-fit min-h-30 mt-5 gap-5 py-5", children: [_jsx("div", { className: "w-full h-fit flex justify-center items-center text-green-dark", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", className: "size-10", children: _jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 3.75h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Z" }) }) }), _jsx("div", { className: cn(button, "bg-green-dark text-white hover:shadow-green hover:scale-103 duration-300"), onClick: () => {
|
|
40
|
+
window.location.href = "/contact/agencies";
|
|
41
|
+
}, children: "\uC9C0\uC5ED\uBCF8\uBD80 \uCC3E\uAE30" })] }) }), _jsx(HelpCard, { title: "\uC790\uC8FC \uBB3B\uB294 \uC9C8\uBB38", subtitle: "\uC790\uC8FC\uBB3B\uB294 \uC9C8\uBB38\uC744 \uBAA8\uC544\uBD24\uC5B4\uC694", children: _jsxs("div", { className: "flex flex-col justify-center items-center w-full bg-white/80 rounded-lg h-fit min-h-30 mt-10 gap-5 py-5", children: [_jsx("div", { className: "w-full h-fit flex justify-center items-center text-green-dark", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", className: "size-10", children: _jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z" }) }) }), _jsx("div", { className: cn(button, "bg-green-dark text-white hover:shadow-green hover:scale-103 duration-300"), onClick: () => {
|
|
42
|
+
window.location.href = "https://tosel-faq.notion.site/";
|
|
43
|
+
}, children: "\uB3C4\uC6C0\uB9D0 \uBC14\uB85C\uAC00\uAE30" })] }) }), _jsx(HelpCard, { title: "\uC9C1\uC811 \uBB38\uC758\uD558\uAE30", subtitle: "\uC774\uBA54\uC77C\uC744 \uD1B5\uD574 \uBCF8\uC0AC\uB85C \uBB38\uC758\uD560 \uC218 \uC788\uC5B4\uC694.", children: _jsxs("div", { className: "w-full h-full flex flex-col sm:flex-row md:flex-col justify-center items-center gap-5", children: [_jsxs("div", { className: "relative w-full flex flex-col bg-white/80 rounded-lg py-2 gap-2 overflow-hidden", onClick: () => copyToClipboard("cs_tosel@tosel.co.kr", "개인 CS 이메일 주소가 복사되었습니다."), children: [_jsx("div", { className: "leading-none w-full text-center mt-2 font-bold text-green-dark", children: "\uAC1C\uC778" }), _jsx("div", { className: "leading-none w-full text-center mt-2 font-medium text-gray-medium", children: "tosel_cs@tosel.co.kr" }), _jsx("div", { className: "absolute flex justify-center items-center top-0 left-0 w-full h-full hover:bg-white/50 hover:backdrop-blur-sm duration-300 group", children: _jsx("div", { className: cn(button, "bg-green-dark text-green-light opacity-0 group-hover:opacity-100 duration-300"), children: "\uC8FC\uC18C\uBCF5\uC0AC" }) })] }), _jsxs("div", { className: "relative w-full flex flex-col bg-white/80 rounded-lg py-2 gap-2 overflow-hidden", onClick: () => copyToClipboard("cs_academy@tosel.co.kr", "단체 CS 이메일 주소가 복사되었습니다."), children: [_jsx("div", { className: "leading-none w-full text-center mt-2 font-bold text-green-dark", children: "\uB2E8\uCCB4" }), _jsx("div", { className: "leading-none w-full text-center mt-2 font-medium text-gray-medium text-sm", children: "tosel_academy@tosel.co.kr" }), _jsx("div", { className: "absolute flex justify-center items-center top-0 left-0 w-full h-full hover:bg-white/50 hover:backdrop-blur-sm duration-300 group", children: _jsx("div", { className: cn(button, "bg-green-dark text-green-light opacity-0 group-hover:opacity-100 duration-300"), children: "\uC8FC\uC18C\uBCF5\uC0AC" }) })] })] }) })] })] })] }));
|
|
44
|
+
}
|
|
45
|
+
export function HelpCard({ title, subtitle, children, }) {
|
|
46
|
+
const card = {
|
|
47
|
+
display: "flex flex-col justify-center items-center",
|
|
48
|
+
sizes: "w-full md:w-60 h-90 md:rounded-lg rounded-xl",
|
|
49
|
+
backgrounds: "bg-gray-light/50",
|
|
50
|
+
hoverAction: "hover:shadow-green duration-300 hover:scale-101",
|
|
51
|
+
spacings: "p-5",
|
|
52
|
+
};
|
|
53
|
+
const titleBox = {
|
|
54
|
+
display: "flex justify-center items-center",
|
|
55
|
+
sizes: "w-full h-fit shrink-0",
|
|
56
|
+
spacings: "px-5 py-2",
|
|
57
|
+
textStyle: "font-bold text-gray-medium text-base md:text-lg text-center",
|
|
58
|
+
};
|
|
59
|
+
const subTitleBox = {
|
|
60
|
+
display: "flex justify-center items-center",
|
|
61
|
+
sizes: "w-full h-fit shrink-0",
|
|
62
|
+
spacings: "px-5 py-2",
|
|
63
|
+
textStyle: "font-medium text-gray-medium text-xs md:text-sm text-center",
|
|
64
|
+
};
|
|
65
|
+
return (_jsxs("div", { className: cn(card), children: [_jsx("div", { className: cn(titleBox), children: title }), _jsx("div", { className: cn(subTitleBox), children: subtitle }), _jsx("div", { className: "h-full w-full", children: children })] }));
|
|
66
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useResponsive } from "../../../hook";
|
|
3
|
+
import { cn, copyToClipboard } from "../../../util";
|
|
4
|
+
export default function Header({ isHome }) {
|
|
5
|
+
const isXS = useResponsive("xs");
|
|
6
|
+
const isXXS = useResponsive("xxs");
|
|
7
|
+
const container = {
|
|
8
|
+
display: "fixed flex flex-col justify-center items-center",
|
|
9
|
+
sizes: "w-full h-fit",
|
|
10
|
+
backgrounds: "bg-white/10 backdrop-blur-sm",
|
|
11
|
+
cursor: "cursor-default",
|
|
12
|
+
positions: "top-0 left-0 z-40",
|
|
13
|
+
};
|
|
14
|
+
const headWrapper = {
|
|
15
|
+
display: "flex justify-between items-center",
|
|
16
|
+
sizes: "w-full h-15 max-w-[1200px]",
|
|
17
|
+
spacings: "px-5",
|
|
18
|
+
};
|
|
19
|
+
const button = {
|
|
20
|
+
display: "flex justify-center items-center shrink-0",
|
|
21
|
+
sizes: "h-10 w-fit rounded-lg",
|
|
22
|
+
spacings: "px-4",
|
|
23
|
+
textStyle: "text-sm font-medium text-center",
|
|
24
|
+
cursor: "cursor-pointer",
|
|
25
|
+
};
|
|
26
|
+
const leftWrapper = {
|
|
27
|
+
display: "flex gap-2 justify-center items-center",
|
|
28
|
+
};
|
|
29
|
+
const rightWrapper = {
|
|
30
|
+
display: "flex gap-2",
|
|
31
|
+
};
|
|
32
|
+
return (_jsx("div", { className: cn(container), children: _jsxs("div", { className: cn(headWrapper), children: [_jsxs("div", { className: cn(leftWrapper), children: [_jsx("div", { className: "h-fit w-fit", children: _jsx("img", { src: "https://tosel.gcdn.ntruss.com/images/img-favicon-main.png", alt: "", className: "size-8" }) }), _jsx("div", { className: "font-medium text-lg", children: "\uACE0\uAC1D\uC13C\uD130" })] }), _jsxs("div", { className: cn(rightWrapper), children: [isXXS && (_jsx("div", { className: cn(button, "hover:bg-gray-light text-gray-medium duration-300"), onClick: () => copyToClipboard("cs_tosel@tosel.co.kr", "이메일 주소가 복사되었습니다."), children: "cs_tosel@tosel.co.kr" })), _jsx("div", { className: cn(button, "bg-gray-light text-gray-medium hover:bg-green-light hover:text-green-dark "), onClick: () => {
|
|
33
|
+
window.location.href = isHome
|
|
34
|
+
? "https://new.tosel.org"
|
|
35
|
+
: "../contact";
|
|
36
|
+
}, children: isHome ? "홈페이지로" : "CS 홈으로" })] })] }) }));
|
|
37
|
+
}
|
|
@@ -4,10 +4,13 @@ import Tab from "./Tab";
|
|
|
4
4
|
import { cn } from "../../util";
|
|
5
5
|
export default function Gallery({ action, children, option, }) {
|
|
6
6
|
const { text, background, boundary } = option ?? {};
|
|
7
|
-
const tabBox = {
|
|
8
|
-
|
|
7
|
+
const tabBox = {};
|
|
8
|
+
const container = {
|
|
9
|
+
displays: "relative flex flex-col-reverse xl:flex-col",
|
|
10
|
+
position: "top-0 justify-end xl:justify-start",
|
|
11
|
+
sizes: "h-[calc(100%)] xl:h-[calc(100%-76px)] w-full",
|
|
9
12
|
};
|
|
10
|
-
return (_jsxs("div", { className:
|
|
13
|
+
return (_jsxs("div", { className: cn(container), children: [_jsx(Action.Replace, { actions: action?.replaces, children: _jsx(Action.Show, { actions: action?.shows, children: children }) }), action?.tabs && (_jsx(Tab, { tabs: action?.tabs, option: {
|
|
11
14
|
className: cn(tabBox),
|
|
12
15
|
text,
|
|
13
16
|
background,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ShelfProps } from "../../interface/Shelf";
|
|
2
|
-
declare function Shelf({ titles, debug, children }: ShelfProps
|
|
2
|
+
declare function Shelf({ titles, debug, children }: ShelfProps): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
declare namespace Shelf {
|
|
4
|
-
var Wrap: ({ className, titles, children, debug, option
|
|
5
|
-
var Row: ({ titles, children, className, debug
|
|
6
|
-
var Col: ({ titles, children, debug, className
|
|
4
|
+
var Wrap: ({ className, titles, children, debug, option }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
var Row: ({ titles, children, className, debug }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
var Col: ({ titles, children, debug, className }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
var Fourthird: ({ titles, children, debug, className }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
var Quarter: ({ titles, children, debug, className }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
9
|
}
|
|
8
10
|
export default Shelf;
|
package/layout/template/Shelf.js
CHANGED
|
@@ -15,18 +15,20 @@ function Shelf({ titles, debug, children }) {
|
|
|
15
15
|
titleSize: "text-lg xl:text-2xl",
|
|
16
16
|
}, children: children }));
|
|
17
17
|
}
|
|
18
|
-
function Wrap({ className, titles, children, debug, option
|
|
18
|
+
function Wrap({ className, titles, children, debug, option }) {
|
|
19
19
|
const container = {
|
|
20
|
-
displays: "flex flex-
|
|
20
|
+
displays: "flex flex-wrap",
|
|
21
21
|
gaps: gap[option?.gap ?? "xy"],
|
|
22
22
|
className,
|
|
23
23
|
};
|
|
24
24
|
return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
|
|
25
25
|
titleSize: "text-lg xl:text-2xl",
|
|
26
26
|
subtitleSize: "text-sm",
|
|
27
|
+
width: "w-full",
|
|
28
|
+
isSize: true,
|
|
27
29
|
}, debug: debug, children: children }));
|
|
28
30
|
}
|
|
29
|
-
function Row({ titles, children, className, debug
|
|
31
|
+
function Row({ titles, children, className, debug }) {
|
|
30
32
|
const container = {
|
|
31
33
|
displays: "flex flex-col lg:flex-row",
|
|
32
34
|
className: className ?? "gap-x-7.5",
|
|
@@ -35,19 +37,45 @@ function Row({ titles, children, className, debug, }) {
|
|
|
35
37
|
titleSize: "text-lg xl:text-2xl",
|
|
36
38
|
subtitleSize: "text-sm",
|
|
37
39
|
isSize: true,
|
|
40
|
+
width: "w-full",
|
|
41
|
+
}, debug: debug, children: children }));
|
|
42
|
+
}
|
|
43
|
+
function Col({ titles, children, debug, className }) {
|
|
44
|
+
const container = {
|
|
45
|
+
displays: "flex flex-col w-full lg:flex-wrap",
|
|
46
|
+
className: className ?? "gap-y-7.5",
|
|
47
|
+
};
|
|
48
|
+
return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
|
|
49
|
+
titleSize: "text-lg xl:text-2xl",
|
|
50
|
+
subtitleSize: "text-sm",
|
|
51
|
+
}, debug: debug, children: children }));
|
|
52
|
+
}
|
|
53
|
+
function Fourthird({ titles, children, debug, className }) {
|
|
54
|
+
const container = {
|
|
55
|
+
displays: "flex flex-col",
|
|
56
|
+
className: className ?? "gap-y-7.5",
|
|
57
|
+
};
|
|
58
|
+
return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
|
|
59
|
+
titleSize: "text-lg xl:text-2xl",
|
|
60
|
+
subtitleSize: "text-sm",
|
|
61
|
+
width: "basis-[990px] flex-grow w-full",
|
|
62
|
+
height: "h-fit",
|
|
38
63
|
}, debug: debug, children: children }));
|
|
39
64
|
}
|
|
40
|
-
function
|
|
65
|
+
function Quarter({ titles, children, debug, className }) {
|
|
41
66
|
const container = {
|
|
42
|
-
displays: "flex flex-col
|
|
67
|
+
displays: "flex flex-col",
|
|
43
68
|
className: className ?? "gap-y-7.5",
|
|
44
69
|
};
|
|
45
70
|
return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
|
|
46
71
|
titleSize: "text-lg xl:text-2xl",
|
|
47
72
|
subtitleSize: "text-sm",
|
|
73
|
+
width: "flex-grow basis-[450px] max-w-full min-w-[450px]",
|
|
48
74
|
}, debug: debug, children: children }));
|
|
49
75
|
}
|
|
50
76
|
Shelf.Wrap = Wrap;
|
|
51
77
|
Shelf.Row = Row;
|
|
52
78
|
Shelf.Col = Col;
|
|
79
|
+
Shelf.Fourthird = Fourthird;
|
|
80
|
+
Shelf.Quarter = Quarter;
|
|
53
81
|
export default Shelf;
|
package/layout/template/Tab.js
CHANGED
|
@@ -15,15 +15,15 @@ export default function Tab({ tabs, option, state, }) {
|
|
|
15
15
|
? state
|
|
16
16
|
: useState(tabs.map((_, i) => i === 0));
|
|
17
17
|
const container = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
styles: "rounded-xl ",
|
|
18
|
+
displays: "flex shrink-0",
|
|
19
|
+
sizes: "w-full xl:w-fit h-fit",
|
|
20
|
+
spacings: "xl:mt-2.5 p-2.5 gap-2.5",
|
|
21
|
+
backgrounds: boundary ?? "bg-white/50 xl:bg-white/30",
|
|
22
|
+
styles: "rounded-0 xl:rounded-xl",
|
|
23
|
+
scrollStyling: "overflow-y-scroll scrollbar-hidden",
|
|
25
24
|
};
|
|
26
25
|
const button = {
|
|
26
|
+
displays: "flex shrink-0 justify-center items-center",
|
|
27
27
|
styles: "rounded-md duration-500 ",
|
|
28
28
|
sizes: `${heightSize[height ?? "lg"]} ${widthSize[width ?? "lg"]}`,
|
|
29
29
|
font: text ?? "text-green-dark",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { DashboardHeaderProps } from "../../../interface";
|
|
2
|
-
export declare function Header({ title, logo, notification, menu, option, }: DashboardHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function Header({ title, logo, notification, menu, option, isOpen, }: DashboardHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { cn, gradient } from "../../../util";
|
|
3
3
|
import { useActionStore } from "../../../store";
|
|
4
4
|
import Menu from "./Menu";
|
|
@@ -6,29 +6,55 @@ import { Action } from "../..";
|
|
|
6
6
|
import Notification from "./Notification";
|
|
7
7
|
import SVG from "../../../asset/SVG";
|
|
8
8
|
import { Label } from "../../../widget";
|
|
9
|
-
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import { useResponsive } from "../../../hook";
|
|
11
|
+
export function Header({ title, logo, notification, menu, option, isOpen, }) {
|
|
10
12
|
const { setView, setIsOwn } = useActionStore();
|
|
11
13
|
const { notifications, flag, onClick } = notification;
|
|
12
14
|
const { text, background, className, iconColor } = option ?? {};
|
|
15
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
16
|
+
const toggleMenu = () => {
|
|
17
|
+
setIsExpanded(!isExpanded);
|
|
18
|
+
setView("dashboardMenu");
|
|
19
|
+
};
|
|
20
|
+
const isSM = useResponsive("sm");
|
|
13
21
|
const container = {
|
|
14
|
-
positions: "fixed
|
|
15
|
-
displays: "flex items-center justify-between ",
|
|
22
|
+
positions: "fixed top-0 left-0 z-45",
|
|
23
|
+
displays: "flex items-center justify-between gap-0 xl:gap-7.5",
|
|
16
24
|
sizes: "h-15 w-full",
|
|
17
25
|
background: `${background ?? "bg-white"}`,
|
|
18
26
|
text: `${text ?? "text-black"} `,
|
|
19
|
-
styles: "px-5 xl:px-8 2xl:px-16
|
|
27
|
+
styles: "px-5 xl:px-8 2xl:px-16 shadow-main",
|
|
20
28
|
className,
|
|
21
29
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const leftHeaderWrapper = {
|
|
31
|
+
displays: "flex flex-row justify-start items-center",
|
|
32
|
+
sizes: "w-[184px] h-fit shrink-0",
|
|
33
|
+
spacings: "gap-3",
|
|
34
|
+
};
|
|
35
|
+
const menuButton = {
|
|
36
|
+
displays: "flex mmd:hidden justify-center items-center",
|
|
37
|
+
spacings: "p-2",
|
|
38
|
+
};
|
|
39
|
+
const rightHeaderWrapper = {
|
|
40
|
+
displays: "flex flex-row justify-end sm:justify-between items-center",
|
|
41
|
+
sizes: "h-fit w-full",
|
|
42
|
+
};
|
|
43
|
+
const titleStyling = {
|
|
44
|
+
displays: "flex",
|
|
45
|
+
font: "font-pretendard-var font-bold text-2xl leading-none",
|
|
46
|
+
spacings: "pl-5",
|
|
47
|
+
};
|
|
48
|
+
return (_jsxs("div", { className: cn(container), children: [_jsxs("div", { className: cn(leftHeaderWrapper), children: [_jsx("div", { className: cn(menuButton), onClick: () => toggleMenu(), children: _jsx("div", { className: "w-6 h-6", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: [!isOpen && (_jsx("path", { id: "menu", fill: "currentColor", d: "M4.118 6.2h16a1.2 1.2 0 100-2.4h-16a1.2 1.2 0 100 2.4m16 4.6h-16a1.2 1.2 0 100 2.4h16a1.2 1.2 0 100-2.4m0 7h-16a1.2 1.2 0 100 2.4h16a1.2 1.2 0 100-2.4", "fill-rule": "evenodd" })), isOpen && (_jsx("path", { id: "close", fill: "currentColor", "fill-rule": "evenodd", d: "M13.815 12l5.651-5.651a1.2 1.2 0 00-1.697-1.698l-5.651 5.652-5.652-5.652a1.201 1.201 0 00-1.697 1.698L10.421 12l-5.652 5.651a1.202 1.202 0 00.849 2.049c.307 0 .614-.117.848-.351l5.652-5.652 5.651 5.652a1.198 1.198 0 001.697 0 1.2 1.2 0 000-1.698L13.815 12z" }))] }) }) }), logo ? _jsx(_Fragment, { children: logo }) : _jsx("div", { className: "text-2xl", children: "TOSEL" })] }), _jsxs("div", { className: cn(rightHeaderWrapper), children: [isSM && _jsx("div", { className: cn(titleStyling), children: title }), _jsx("div", { className: "relative flex gap-5.25", children: _jsx(Action.Show, { actions: [
|
|
49
|
+
["notification", _jsx(Notification, { notifications: notifications })],
|
|
50
|
+
[menu ? "menu" : false, menu && _jsx(Menu, { ...menu })],
|
|
51
|
+
], children: menu?.profile ? (_jsx(SVG.Profile, { onClick: () => {
|
|
52
|
+
setIsOwn(true);
|
|
53
|
+
return setView("menu");
|
|
54
|
+
}, color: iconColor })) : (_jsx(Label.Button, { title: "\uB85C\uADF8\uC778", onClick: () => option?.onClick && option.onClick(), option: {
|
|
55
|
+
width: "sm",
|
|
56
|
+
height: "xs",
|
|
57
|
+
background: gradient.bg.greenToRed,
|
|
58
|
+
text: "text-white",
|
|
59
|
+
} })) }) })] })] }));
|
|
34
60
|
}
|
|
@@ -5,23 +5,28 @@ import { cn } from "../../../util";
|
|
|
5
5
|
import { useActionStore } from "../../../store";
|
|
6
6
|
import Navigation from "./Navigation";
|
|
7
7
|
export default function Layout({ header, navigations, children, option, }) {
|
|
8
|
-
const {
|
|
8
|
+
const { events, flag, setFlag, isOwn, setIsOwn, clearView } = useActionStore();
|
|
9
9
|
const { title, option: headerOption, logo, notification, menu } = header;
|
|
10
10
|
const { background } = option ?? {};
|
|
11
|
+
const isOpen = events.some((event) => event.event === "dashboardMenu");
|
|
11
12
|
useEffect(() => {
|
|
12
13
|
if (isOwn)
|
|
13
14
|
return setIsOwn(false);
|
|
14
15
|
return clearView();
|
|
15
16
|
}, [flag]);
|
|
16
17
|
const container = {
|
|
17
|
-
sizes: "
|
|
18
|
+
sizes: "h-screen",
|
|
18
19
|
background: `${background ?? "bg-gray-light"} `,
|
|
19
20
|
styles: "font-pretendard-medium",
|
|
20
21
|
};
|
|
22
|
+
const spacer = {
|
|
23
|
+
displays: "flex shrink-0",
|
|
24
|
+
sizes: "w-full h-15 xl:h-22.5",
|
|
25
|
+
};
|
|
21
26
|
const body = {
|
|
22
|
-
sizes: "h-
|
|
23
|
-
displays: "flex gap-
|
|
24
|
-
paddings: "
|
|
27
|
+
sizes: "h-[calc(100%-60px)] xl:h-[calc(100%-90px)]",
|
|
28
|
+
displays: "flex gap-0 xl:gap-7.5 relative",
|
|
29
|
+
paddings: "xl:px-5 2xl:pl-12 2xl:pr-11.25",
|
|
25
30
|
};
|
|
26
|
-
return (_jsxs("div", { className: cn(container), onClick: setFlag, children: [_jsx(Header, { title: title, notification: notification, menu: menu, option: headerOption, logo: logo }), _jsxs("div", { className: cn(body), children: [_jsx(Navigation.Container, { children: navigations.map((nav, index) => (_jsx(Fragment, { children: nav }, index))) }), children] })] }));
|
|
31
|
+
return (_jsxs("div", { className: cn(container), onClick: setFlag, children: [_jsx(Header, { title: title, notification: notification, menu: menu, option: headerOption, isOpen: isOpen, logo: logo }), _jsx("div", { className: cn(spacer) }), _jsxs("div", { className: cn(body), children: [_jsx(Navigation.Container, { children: navigations.map((nav, index) => (_jsx(Fragment, { children: nav }, index))) }), children] })] }));
|
|
27
32
|
}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { useActionStore } from "../../../store";
|
|
2
4
|
import { cn } from "../../../util";
|
|
5
|
+
import Action from "../Action";
|
|
6
|
+
import { useResponsive } from "../../../hook";
|
|
3
7
|
function Container({ children }) {
|
|
8
|
+
const { events } = useActionStore();
|
|
9
|
+
const isMmd = useResponsive("mmd");
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
console.log(events);
|
|
12
|
+
}, [events]);
|
|
13
|
+
return (_jsx(Action.Show, { actions: [[isMmd || "dashboardMenu", _jsx(Contents, { children: children })]], children: null }));
|
|
14
|
+
}
|
|
15
|
+
function Contents({ children, showAction, }) {
|
|
4
16
|
const container = {
|
|
5
|
-
positions: "
|
|
6
|
-
displays: "flex
|
|
7
|
-
|
|
17
|
+
positions: "absolute mmd:relative top-0 left-0 shrink-0 mmd:flex ",
|
|
18
|
+
displays: "flex-col",
|
|
19
|
+
spacings: "z-40",
|
|
20
|
+
sizes: showAction?.isVisible
|
|
21
|
+
? "w-[204px] h-full"
|
|
22
|
+
: "w-0 overflow-hidden h-full",
|
|
23
|
+
animations: "duration-300",
|
|
24
|
+
colors: "bg-white/50 mmd:bg-white/0 backdrop-blur shadow-main mmd:shadow-none",
|
|
8
25
|
};
|
|
9
26
|
return (_jsxs("div", { className: cn(container), children: [children, _jsx(Copyright, {})] }));
|
|
10
27
|
}
|
|
@@ -5,8 +5,8 @@ const buttonClassNames = (href, nowPath, color) => {
|
|
|
5
5
|
const { isDark } = useActionStore();
|
|
6
6
|
const [bg, [text, selectedText]] = color ?? ["white", ["white", "black"]];
|
|
7
7
|
const container = {
|
|
8
|
-
displays: "flex flex-row items-center justify-
|
|
9
|
-
sizes: " w-full xl:w-51 h-11
|
|
8
|
+
displays: "flex flex-row items-center justify-start gap-2.5",
|
|
9
|
+
sizes: " w-full xl:w-51 h-11",
|
|
10
10
|
styles: "xl:rounded-lg xl:pl-5 font-pretendard-bold",
|
|
11
11
|
};
|
|
12
12
|
const toggle = checkPathMatch(href, nowPath)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { checkPathMatch, cn } from "../../../util";
|
|
2
2
|
const navigatorStyle = ({ href, nowPath, background = "bg-white", text = "text-white", }) => {
|
|
3
3
|
const style = {
|
|
4
|
-
displays: "flex flex-row items-center justify-
|
|
4
|
+
displays: "flex flex-row items-center justify-start gap-2.5",
|
|
5
5
|
sizes: " w-full xl:w-51 h-11 ",
|
|
6
|
+
spacings: "pl-5 xl:p-0",
|
|
6
7
|
styles: "xl:rounded-lg xl:pl-5 font-pretendard-bold",
|
|
7
8
|
texts: checkPathMatch(href, nowPath)
|
|
8
9
|
? [background, text].join(" ")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edu-tosel/design",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.263",
|
|
4
4
|
"description": "UI components for International TOSEL Committee",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jsx",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"date-fns": "^2.30.0",
|
|
20
20
|
"date-fns-tz": "^2.0.1",
|
|
21
21
|
"dayjs": "^1.11.12",
|
|
22
|
+
"es-hangul": "^2.2.4",
|
|
22
23
|
"gsap": "^3.12.5",
|
|
23
24
|
"moment-timezone": "^0.5.45",
|
|
24
25
|
"react": "^18.2.0",
|
package/tailwind.config.ts
CHANGED
|
@@ -75,7 +75,6 @@ export default {
|
|
|
75
75
|
to: { width: "0%" },
|
|
76
76
|
},
|
|
77
77
|
},
|
|
78
|
-
|
|
79
78
|
animation: {
|
|
80
79
|
grow: "grow 0.2s ease-in-out forwards",
|
|
81
80
|
shrink: "shrink 0.2s ease-in-out forwards",
|
|
@@ -431,6 +430,7 @@ export default {
|
|
|
431
430
|
},
|
|
432
431
|
scale: {
|
|
433
432
|
101: "1.01",
|
|
433
|
+
103: "1.03",
|
|
434
434
|
110: "1.1",
|
|
435
435
|
120: "1.2",
|
|
436
436
|
200: "2",
|
|
@@ -681,6 +681,18 @@ export default {
|
|
|
681
681
|
"-ms-overflow-style": "none", // For Internet Explorer and Edge
|
|
682
682
|
"scrollbar-width": "none", // For Firefox
|
|
683
683
|
},
|
|
684
|
+
".scrollbar-custom": {
|
|
685
|
+
/* Fully custom scrollbar style */
|
|
686
|
+
"&::-webkit-scrollbar": {
|
|
687
|
+
width: "8px",
|
|
688
|
+
},
|
|
689
|
+
|
|
690
|
+
"&::-webkit-scrollbar-thumb": {
|
|
691
|
+
backgroundColor: "#BABABA",
|
|
692
|
+
borderRadius: "10px",
|
|
693
|
+
margin: "4px",
|
|
694
|
+
},
|
|
695
|
+
},
|
|
684
696
|
".page-break": {
|
|
685
697
|
"@media print": {
|
|
686
698
|
"page-break-before": "always",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function copyToClipboard(value: string | undefined): void;
|
|
1
|
+
export default function copyToClipboard(value: string | undefined, customMessage?: string): void;
|
package/util/copyToClipboard.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
export default function copyToClipboard(value) {
|
|
1
|
+
export default function copyToClipboard(value, customMessage) {
|
|
2
2
|
const textToCopy = value ?? "";
|
|
3
3
|
if (textToCopy) {
|
|
4
4
|
navigator.clipboard
|
|
5
5
|
.writeText(textToCopy)
|
|
6
6
|
.then(() => {
|
|
7
|
-
|
|
7
|
+
const message = customMessage ?? `클립보드에 복사되었습니다: ${textToCopy}`;
|
|
8
|
+
alert(message); // 복사 성공 메시지 출력
|
|
8
9
|
})
|
|
9
10
|
.catch((err) => {
|
|
10
11
|
console.error("복사에 실패했습니다:", err);
|
|
11
12
|
});
|
|
12
13
|
}
|
|
13
14
|
else {
|
|
14
|
-
alert("서비스 준비 중입니다."); // 값이 없을 경우
|
|
15
|
+
alert("서비스 준비 중입니다."); // 값이 없을 경우 기본 메시지 출력
|
|
15
16
|
}
|
|
16
17
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function formatPhoneNumberToE164(phoneNumber: string, countryCode?: string): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default function formatPhoneNumberToE164(phoneNumber, countryCode = "KR") {
|
|
2
|
+
const countryCodes = {
|
|
3
|
+
KR: "+82",
|
|
4
|
+
US: "+1",
|
|
5
|
+
JP: "+81",
|
|
6
|
+
CN: "+86",
|
|
7
|
+
};
|
|
8
|
+
const defaultAreaCodes = {
|
|
9
|
+
KR: "0",
|
|
10
|
+
};
|
|
11
|
+
const cleanedNumber = phoneNumber.replace(/[^\d]/g, "");
|
|
12
|
+
const countryCodePrefix = countryCodes[countryCode] || "+82";
|
|
13
|
+
const defaultAreaCode = defaultAreaCodes[countryCode] || "0";
|
|
14
|
+
const normalizedNumber = cleanedNumber.startsWith(defaultAreaCode)
|
|
15
|
+
? cleanedNumber.slice(defaultAreaCode.length)
|
|
16
|
+
: cleanedNumber;
|
|
17
|
+
return `${countryCodePrefix}${normalizedNumber}`;
|
|
18
|
+
}
|
package/util/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { default as compareDates } from "./compareDates";
|
|
|
9
9
|
export { default as convertDateToString } from "./convertDateToString";
|
|
10
10
|
export { default as copyToClipboard } from "./copyToClipboard";
|
|
11
11
|
export { default as createRecord } from "./createRecord";
|
|
12
|
+
export { default as formatMobileNum } from "./formatPhoneNumberToE164";
|
|
12
13
|
export * from "../style/colors";
|
|
13
14
|
export * from "./pattern";
|
|
14
15
|
export * from "./shape";
|
package/util/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { default as compareDates } from "./compareDates";
|
|
|
9
9
|
export { default as convertDateToString } from "./convertDateToString";
|
|
10
10
|
export { default as copyToClipboard } from "./copyToClipboard";
|
|
11
11
|
export { default as createRecord } from "./createRecord";
|
|
12
|
+
export { default as formatMobileNum } from "./formatPhoneNumberToE164";
|
|
12
13
|
export * from "../style/colors";
|
|
13
14
|
export * from "./pattern";
|
|
14
15
|
export * from "./shape";
|
package/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.263
|