sales-frontend-components 0.0.67 → 0.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,18 +1,14 @@
1
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
1
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import { useController } from 'react-hook-form';
3
- import { CheckboxButton, Checkbox, DatePicker, DateRangePicker, SegmentGroup, FormField, Icon, Button, Modal, List, ListItem, Segment, Select, Accordion, FormCore, RadioGroup, useModalState, Radio, Table, Tab, ModalUtils } from 'sales-frontend-design-system';
4
- import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
5
- import styles from './step-indicator/step-indicator.module.scss';
6
- import styles$1 from './camera/camera.module.scss';
7
- import styles$2 from './debug-tool/debug-tool.module.scss';
8
- import { isClient, getEnvironmentFromHostname } from 'sales-frontend-utils';
9
- import { useDebugStore } from 'sales-frontend-api';
10
- import styles$3 from './debug-tool/features/network-log/network-log.module.scss';
11
- import { useSearchModalAddressQuery, useSearchOccupationQuery, useSearchVehicleQuery } from 'sales-frontend-api/method';
12
- import styles$4 from './modal/standard/address-search/select-address.module.scss';
13
- import styles$5 from './modal/pre-standard/job-vehicle-search-modal/job-vehicle-search-modal.module.scss';
14
- import styles$6 from './modal/pre-standard/job-search-modal/job-search-modal.module.scss';
15
- import styles$7 from './modal/pre-standard/vehicle-search-modal/vehicle-search-modal.module.scss';
3
+ import { CheckboxButton, Checkbox, DatePicker, DateRangePicker, Accordion, Radio, Table, Button, FormField, Select, Tab, Icon, useModalState, Modal, SegmentGroup, ModalUtils, FormCore, RadioGroup } from 'sales-frontend-design-system';
4
+ import React, { useState, useEffect, useRef, useCallback } from 'react';
5
+ import { useSearchOccupationQuery, useSearchModalAddressQuery, useSearchVehicleQuery } from 'sales-frontend-api/method';
6
+ import styles from './modal/pre-standard/job-search-modal/job-search-modal.module.scss';
7
+ import styles$1 from './step-indicator/step-indicator.module.scss';
8
+ import styles$2 from './camera/camera.module.scss';
9
+ import styles$3 from './modal/standard/address-search/select-address.module.scss';
10
+ import styles$4 from './modal/pre-standard/job-vehicle-search-modal/job-vehicle-search-modal.module.scss';
11
+ import styles$5 from './modal/pre-standard/vehicle-search-modal/vehicle-search-modal.module.scss';
16
12
 
17
13
  const FormCheckboxButton = ({
18
14
  name,
@@ -22,7 +18,21 @@ const FormCheckboxButton = ({
22
18
  ...props
23
19
  }) => {
24
20
  const { field, fieldState } = useController({ name, control, disabled });
25
- return /* @__PURE__ */ jsx(CheckboxButton, { ...props, ...field, id: field.name, checked: field.value, error: fieldState.invalid, children });
21
+ return /* @__PURE__ */ jsx(
22
+ CheckboxButton,
23
+ {
24
+ ...props,
25
+ ...field,
26
+ id: field.name,
27
+ checked: field.value ?? false,
28
+ error: fieldState.invalid,
29
+ onChange: (checked) => {
30
+ field.onChange(checked);
31
+ props.onChange?.(checked);
32
+ },
33
+ children
34
+ }
35
+ );
26
36
  };
27
37
 
28
38
  const FormCheckbox = ({
@@ -100,73 +110,10 @@ const FormDateRangePicker = ({
100
110
  );
101
111
  };
102
112
 
103
- const FormSegmentGroup = ({
104
- name,
105
- control,
106
- disabled,
107
- ...props
108
- }) => {
109
- const { field, fieldState } = useController({ name, control, disabled });
110
- return /* @__PURE__ */ jsx(
111
- SegmentGroup,
112
- {
113
- ...props,
114
- tabIndex: 0,
115
- id: field.name,
116
- ref: field.ref,
117
- defaultValue: field.value,
118
- disabled: field.disabled,
119
- error: fieldState.invalid,
120
- onBlur: field.onBlur,
121
- onValueChange: (selected) => {
122
- field.onChange(selected);
123
- props.onValueChange?.(selected);
124
- }
125
- }
126
- );
127
- };
128
-
129
- const FormTextField = ({
130
- name,
131
- control,
132
- size = "medium",
133
- disabled,
134
- error,
135
- onBlur,
136
- onChange,
137
- rootProps,
138
- ...props
139
- }) => {
140
- const { field, fieldState } = useController({ name, control, disabled });
141
- return /* @__PURE__ */ jsx(
142
- FormField.TextField,
143
- {
144
- ...props,
145
- id: field.name,
146
- size,
147
- autoComplete: "off",
148
- name: field.name,
149
- value: field.value ?? "",
150
- disabled: field.disabled,
151
- error: fieldState.invalid || error,
152
- onChange: (e) => {
153
- field.onChange(e);
154
- onChange?.(e);
155
- },
156
- onBlur: (e) => {
157
- field.onBlur();
158
- onBlur?.(e);
159
- },
160
- rootProps: {
161
- ...rootProps,
162
- onClear: () => {
163
- field.onChange("");
164
- rootProps?.onClear?.();
165
- }
166
- }
167
- }
168
- );
169
- };
113
+ const JOB_SEARCH_TABS = [
114
+ { value: "jobName", label: "\uC9C1\uC885\uBA85 \uAC80\uC0C9" },
115
+ { value: "jobCode", label: "\uBD84\uB958\uB85C \uAC80\uC0C9" }
116
+ ];
170
117
 
171
118
  function getDefaultExportFromCjs (x) {
172
119
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -259,2053 +206,1491 @@ function requireBind () {
259
206
  var bindExports = requireBind();
260
207
  var classNames = /*@__PURE__*/getDefaultExportFromCjs(bindExports);
261
208
 
262
- const cx$9 = classNames.bind(styles);
263
- const StepIndicator = ({
264
- items,
265
- onClickItem,
266
- currentIndex = 0,
267
- defaultValue = "",
268
- dotCount = 3
269
- }) => {
270
- const [current, setCurrent] = React.useState(currentIndex);
271
- React.useEffect(() => {
272
- items.map((item, idx) => {
273
- if (item.value === defaultValue) {
274
- setCurrent(idx);
209
+ const highlightOnSearchKeyword = (originalText, targetString) => {
210
+ if (originalText?.includes(targetString)) {
211
+ const replacedText = [];
212
+ const splitText = originalText.split(targetString);
213
+ for (let i = 0; i < splitText.length; i++) {
214
+ replacedText.push(splitText[i]);
215
+ if (i !== splitText.length - 1) {
216
+ replacedText.push(/* @__PURE__ */ jsx("span", { className: "text-primary", children: targetString }));
275
217
  }
276
- });
277
- }, [items, defaultValue]);
278
- return /* @__PURE__ */ jsxs("div", { className: cx$9("stepper-layout"), children: [
279
- /* @__PURE__ */ jsx("div", { className: cx$9("stepper"), children: items.map((item, idx) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
280
- /* @__PURE__ */ jsx(
281
- "div",
282
- {
283
- className: cx$9("circle", (defaultValue === item.value || current === idx) && "active"),
284
- onClick: () => onClickItem?.(item),
285
- children: item.isCompleted || idx < current ? /* @__PURE__ */ jsx("span", { className: cx$9("completed") }) : ++idx
286
- }
287
- ),
288
- idx < items.length && Array.from({ length: dotCount }).map((_, dotIdx) => /* @__PURE__ */ jsx("span", { className: cx$9("dot") }, `dot-${idx}-${dotIdx}`))
289
- ] }, `num-${idx}`)) }),
290
- /* @__PURE__ */ jsx("ul", { className: cx$9("step-labels"), children: items.map((item, idx) => /* @__PURE__ */ jsx("li", { className: cx$9((defaultValue === item.value || current === idx) && "active"), children: /* @__PURE__ */ jsx("span", { children: item.label ?? item.value }) }, `label-${idx}`)) })
291
- ] });
218
+ }
219
+ return replacedText;
220
+ }
221
+ return originalText;
292
222
  };
293
223
 
294
- const cx$8 = classNames.bind(styles$1);
295
- function Attachment({
296
- photos,
297
- onAddPhoto,
298
- onRemovePhoto,
299
- show,
300
- type = "multiple",
301
- buttonText
302
- }) {
303
- const handleAddPhoto = () => {
304
- onAddPhoto();
305
- };
306
- const handleRemovePhoto = (id) => {
307
- onRemovePhoto(id);
308
- };
309
- const renderPhotoSingle = () => {
310
- if (photos.length === 0) {
311
- return /* @__PURE__ */ jsx("div", { className: cx$8("single-photo-item", "add-photo-item"), children: /* @__PURE__ */ jsxs("button", { className: cx$8("add-photo-button-single"), onClick: handleAddPhoto, children: [
312
- /* @__PURE__ */ jsx(Icon, { name: "illust/camera" }),
313
- /* @__PURE__ */ jsx("span", { children: buttonText || "\uC0AC\uC9C4 \uCCA8\uBD80\uD558\uAE30" })
314
- ] }) });
315
- }
316
- return photos.map((photo) => /* @__PURE__ */ jsxs("div", { className: cx$8("single-photo-item"), children: [
317
- /* @__PURE__ */ jsx("div", { className: cx$8("photo-placeholder"), children: /* @__PURE__ */ jsx("img", { src: photo.src, alt: photo.name, className: cx$8("photo-image") }) }),
318
- /* @__PURE__ */ jsx("button", { className: cx$8("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
319
- ] }, photo.id));
320
- };
321
- const renderPhotoGrid = () => {
322
- const maxPhotos = type === "single" ? 1 : 4;
323
- const gridItems = [];
324
- if (photos.length < maxPhotos) {
325
- gridItems.push(
326
- /* @__PURE__ */ jsx("div", { className: cx$8("photo-item", "add-photo-item"), children: /* @__PURE__ */ jsxs("button", { className: cx$8("add-photo-button"), onClick: handleAddPhoto, children: [
327
- /* @__PURE__ */ jsx(Icon, { name: "illust/camera" }),
328
- /* @__PURE__ */ jsx("span", { children: buttonText || "\uCCA8\uBD80\uD558\uAE30" }),
329
- /* @__PURE__ */ jsxs("span", { className: cx$8("photo-count"), children: [
224
+ const cx$9 = classNames.bind(styles);
225
+ function JobSearchCategory({ filteredJobs, onJobSelect, searchTerm }) {
226
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: cx$9("category-section"), children: [
227
+ /* @__PURE__ */ jsxs("p", { className: cx$9("result-title"), children: [
228
+ "\uCD1D ",
229
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: filteredJobs.length }),
230
+ "\uAC74\uC758 \uAC80\uC0C9\uACB0\uACFC"
231
+ ] }),
232
+ /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsx(Radio.Root, { name: "job-selection", size: "small", className: cx$9("job-radio-root"), onToggle: () => {
233
+ }, children: filteredJobs.map((job, index) => /* @__PURE__ */ jsxs(
234
+ Accordion.Item,
235
+ {
236
+ id: `item-${job.occupationIndustryCode}-${index}-accordion`,
237
+ children: [
238
+ /* @__PURE__ */ jsx(Accordion.HeaderDiv, { children: /* @__PURE__ */ jsx("div", { style: { flex: 1 }, children: /* @__PURE__ */ jsxs(Radio.Item, { size: "small", value: job.occupationIndustryCode, onChange: () => onJobSelect(job), children: [
239
+ highlightOnSearchKeyword(job.occupationIndustryName, searchTerm),
330
240
  "(",
331
- /* @__PURE__ */ jsx("span", { className: cx$8("photo-count-number"), children: photos.length }),
332
- "/",
333
- maxPhotos,
241
+ job.occupationIndustryCode,
334
242
  ")"
335
- ] })
336
- ] }) }, "add-photo")
337
- );
338
- }
339
- photos.forEach((photo) => {
340
- gridItems.push(
341
- /* @__PURE__ */ jsxs("div", { className: cx$8("photo-item"), children: [
342
- /* @__PURE__ */ jsx("div", { className: cx$8("photo-placeholder"), children: /* @__PURE__ */ jsx("img", { src: photo.src, alt: photo.name, className: cx$8("photo-image") }) }),
343
- /* @__PURE__ */ jsx("button", { className: cx$8("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
344
- ] }, photo.id)
345
- );
346
- });
347
- return gridItems;
348
- };
349
- const isVisible = show || !show && photos.length > 0;
350
- if (!isVisible) {
351
- return null;
352
- }
353
- if (type === "single") {
354
- return /* @__PURE__ */ jsx("div", { className: cx$8("photo-single"), children: renderPhotoSingle() });
355
- }
356
- return /* @__PURE__ */ jsx("div", { className: cx$8("photo-grid", { linear: type === "linear" }), children: renderPhotoGrid() });
243
+ ] }) }) }),
244
+ /* @__PURE__ */ jsx(Accordion.Content, { variant: "text", children: /* @__PURE__ */ jsx(Table, { variant: "horizontal", children: /* @__PURE__ */ jsxs("tbody", { children: [
245
+ /* @__PURE__ */ jsxs("tr", { children: [
246
+ /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1" }),
247
+ /* @__PURE__ */ jsx("td", { className: "px-24", children: "1\uD589 1\uBC88\uC9F8" }),
248
+ /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1-2" }),
249
+ /* @__PURE__ */ jsx("td", { className: "px-24 ", children: "1\uD589 2\uBC88\uC9F8" })
250
+ ] }),
251
+ /* @__PURE__ */ jsxs("tr", { children: [
252
+ /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 2" }),
253
+ /* @__PURE__ */ jsx("td", { className: "pl-24 pr-16", colSpan: 3, children: /* @__PURE__ */ jsxs("p", { className: "d-flex-center-center", children: [
254
+ "2\uD589 1\uBC88\uC9F8 ",
255
+ /* @__PURE__ */ jsx("span", { className: "flex-1 pipe-left", children: "\uC11C\uBE0C\uD14D\uC2A4\uD2B8" }),
256
+ /* @__PURE__ */ jsx(Button, { variant: "neutral", size: "xsmall", appearance: "outline", children: "\uBC84\uD2BC\uBA85" })
257
+ ] }) })
258
+ ] })
259
+ ] }) }) })
260
+ ]
261
+ },
262
+ `item-${job.occupationIndustryCode}-${index}`
263
+ )) }) }),
264
+ filteredJobs.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
265
+ "`",
266
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: searchTerm }),
267
+ "`\uC5D0 \uB300\uD55C \uAC80\uC0C9\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
268
+ ] })
269
+ ] }) });
357
270
  }
358
271
 
359
- const maxImageSize = 3 * 1024 * 1024;
360
- function resize(image, options = { ext: "jpeg", filesize: maxImageSize }) {
361
- return new Promise((resolve, reject) => {
362
- const canvas = document.createElement("canvas");
363
- const ctx = canvas.getContext("2d");
364
- if (!ctx) {
365
- reject(new Error("Canvas context\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
366
- return;
367
- }
368
- const img = new Image();
369
- img.crossOrigin = "anonymous";
370
- img.onload = () => {
371
- let { width, height } = img;
372
- const { filesize, ext } = options;
373
- if (filesize) {
374
- const originalSize = width * height * 4;
375
- if (originalSize > filesize) {
376
- const ratio = Math.sqrt(filesize / originalSize);
377
- width = Math.floor(width * ratio);
378
- height = Math.floor(height * ratio);
379
- }
380
- } else {
381
- const { width: targetWidth, height: targetHeight } = options;
382
- if (targetWidth && targetHeight) {
383
- width = targetWidth;
384
- height = targetHeight;
385
- } else if (targetWidth) {
386
- const ratio = targetWidth / width;
387
- width = targetWidth;
388
- height = Math.floor(height * ratio);
389
- } else if (targetHeight) {
390
- const ratio = targetHeight / height;
391
- height = targetHeight;
392
- width = Math.floor(width * ratio);
393
- }
394
- }
395
- canvas.width = width;
396
- canvas.height = height;
397
- ctx.drawImage(img, 0, 0, width, height);
398
- if (typeof image === "string") {
399
- const mimeType = ext === "png" ? "image/png" : "image/jpeg";
400
- const quality = ext === "png" ? 1 : 0.8;
401
- const base64 = canvas.toDataURL(mimeType, quality);
402
- resolve(base64);
403
- } else {
404
- canvas.toBlob(
405
- (blob) => {
406
- if (!blob) {
407
- reject(new Error("Blob\uC744 \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
408
- return;
409
- }
410
- const mimeType = ext === "png" ? "image/png" : "image/jpeg";
411
- const fileName = image.name ? `${image.name.replace(/\.[^/.]+$/, "")}.${ext}` : `resized.${ext}`;
412
- const resizedFile = new File([blob], fileName, { type: mimeType });
413
- resolve(resizedFile);
414
- },
415
- ext === "png" ? "image/png" : "image/jpeg",
416
- ext === "png" ? 1 : 0.8
417
- );
418
- }
419
- };
420
- img.onerror = () => {
421
- reject(new Error("\uC774\uBBF8\uC9C0\uB97C \uB85C\uB4DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
422
- };
423
- if (typeof image === "string") {
424
- img.src = image;
425
- } else {
426
- const reader = new FileReader();
427
- reader.onload = (e) => {
428
- if (e.target?.result) {
429
- img.src = e.target.result;
430
- } else {
431
- reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
432
- }
433
- };
434
- reader.onerror = () => {
435
- reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
436
- };
437
- reader.readAsDataURL(image);
438
- }
439
- });
272
+ const cx$8 = classNames.bind(styles);
273
+ function JobSearchFavorite({ filteredJobs, onJobSelect }) {
274
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: cx$8("popular-jobs"), children: [
275
+ /* @__PURE__ */ jsx("p", { children: "\uB9CE\uC774 \uCC3E\uB294 \uC9C1\uC885" }),
276
+ /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsx(Radio.Root, { name: "job-selection", size: "small", className: cx$8("job-radio-root"), children: filteredJobs.map((job, index) => /* @__PURE__ */ jsxs(
277
+ Accordion.Item,
278
+ {
279
+ id: `item-${job.occupationIndustryCode}-${index}`,
280
+ className: cx$8("accordion-item"),
281
+ children: [
282
+ /* @__PURE__ */ jsx(Accordion.HeaderDiv, { className: cx$8("accordion-header-item"), children: /* @__PURE__ */ jsxs(
283
+ Radio.Item,
284
+ {
285
+ size: "small",
286
+ value: job.occupationIndustryCode,
287
+ onChange: () => onJobSelect(job),
288
+ className: cx$8("radio-item"),
289
+ children: [
290
+ job.occupationIndustryName,
291
+ "(",
292
+ job.occupationIndustryCode,
293
+ ")"
294
+ ]
295
+ }
296
+ ) }),
297
+ /* @__PURE__ */ jsx(Accordion.Content, { variant: "text", children: "\uD56D\uBAA9 1 \uB0B4\uC6A9" })
298
+ ]
299
+ },
300
+ `item-${job.occupationIndustryCode}-${index}`
301
+ )) }) })
302
+ ] }) });
440
303
  }
441
304
 
442
- const genImageId = () => `camera-${Date.now()}-${Math.random()}`;
443
- function useCamera({
444
- onChange,
445
- resize: resizeOption,
446
- cameraOnly,
447
- onDelete,
448
- show,
449
- type = "multiple",
450
- buttonText
451
- } = {}) {
452
- const [attachedPhotos, setAttachedPhotos] = useState([]);
453
- const findImage = (imageId) => {
454
- return attachedPhotos.find((image) => image.id === imageId);
455
- };
456
- const onClick = () => {
457
- const input = document.createElement("input");
458
- input.type = "file";
459
- input.accept = "image/*";
460
- if (cameraOnly) {
461
- input.capture = "camera";
462
- }
463
- input.addEventListener("change", async (event) => {
464
- const target = event.target;
465
- const { files } = target;
466
- if (files && files.length > 0) {
467
- const file = files[0];
468
- if (file) {
469
- const resizedFile = await resize(file, resizeOption);
470
- const newPhoto = {
471
- id: genImageId(),
472
- src: URL.createObjectURL(resizedFile),
473
- name: `\uC11C\uB958\uC0AC\uC9C4_${attachedPhotos.length + 1}`
474
- };
475
- if (type === "single") {
476
- setAttachedPhotos([newPhoto]);
477
- } else {
478
- setAttachedPhotos([...attachedPhotos, newPhoto]);
479
- }
480
- onChange && onChange(file);
481
- }
482
- }
483
- document.body.removeChild(input);
484
- });
485
- input.style.display = "none";
486
- document.body.appendChild(input);
487
- input.click();
488
- };
489
- const deleteImage = (imageId) => {
490
- const imageIndex = attachedPhotos.findIndex((image) => image.id === imageId);
491
- if (imageIndex > -1) {
492
- const item = attachedPhotos.splice(imageIndex, 1);
493
- item[0] && URL.revokeObjectURL(item[0].src);
494
- setAttachedPhotos([...attachedPhotos]);
495
- onDelete && onDelete(imageId);
496
- }
497
- };
498
- const CameraComponent = () => /* @__PURE__ */ jsx(
499
- Attachment,
500
- {
501
- show: !!show,
502
- onAddPhoto: onClick,
503
- onRemovePhoto: deleteImage,
504
- photos: attachedPhotos,
505
- type,
506
- buttonText
507
- }
508
- );
509
- useEffect(() => {
510
- return () => {
511
- attachedPhotos.forEach((image) => {
512
- URL.revokeObjectURL(image.src);
513
- });
514
- };
515
- }, []);
516
- return {
517
- onClick,
518
- getImage: findImage,
519
- deleteImage,
520
- attachedPhotos,
521
- Attachment: CameraComponent
522
- };
305
+ const cx$7 = classNames.bind(styles);
306
+ function JobSearchResult({ filteredJobs, onJobSelect, searchTerm }) {
307
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: cx$7("popular-jobs"), children: [
308
+ /* @__PURE__ */ jsxs("p", { className: cx$7("result-title"), children: [
309
+ "\uCD1D ",
310
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: filteredJobs.length }),
311
+ "\uAC74\uC758 \uAC80\uC0C9\uACB0\uACFC"
312
+ ] }),
313
+ /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsx(Radio.Root, { name: "job-selection", size: "small", className: cx$7("job-radio-root"), children: filteredJobs.map((job) => /* @__PURE__ */ jsxs(
314
+ Accordion.Item,
315
+ {
316
+ id: `item-${job.occupationIndustryCode}`,
317
+ children: [
318
+ /* @__PURE__ */ jsx(Accordion.HeaderDiv, { children: /* @__PURE__ */ jsx("div", { style: { flex: 1 }, children: /* @__PURE__ */ jsx(
319
+ Radio.Item,
320
+ {
321
+ id: `item-${job.occupationIndustryCode}`,
322
+ size: "small",
323
+ value: job.occupationIndustryCode,
324
+ onChange: () => {
325
+ onJobSelect(job);
326
+ },
327
+ children: highlightOnSearchKeyword(job.occupationIndustryName, searchTerm)
328
+ }
329
+ ) }) }),
330
+ /* @__PURE__ */ jsx(Accordion.Content, { variant: "text", children: /* @__PURE__ */ jsx(Table, { variant: "horizontal", children: /* @__PURE__ */ jsxs("tbody", { children: [
331
+ /* @__PURE__ */ jsxs("tr", { children: [
332
+ /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1" }),
333
+ /* @__PURE__ */ jsx("td", { className: "px-24", children: "1\uD589 1\uBC88\uC9F8" }),
334
+ /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1-2" }),
335
+ /* @__PURE__ */ jsx("td", { className: "px-24 ", children: "1\uD589 2\uBC88\uC9F8" })
336
+ ] }),
337
+ /* @__PURE__ */ jsxs("tr", { children: [
338
+ /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 2" }),
339
+ /* @__PURE__ */ jsx("td", { className: "pl-24 pr-16", colSpan: 3, children: /* @__PURE__ */ jsxs("p", { className: "d-flex-center-center", children: [
340
+ "2\uD589 1\uBC88\uC9F8 ",
341
+ /* @__PURE__ */ jsx("span", { className: "flex-1 pipe-left", children: "\uC11C\uBE0C\uD14D\uC2A4\uD2B8" }),
342
+ /* @__PURE__ */ jsx(Button, { variant: "neutral", size: "xsmall", appearance: "outline", children: "\uBC84\uD2BC\uBA85" })
343
+ ] }) })
344
+ ] })
345
+ ] }) }) })
346
+ ]
347
+ },
348
+ job.occupationIndustryCode
349
+ )) }) }),
350
+ filteredJobs.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
351
+ "`",
352
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: searchTerm }),
353
+ "`\uC5D0 \uB300\uD55C \uAC80\uC0C9\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
354
+ ] })
355
+ ] }) });
523
356
  }
524
357
 
525
- const HISTORY_SIZE = 100;
526
- const DEFAULT_DOWNLOAD_PROPS = {
527
- fileExtendsion: "png",
528
- fileName: "image",
529
- transparent: true,
530
- backgroundColor: "white",
531
- width: 500,
532
- height: 500
533
- };
534
- function useCanvasPaint(paintProps = {}) {
535
- const { pen = { strokeWeight: 5, strokeColor: "black" }, onChange, onStart, onEnd } = paintProps;
536
- const [canvasRefState, setCanvasRefState] = useState(null);
537
- const contextRef = useRef(null);
538
- const [isPainting, setIsPainting] = useState(false);
539
- const [history, setHistory] = useState([]);
540
- const [historyIndex, setHistoryIndex] = useState(-1);
541
- const saveState = useCallback(() => {
542
- if (!canvasRefState) {
543
- return;
544
- }
545
- const dataUrl = canvasRefState.toDataURL();
546
- const newHistory = history.slice(0, historyIndex + 1);
547
- if (newHistory.length >= HISTORY_SIZE) {
548
- newHistory.shift();
358
+ const { TextField } = FormField;
359
+ const cx$6 = classNames.bind(styles);
360
+ const { Option } = Select;
361
+ function JobSearch({
362
+ activeTab,
363
+ onTabChange,
364
+ searchTerm,
365
+ setSearchInput,
366
+ filteredJobs,
367
+ onJobSelect,
368
+ setSearchTerm,
369
+ searchInput,
370
+ firstCategory,
371
+ setFirstCategory,
372
+ secondCategory,
373
+ setSecondCategory,
374
+ firstCategoryList,
375
+ secondCategoryList
376
+ }) {
377
+ const onKeyUp = (e) => {
378
+ if (e.key === "Enter") {
379
+ setSearchTerm(searchInput);
549
380
  }
550
- newHistory.push(dataUrl);
551
- setHistory(newHistory);
552
- setHistoryIndex(newHistory.length - 1);
553
- onChange && onChange();
554
- }, [history, historyIndex, onChange, canvasRefState]);
555
- const restoreState = useCallback(
556
- (index) => {
557
- const context = contextRef.current;
558
- if (!canvasRefState || !context || !history[index]) {
559
- return;
381
+ };
382
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
383
+ /* @__PURE__ */ jsx(
384
+ Tab.Root,
385
+ {
386
+ defaultValue: activeTab,
387
+ onValueChange: onTabChange,
388
+ scroll: "fixed",
389
+ size: "small",
390
+ variant: "sub",
391
+ style: { gap: 0, overflow: "visible" },
392
+ children: JOB_SEARCH_TABS.map((tab) => /* @__PURE__ */ jsx(Tab.Item, { value: tab.value, children: tab.label }, tab.value))
560
393
  }
561
- const dataUrl = history[index];
562
- const img = new Image();
563
- img.onload = () => {
564
- context.clearRect(0, 0, canvasRefState.width, canvasRefState.height);
565
- context.drawImage(img, 0, 0);
566
- };
567
- img.src = dataUrl;
568
- onChange && onChange();
569
- },
570
- [history, onChange, canvasRefState]
571
- );
572
- useEffect(() => {
573
- if (!canvasRefState) {
574
- return;
575
- }
576
- const context = canvasRefState.getContext("2d", { willReadFrequently: true });
577
- if (!context) {
578
- return;
579
- }
580
- contextRef.current = context;
581
- const initialDataUrl = canvasRefState.toDataURL();
582
- setHistory([initialDataUrl]);
583
- setHistoryIndex(0);
584
- }, [canvasRefState]);
394
+ ),
395
+ /* @__PURE__ */ jsxs("div", { children: [
396
+ activeTab === "jobName" && /* @__PURE__ */ jsxs("div", { className: cx$6("favorite-jobs-section"), children: [
397
+ /* @__PURE__ */ jsx(
398
+ TextField,
399
+ {
400
+ placeholder: "\uC9C1\uC885\uBA85 \uAC80\uC0C9",
401
+ value: searchInput,
402
+ onKeyUp,
403
+ onChange: (e) => setSearchInput(e.target.value),
404
+ className: styles.searchInput,
405
+ size: "medium",
406
+ rootProps: {
407
+ endElement: /* @__PURE__ */ jsx(Icon, { name: "sub-ui/search", onClick: () => setSearchTerm(searchInput) }),
408
+ onClear: () => {
409
+ setSearchTerm("");
410
+ setSearchInput("");
411
+ }
412
+ }
413
+ }
414
+ ),
415
+ !searchTerm && /* @__PURE__ */ jsx(JobSearchFavorite, { filteredJobs, onJobSelect }),
416
+ searchTerm && /* @__PURE__ */ jsx(JobSearchResult, { filteredJobs, onJobSelect, searchTerm })
417
+ ] }),
418
+ activeTab === "jobCode" && /* @__PURE__ */ jsxs("div", { className: cx$6("select-jobs-section"), children: [
419
+ /* @__PURE__ */ jsxs("div", { className: cx$6("category-section"), children: [
420
+ /* @__PURE__ */ jsx(
421
+ Select,
422
+ {
423
+ name: "first_category",
424
+ onChange: (value) => {
425
+ setFirstCategory(value);
426
+ setSecondCategory("");
427
+ },
428
+ placeholder: "\uB300\uBD84\uB958 \uC120\uD0DD",
429
+ rootProps: {
430
+ style: {
431
+ // width: '300px'
432
+ }
433
+ },
434
+ size: "large",
435
+ value: firstCategory,
436
+ children: firstCategoryList.map((option, index) => /* @__PURE__ */ jsx(Option, { value: option.occupationIndustryCode, children: option.occupationIndustryName }, `${index}-${option.occupationIndustryCode}`))
437
+ }
438
+ ),
439
+ /* @__PURE__ */ jsx(
440
+ Select,
441
+ {
442
+ name: "second_category",
443
+ onChange: setSecondCategory,
444
+ placeholder: "\uC911\uBD84\uB958 \uC120\uD0DD",
445
+ rootProps: {
446
+ style: {
447
+ // width: '300px'
448
+ }
449
+ },
450
+ size: "large",
451
+ value: secondCategory,
452
+ disabled: !firstCategory,
453
+ children: secondCategoryList.map((option, index) => /* @__PURE__ */ jsx(Option, { value: option.occupationIndustryCode, children: option.occupationIndustryName }, `${index}-${option.occupationIndustryCode}`))
454
+ }
455
+ )
456
+ ] }),
457
+ firstCategory && secondCategory && /* @__PURE__ */ jsx(JobSearchCategory, { filteredJobs, onJobSelect, searchTerm })
458
+ ] })
459
+ ] })
460
+ ] });
461
+ }
462
+
463
+ const initData = [
464
+ {
465
+ occupationIndustryCode: "430101",
466
+ occupationIndustryName: "\uD68C\uC0AC \uC0AC\uBB34\uC9C1 \uC885\uC0AC\uC790",
467
+ occupationTypeCode: null,
468
+ historySequence: 0
469
+ },
470
+ {
471
+ occupationIndustryCode: "400301",
472
+ occupationIndustryName: "\uACBD\uC601\uC9C0\uC6D0 \uC0AC\uBB34\uC9C1 \uAD00\uB9AC\uC790",
473
+ occupationTypeCode: null,
474
+ historySequence: 0
475
+ },
476
+ {
477
+ occupationIndustryCode: "510201",
478
+ occupationIndustryName: "\uC804\uC5C5\uC8FC\uBD80",
479
+ occupationTypeCode: null,
480
+ historySequence: 0
481
+ },
482
+ {
483
+ occupationIndustryCode: "442501",
484
+ occupationIndustryName: "\uC8FC\uBC29\uC7A5 \uBC0F \uC870\uB9AC\uC0AC(\uC120\uBC15 \uC870\uB9AC\uC0AC \uC81C\uC678)",
485
+ occupationTypeCode: null,
486
+ historySequence: 0
487
+ },
488
+ {
489
+ occupationIndustryCode: "450303",
490
+ occupationIndustryName: "\uBCF4\uD5D8\uC124\uACC4\uC0AC(\uB2F9\uC0AC)",
491
+ occupationTypeCode: null,
492
+ historySequence: 0
493
+ }
494
+ ];
495
+ const useJobSearch = () => {
496
+ const [activeTab, setActiveTab] = useState(JOB_SEARCH_TABS[0]?.value ?? "");
497
+ const [selectedJob, setSelectedJob] = useState(null);
498
+ const [searchTerm, setSearchTerm] = useState("");
499
+ const [searchInput, setSearchInput] = useState("");
500
+ const handleJobSelect = (job) => {
501
+ setSelectedJob(job);
502
+ };
503
+ const [firstCategory, setFirstCategory] = useState("");
504
+ const [secondCategory, setSecondCategory] = useState("");
505
+ const [jobList, setJobList] = useState(initData);
506
+ const [firstCategoryList, setFirstCategoryList] = useState([]);
507
+ const [secondCategoryList, setSecondCategoryList] = useState([]);
508
+ const { data } = useSearchOccupationQuery({
509
+ occupationMajorCategoryCode: firstCategory,
510
+ occupationSearchTypeCode: searchTerm ? "4" : "3",
511
+ occupationSubCategoryCode: secondCategory,
512
+ searchOccupationIndustryName: searchTerm
513
+ });
514
+ const { data: firstCategoryData } = useSearchOccupationQuery({
515
+ occupationMajorCategoryCode: "",
516
+ occupationSearchTypeCode: "1",
517
+ occupationSubCategoryCode: "",
518
+ searchOccupationIndustryName: ""
519
+ });
520
+ const { data: secondCategoryData } = useSearchOccupationQuery({
521
+ occupationMajorCategoryCode: firstCategory,
522
+ occupationSearchTypeCode: "2",
523
+ occupationSubCategoryCode: "",
524
+ searchOccupationIndustryName: ""
525
+ });
585
526
  useEffect(() => {
586
- const context = contextRef.current;
587
- if (context) {
588
- context.lineWidth = pen.strokeWeight;
589
- context.strokeStyle = pen.strokeColor;
590
- }
591
- }, [pen]);
592
- const getEventPosition = useCallback(
593
- (event) => {
594
- if (!canvasRefState) {
595
- return null;
596
- }
597
- const rect = canvasRefState.getBoundingClientRect();
598
- const scaleX = canvasRefState.width / rect.width;
599
- const scaleY = canvasRefState.height / rect.height;
600
- let clientX;
601
- let clientY;
602
- if (event instanceof MouseEvent) {
603
- clientX = event.clientX;
604
- clientY = event.clientY;
605
- } else if (event instanceof TouchEvent) {
606
- const touch = event.touches[0];
607
- if (!touch) {
608
- return null;
609
- }
610
- clientX = touch.clientX;
611
- clientY = touch.clientY;
612
- } else {
613
- return null;
614
- }
615
- const offsetX = (clientX - rect.left) * scaleX;
616
- const offsetY = (clientY - rect.top) * scaleY;
617
- return { offsetX, offsetY };
618
- },
619
- [canvasRefState]
620
- );
621
- const startPainting = useCallback(
622
- (event) => {
623
- event.preventDefault();
624
- const context = contextRef.current;
625
- if (!context) {
626
- return;
627
- }
628
- const pos = getEventPosition(event);
629
- if (!pos) {
630
- return;
631
- }
632
- onStart && onStart();
633
- const { offsetX, offsetY } = pos;
634
- context.beginPath();
635
- context.moveTo(offsetX, offsetY);
636
- setIsPainting(true);
637
- },
638
- [onStart, getEventPosition]
639
- );
640
- const stopPainting = useCallback(() => {
641
- const context = contextRef.current;
642
- if (!context || !isPainting) {
643
- return;
527
+ if (data && searchTerm && activeTab === "jobName") {
528
+ const filteredJobs = data.data.occupationList.filter((job) => job.occupationIndustryName.includes(searchTerm));
529
+ setJobList(filteredJobs);
530
+ } else if (!data && searchTerm && activeTab === "jobName") {
531
+ setJobList([]);
532
+ } else if (!searchTerm && activeTab === "jobName") {
533
+ setJobList(initData);
534
+ } else if (activeTab === "jobCode" && firstCategory && secondCategory) {
535
+ setJobList(data?.data.occupationList || []);
644
536
  }
645
- context.closePath();
646
- setIsPainting(false);
647
- onEnd && onEnd();
648
- saveState();
649
- }, [isPainting, onEnd, saveState]);
650
- const paint = useCallback(
651
- (event) => {
652
- event.preventDefault();
653
- if (!isPainting || !contextRef.current) {
654
- return;
655
- }
656
- const pos = getEventPosition(event);
657
- if (!pos) {
658
- return;
659
- }
660
- const { offsetX, offsetY } = pos;
661
- contextRef.current.lineTo(offsetX, offsetY);
662
- contextRef.current.stroke();
663
- },
664
- [isPainting, getEventPosition]
665
- );
537
+ }, [searchTerm, data, firstCategory, secondCategory, secondCategoryData, activeTab]);
666
538
  useEffect(() => {
667
- if (!canvasRefState) {
668
- return;
669
- }
670
- canvasRefState.addEventListener("mousedown", startPainting);
671
- canvasRefState.addEventListener("mouseup", stopPainting);
672
- canvasRefState.addEventListener("mousemove", paint);
673
- canvasRefState.addEventListener("mouseleave", stopPainting);
674
- canvasRefState.addEventListener("touchstart", startPainting);
675
- canvasRefState.addEventListener("touchend", stopPainting);
676
- canvasRefState.addEventListener("touchmove", paint);
677
- canvasRefState.addEventListener("touchcancel", stopPainting);
678
- return () => {
679
- canvasRefState.removeEventListener("mousedown", startPainting);
680
- canvasRefState.removeEventListener("mouseup", stopPainting);
681
- canvasRefState.removeEventListener("mousemove", paint);
682
- canvasRefState.removeEventListener("mouseleave", stopPainting);
683
- canvasRefState.removeEventListener("touchstart", startPainting);
684
- canvasRefState.removeEventListener("touchend", stopPainting);
685
- canvasRefState.removeEventListener("touchmove", paint);
686
- canvasRefState.removeEventListener("touchcancel", stopPainting);
687
- };
688
- }, [startPainting, stopPainting, paint, canvasRefState]);
689
- const clear = () => {
690
- const context = contextRef.current;
691
- if (canvasRefState && context) {
692
- context.clearRect(0, 0, canvasRefState.width, canvasRefState.height);
693
- const initialDataUrl = canvasRefState.toDataURL();
694
- setHistory([initialDataUrl]);
695
- setHistoryIndex(0);
696
- onChange && onChange();
697
- }
698
- };
699
- const undo = () => {
700
- if (historyIndex > 0) {
701
- const newIndex = historyIndex - 1;
702
- setHistoryIndex(newIndex);
703
- restoreState(newIndex);
704
- }
705
- };
706
- const redo = () => {
707
- if (historyIndex < history.length - 1) {
708
- const newIndex = historyIndex + 1;
709
- setHistoryIndex(newIndex);
710
- restoreState(newIndex);
711
- }
712
- };
713
- const loadImage = (base64String) => {
714
- const context = contextRef.current;
715
- if (!canvasRefState || !context) {
716
- return;
717
- }
718
- const img = new Image();
719
- img.onload = () => {
720
- context.clearRect(0, 0, canvasRefState.width, canvasRefState.height);
721
- context.drawImage(img, 0, 0, canvasRefState.width, canvasRefState.height);
722
- saveState();
723
- };
724
- img.src = base64String;
725
- };
726
- const getBase64String = (imageProps) => {
727
- const props = { ...DEFAULT_DOWNLOAD_PROPS, ...imageProps };
728
- const { fileExtendsion, transparent, backgroundColor, width, height } = props;
729
- const originalCanvas = canvasRefState;
730
- if (!originalCanvas) {
731
- return;
732
- }
733
- const tempCanvas = document.createElement("canvas");
734
- tempCanvas.width = width;
735
- tempCanvas.height = height;
736
- const tempCtx = tempCanvas.getContext("2d");
737
- if (tempCtx) {
738
- if (!transparent) {
739
- tempCtx.fillStyle = backgroundColor || "white";
740
- tempCtx.fillRect(0, 0, width, height);
741
- }
742
- tempCtx.drawImage(originalCanvas, 0, 0, width, height);
743
- return tempCanvas.toDataURL(`image/${fileExtendsion}`);
744
- }
745
- };
746
- const download = (downloadProps) => {
747
- const props = { ...DEFAULT_DOWNLOAD_PROPS, ...downloadProps };
748
- const { fileName, fileExtendsion, transparent, backgroundColor, width, height } = props;
749
- const originalCanvas = canvasRefState;
750
- if (!originalCanvas) {
751
- return;
752
- }
753
- const tempCanvas = document.createElement("canvas");
754
- tempCanvas.width = width;
755
- tempCanvas.height = height;
756
- const tempCtx = tempCanvas.getContext("2d");
757
- if (tempCtx) {
758
- if (!transparent) {
759
- tempCtx.fillStyle = backgroundColor || "white";
760
- tempCtx.fillRect(0, 0, width, height);
761
- }
762
- tempCtx.drawImage(originalCanvas, 0, 0, width, height);
763
- const link = document.createElement("a");
764
- link.download = `${fileName}.${fileExtendsion}`;
765
- link.href = tempCanvas.toDataURL(`image/${fileExtendsion}`);
766
- link.click();
767
- }
768
- };
769
- const isCanvasBlank = () => {
770
- if (!canvasRefState) {
771
- return true;
772
- }
773
- const { width, height } = canvasRefState;
774
- const ctx = canvasRefState.getContext("2d");
775
- if (!ctx) {
776
- console.error("2D context not available");
777
- return true;
778
- }
779
- const imageData = ctx.getImageData(0, 0, width, height);
780
- const { data } = imageData;
781
- for (let i = 0; i < data.length; i += 4) {
782
- if (data[i + 3] !== 0) {
783
- return false;
784
- }
539
+ console.log("jobList", jobList);
540
+ }, [jobList]);
541
+ useEffect(() => {
542
+ if (firstCategoryData) {
543
+ setFirstCategoryList(firstCategoryData.data.occupationList);
785
544
  }
786
- return true;
545
+ }, [firstCategoryData]);
546
+ useEffect(() => {
547
+ if (secondCategoryData) {
548
+ setSecondCategoryList(secondCategoryData.data.occupationList);
549
+ }
550
+ }, [secondCategoryData]);
551
+ return {
552
+ activeTab,
553
+ setActiveTab,
554
+ selectedJob,
555
+ searchTerm,
556
+ setSearchTerm,
557
+ handleJobSelect,
558
+ filteredJobs: jobList,
559
+ searchInput,
560
+ setSearchInput,
561
+ firstCategory,
562
+ setFirstCategory,
563
+ secondCategory,
564
+ setSecondCategory,
565
+ secondCategoryList,
566
+ firstCategoryList
567
+ };
568
+ };
569
+ function useJobSearchModal() {
570
+ const {
571
+ activeTab,
572
+ setActiveTab,
573
+ searchTerm,
574
+ setSearchTerm,
575
+ filteredJobs,
576
+ handleJobSelect,
577
+ selectedJob,
578
+ searchInput,
579
+ setSearchInput,
580
+ firstCategory,
581
+ setFirstCategory,
582
+ secondCategory,
583
+ setSecondCategory,
584
+ firstCategoryList,
585
+ secondCategoryList
586
+ } = useJobSearch();
587
+ const { isOpen, openModal, closeModal } = useModalState();
588
+ const onTabChange = (value) => {
589
+ setSearchTerm("");
590
+ setFirstCategory("");
591
+ setSecondCategory("");
592
+ setActiveTab(value);
787
593
  };
788
594
  return {
789
- clear,
790
- undo,
791
- redo,
792
- loadImage,
793
- download,
794
- getBase64String,
795
- isCanvasBlank,
796
- setCanvasRefState,
797
- canvasRefState
595
+ JobSearchModal: /* @__PURE__ */ jsxs(Modal.Root, { isOpen, onClose: closeModal, modalSize: "xlarge", children: [
596
+ /* @__PURE__ */ jsx(Modal.Overlay, {}),
597
+ /* @__PURE__ */ jsxs(Modal.Content, { style: { height: "697px" }, children: [
598
+ /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uC9C1\uC885 \uAC80\uC0C9", showCloseButton: true }),
599
+ /* @__PURE__ */ jsx(Modal.Body, { raw: true, children: /* @__PURE__ */ jsx(
600
+ JobSearch,
601
+ {
602
+ firstCategory,
603
+ firstCategoryList,
604
+ secondCategoryList,
605
+ setFirstCategory,
606
+ secondCategory,
607
+ activeTab,
608
+ onTabChange,
609
+ searchTerm,
610
+ setSearchInput,
611
+ filteredJobs: filteredJobs || [],
612
+ onJobSelect: handleJobSelect,
613
+ searchInput,
614
+ setSearchTerm,
615
+ setSecondCategory
616
+ }
617
+ ) }),
618
+ /* @__PURE__ */ jsx(Modal.Footer, { children: /* @__PURE__ */ jsx(Button, { variant: "primary", size: "medium", appearance: "filled", width: "full", onClick: closeModal, children: "\uD655\uC778" }) })
619
+ ] })
620
+ ] }),
621
+ JobSearchComponent: /* @__PURE__ */ jsx(
622
+ JobSearch,
623
+ {
624
+ firstCategoryList,
625
+ secondCategoryList,
626
+ firstCategory,
627
+ setFirstCategory,
628
+ secondCategory,
629
+ setSecondCategory,
630
+ activeTab,
631
+ onTabChange,
632
+ searchTerm,
633
+ setSearchInput,
634
+ filteredJobs: filteredJobs || [],
635
+ onJobSelect: handleJobSelect,
636
+ searchInput,
637
+ setSearchTerm
638
+ }
639
+ ),
640
+ isJobSearchOpen: isOpen,
641
+ openJobSearchModal: openModal,
642
+ closeJobSearchModal: closeModal,
643
+ selectedJob
798
644
  };
799
645
  }
800
646
 
801
- const testSignatureBase64Data = "data:image/png;base64,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";
802
-
803
- const FloatingButton = ({ onClick }) => {
804
- const [position, setPosition] = useState({ x: 0, y: 0 });
805
- const [isDragging, setIsDragging] = useState(false);
806
- const dragHappened = useRef(false);
807
- const dragStartPos = useRef({ x: 0, y: 0 });
808
- const elementStartPos = useRef({ x: 0, y: 0 });
809
- const handleMouseDown = (e) => {
810
- if (e.button !== 0) {
811
- return;
647
+ const FormSearchJobField = ({
648
+ name,
649
+ control,
650
+ disabled,
651
+ rootProps,
652
+ error,
653
+ size = "medium",
654
+ placeholder = "\uC9C1\uC885 \uAC80\uC0C9",
655
+ ...props
656
+ }) => {
657
+ const [selected, setSelected] = useState();
658
+ const { field, fieldState } = useController({ name, control, disabled });
659
+ const { JobSearchModal, openJobSearchModal, selectedJob } = useJobSearchModal();
660
+ useEffect(() => {
661
+ if (selectedJob) {
662
+ setSelected(selectedJob);
663
+ field.onChange(selectedJob.occupationIndustryCode);
664
+ props.onValueChange?.(selectedJob);
812
665
  }
813
- dragHappened.current = false;
814
- setIsDragging(true);
815
- dragStartPos.current = { x: e.clientX, y: e.clientY };
816
- elementStartPos.current = { ...position };
817
- const handleMouseMove = (event) => {
818
- const dx = event.clientX - dragStartPos.current.x;
819
- const dy = event.clientY - dragStartPos.current.y;
820
- if (!dragHappened.current && (Math.abs(dx) > 5 || Math.abs(dy) > 5)) {
821
- dragHappened.current = true;
666
+ }, [selectedJob]);
667
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
668
+ /* @__PURE__ */ jsx(
669
+ FormField.TextField,
670
+ {
671
+ ...props,
672
+ ...field,
673
+ id: field.name,
674
+ error: fieldState.invalid || error,
675
+ value: selected?.occupationIndustryName ?? "",
676
+ rootProps: {
677
+ ...rootProps,
678
+ endElement: /* @__PURE__ */ jsx(Icon, { name: "sub-ui/search" })
679
+ },
680
+ readOnly: true,
681
+ size,
682
+ placeholder,
683
+ style: { background: "#fff", cursor: "pointer" },
684
+ autoComplete: "off",
685
+ onClick: openJobSearchModal
822
686
  }
823
- setPosition({
824
- x: elementStartPos.current.x + dx,
825
- y: elementStartPos.current.y + dy
826
- });
827
- };
828
- const handleMouseUp = () => {
829
- window.removeEventListener("mousemove", handleMouseMove);
830
- window.removeEventListener("mouseup", handleMouseUp);
831
- setIsDragging(false);
832
- };
833
- window.addEventListener("mousemove", handleMouseMove);
834
- window.addEventListener("mouseup", handleMouseUp);
835
- };
836
- const handleClick = (e) => {
837
- if (dragHappened.current) {
838
- e.preventDefault();
839
- e.stopPropagation();
840
- return;
841
- }
842
- onClick();
843
- };
844
- return /* @__PURE__ */ jsx(
845
- Button,
846
- {
847
- variant: "secondary",
848
- appearance: "filled",
849
- size: "xsmall",
850
- className: styles$2["debug-floating-button"],
851
- style: {
852
- transform: `translate(${position.x}px, ${position.y}px)`,
853
- cursor: isDragging ? "grabbing" : "grab"
854
- },
855
- onMouseDown: handleMouseDown,
856
- onClick: handleClick,
857
- children: "DEBUG"
858
- }
859
- );
860
- };
861
-
862
- const MenuPanel = ({ menuItems, onMenuItemClick, onClose }) => {
863
- return /* @__PURE__ */ jsxs(Modal.Root, { isOpen: true, onClose, modalSize: "small", children: [
864
- /* @__PURE__ */ jsx(Modal.Overlay, {}),
865
- /* @__PURE__ */ jsxs(Modal.Content, { children: [
866
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "Debug Menu", showCloseButton: true }),
867
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx(List, { selectable: true, children: menuItems.map((item) => /* @__PURE__ */ jsx(ListItem, { onClick: () => onMenuItemClick(item.component), children: item.label }, item.id)) }) })
868
- ] })
687
+ ),
688
+ JobSearchModal
869
689
  ] });
870
690
  };
871
691
 
872
- let globalLogs = [];
873
- let listeners = [];
874
- const originalConsoleMethods = {};
875
- let isConsoleOverridden = false;
876
- const addLog = (type, ...args) => {
877
- const newLog = {
878
- id: Date.now() + Math.random(),
879
- type,
880
- timestamp: (/* @__PURE__ */ new Date()).toLocaleTimeString(),
881
- message: args
882
- };
883
- globalLogs = [...globalLogs, newLog];
884
- listeners.forEach((listener) => listener([...globalLogs]));
885
- };
886
- const initializeConsoleLogOverride = () => {
887
- if (!isClient() || isConsoleOverridden) {
888
- return;
889
- }
890
- const logTypes = ["log", "info", "warn", "error", "debug"];
891
- logTypes.forEach((type) => {
892
- originalConsoleMethods[type] = console[type];
893
- console[type] = (...args) => {
894
- if (originalConsoleMethods[type]) {
895
- originalConsoleMethods[type]?.apply(console, args);
896
- }
897
- addLog(type, ...args);
692
+ const FormSegmentGroup = ({
693
+ name,
694
+ control,
695
+ disabled,
696
+ disabledItems,
697
+ items,
698
+ ...props
699
+ }) => {
700
+ const { field, fieldState } = useController({ name, control, disabled });
701
+ const itemList = items.map((item) => {
702
+ return {
703
+ ...item,
704
+ disabled: disabledItems?.includes(item.value)
898
705
  };
899
706
  });
900
- isConsoleOverridden = true;
901
- };
902
- const restoreConsoleLog = () => {
903
- if (!isClient() || !isConsoleOverridden) {
904
- return;
905
- }
906
- const logTypes = ["log", "info", "warn", "error", "debug"];
907
- logTypes.forEach((type) => {
908
- if (originalConsoleMethods[type]) {
909
- console[type] = originalConsoleMethods[type];
707
+ return /* @__PURE__ */ jsx(
708
+ SegmentGroup,
709
+ {
710
+ ...props,
711
+ tabIndex: 0,
712
+ id: field.name,
713
+ ref: field.ref,
714
+ defaultValue: field.value,
715
+ disabled: field.disabled,
716
+ error: fieldState.invalid,
717
+ onBlur: field.onBlur,
718
+ items: itemList,
719
+ onValueChange: (selected) => {
720
+ field.onChange(selected);
721
+ props.onValueChange?.(selected);
722
+ }
910
723
  }
911
- });
912
- isConsoleOverridden = false;
913
- };
914
- const useConsoleLog = () => {
915
- const [logs, setLogs] = useState(globalLogs);
916
- useEffect(() => {
917
- listeners.push(setLogs);
918
- return () => {
919
- listeners = listeners.filter((l) => l !== setLogs);
920
- };
921
- }, []);
922
- const clearLogs = useCallback(() => {
923
- globalLogs = [];
924
- listeners.forEach((listener) => listener([]));
925
- }, []);
926
- return { logs, clearLogs };
724
+ );
927
725
  };
928
726
 
929
- const safeStringify$1 = (obj) => {
930
- try {
931
- return JSON.stringify(obj, null, 2);
932
- } catch (e) {
933
- return "[Unserializable Object]";
934
- }
935
- };
936
- const LogMessage = ({ entry }) => {
937
- const messageParts = entry.message.map((part) => {
938
- if (typeof part === "object" && part !== null) {
939
- return safeStringify$1(part);
727
+ const FormSelect = ({
728
+ name,
729
+ control,
730
+ disabled,
731
+ error,
732
+ children,
733
+ ...props
734
+ }) => {
735
+ const { field, fieldState } = useController({ name, control, disabled });
736
+ return /* @__PURE__ */ jsx(
737
+ Select,
738
+ {
739
+ ...props,
740
+ id: field.name,
741
+ disabled: field.disabled,
742
+ error: fieldState.invalid || error,
743
+ onBlur: field.onBlur,
744
+ value: field.value,
745
+ onChange: (selected) => {
746
+ field.onChange(selected);
747
+ },
748
+ children
940
749
  }
941
- return String(part);
942
- });
943
- return /* @__PURE__ */ jsx("pre", { className: `${styles$2["log-message"]} ${styles$2[`log-${entry.type}`]}`, children: messageParts.join(" ") });
750
+ );
944
751
  };
945
- const ConsoleLogPanel = ({ onClose }) => {
946
- const { logs, clearLogs } = useConsoleLog();
947
- const [filter, setFilter] = useState("all");
948
- const logContainerRef = useRef(null);
949
- const filteredLogs = useMemo(() => {
950
- if (filter === "all") {
951
- return logs;
952
- }
953
- return logs.filter((log) => log.type === filter);
954
- }, [logs, filter]);
955
- useEffect(() => {
956
- if (logContainerRef.current) {
957
- logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight;
958
- }
959
- }, [filteredLogs]);
960
- return /* @__PURE__ */ jsx(Modal.Root, { isOpen: true, onClose, modalSize: "full-screen", children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
961
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "Console Logs", showCloseButton: true }),
962
- /* @__PURE__ */ jsxs(Modal.Body, { children: [
963
- /* @__PURE__ */ jsxs("div", { className: styles$2["panel-toolbar"], children: [
964
- /* @__PURE__ */ jsxs(
965
- Segment.Root,
966
- {
967
- size: "xsmall",
968
- appearance: "outline",
969
- align: "left",
970
- defaultValue: filter,
971
- onValueChange: (value) => setFilter(value),
972
- children: [
973
- /* @__PURE__ */ jsx(Segment.Item, { value: "all", children: "All" }),
974
- /* @__PURE__ */ jsx(Segment.Item, { value: "log", children: "Log" }),
975
- /* @__PURE__ */ jsx(Segment.Item, { value: "warn", children: "Warn" }),
976
- /* @__PURE__ */ jsx(Segment.Item, { value: "error", children: "Error" })
977
- ]
978
- }
979
- ),
980
- /* @__PURE__ */ jsx(
981
- Button,
982
- {
983
- variant: "neutral",
984
- appearance: "outline",
985
- size: "xsmall",
986
- onClick: clearLogs,
987
- style: { marginLeft: "auto" },
988
- children: "Clear"
989
- }
990
- )
991
- ] }),
992
- /* @__PURE__ */ jsx("div", { className: styles$2["log-list-container"], ref: logContainerRef, children: filteredLogs.map((log) => /* @__PURE__ */ jsxs("div", { className: styles$2["log-item"], children: [
993
- /* @__PURE__ */ jsx("span", { className: styles$2["log-timestamp"], children: log.timestamp }),
994
- /* @__PURE__ */ jsx(LogMessage, { entry: log })
995
- ] }, log.id)) })
996
- ] })
997
- ] }) });
752
+ const FormSelectOption = ({ children, value, ...rest }) => {
753
+ return /* @__PURE__ */ jsx(Select.Option, { value, ...rest, children });
754
+ };
755
+ const FormSelectGroup = ({
756
+ options,
757
+ optionsProps,
758
+ ...props
759
+ }) => {
760
+ return /* @__PURE__ */ jsx(FormSelect, { ...props, children: options.map((option) => /* @__PURE__ */ jsx(FormSelectOption, { value: option.value, ...optionsProps, children: option.label }, option.value)) });
998
761
  };
762
+ FormSelect.Option = FormSelectOption;
763
+ FormSelect.Group = FormSelectGroup;
999
764
 
1000
- const LoginPanel = ({ onClose, onLogin }) => {
1001
- const [selectedTypeId, setSelectedTypeId] = useState(loginTypes[0]?.id || "");
1002
- const [formData, setFormData] = useState({});
1003
- const selectedType = useMemo(() => loginTypes.find((t) => t.id === selectedTypeId), [selectedTypeId]);
1004
- const handleInputChange = (e) => {
1005
- const { name, value } = e.target;
1006
- setFormData((prev) => ({ ...prev, [name]: value }));
1007
- };
1008
- const handleSubmit = (e) => {
1009
- e.preventDefault();
1010
- if (selectedType) {
1011
- onLogin(selectedType.id, formData);
1012
- onClose();
765
+ const FormTextField = ({
766
+ name,
767
+ control,
768
+ size = "medium",
769
+ disabled,
770
+ error,
771
+ onBlur,
772
+ onChange,
773
+ rootProps,
774
+ ...props
775
+ }) => {
776
+ const { field, fieldState } = useController({ name, control, disabled });
777
+ return /* @__PURE__ */ jsx(
778
+ FormField.TextField,
779
+ {
780
+ ...props,
781
+ id: field.name,
782
+ size,
783
+ autoComplete: "off",
784
+ name: field.name,
785
+ value: field.value ?? "",
786
+ disabled: field.disabled,
787
+ error: fieldState.invalid || error,
788
+ onChange: (e) => {
789
+ field.onChange(e);
790
+ onChange?.(e);
791
+ },
792
+ onBlur: (e) => {
793
+ field.onBlur();
794
+ onBlur?.(e);
795
+ },
796
+ rootProps: {
797
+ ...rootProps,
798
+ onClear: () => {
799
+ field.onChange("");
800
+ rootProps?.onClear?.();
801
+ }
802
+ }
1013
803
  }
1014
- };
1015
- useEffect(() => {
1016
- setFormData({});
1017
- }, [selectedType]);
1018
- return /* @__PURE__ */ jsx(Modal.Root, { isOpen: true, onClose, modalSize: "full-screen", children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1019
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uAC04\uD3B8 \uB85C\uADF8\uC778", showCloseButton: true }),
1020
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs("form", { className: styles$2["login-form-container"], onSubmit: handleSubmit, children: [
1021
- /* @__PURE__ */ jsxs(FormField.FieldControl, { children: [
1022
- /* @__PURE__ */ jsx(FormField.Label, { htmlFor: "login-type-select", children: "\uB85C\uADF8\uC778 \uC720\uD615" }),
1023
- /* @__PURE__ */ jsx(
1024
- Select,
1025
- {
1026
- value: selectedTypeId,
1027
- onChange: setSelectedTypeId,
1028
- size: "xsmall",
1029
- rootProps: { style: { width: "100%" } },
1030
- children: loginTypes.map((type) => /* @__PURE__ */ jsx(Select.Option, { value: type.id, children: type.label }, type.id))
1031
- }
1032
- )
1033
- ] }),
1034
- selectedType?.fields.map((field) => /* @__PURE__ */ jsxs(FormField.FieldControl, { children: [
1035
- /* @__PURE__ */ jsx(FormField.Label, { htmlFor: field.name, children: field.label }),
1036
- /* @__PURE__ */ jsx(
1037
- FormField.TextField,
1038
- {
1039
- size: "xsmall",
1040
- type: field.type,
1041
- id: field.name,
1042
- name: field.name,
1043
- placeholder: field.placeholder,
1044
- value: formData[field.name] || "",
1045
- onChange: handleInputChange,
1046
- required: true
1047
- }
1048
- )
1049
- ] }, field.name)),
1050
- /* @__PURE__ */ jsx("div", { className: styles$2["form-actions"], children: /* @__PURE__ */ jsx(Button, { type: "submit", variant: "primary", appearance: "filled", size: "xsmall", children: "\uB85C\uADF8\uC778" }) })
1051
- ] }) })
1052
- ] }) });
804
+ );
1053
805
  };
1054
806
 
1055
- const SEARCH_SECTIONS = [
1056
- { value: "all", label: "\uC804\uCCB4" },
1057
- { value: "url", label: "\uC8FC\uC18C" },
1058
- { value: "headers", label: "\uD5E4\uB354" },
1059
- { value: "params", label: "\uD30C\uB77C\uBBF8\uD130" },
1060
- { value: "data", label: "\uC694\uCCAD" },
1061
- { value: "response", label: "\uC751\uB2F5" },
1062
- { value: "error", label: "\uC5D0\uB7EC" }
1063
- ];
1064
- const getLogInfo = (log) => {
1065
- if (log.holdStatus === "held") {
1066
- if ("request" in log) {
1067
- return log.request;
1068
- }
1069
- if ("response" in log) {
1070
- return log.response;
1071
- }
1072
- if ("error" in log) {
1073
- return log.error;
1074
- }
1075
- }
1076
- return log;
1077
- };
1078
- const NetworkLog = ({ onClose }) => {
1079
- const {
1080
- requests,
1081
- responses,
1082
- errors,
1083
- clear,
1084
- isHold,
1085
- toggleHold,
1086
- heldRequests,
1087
- heldResponses,
1088
- heldErrors,
1089
- playAllRequests,
1090
- playAllResponses
1091
- } = useDebugStore();
1092
- const [searchTerm, setSearchTerm] = useState("");
1093
- const [searchSection, setSearchSection] = useState(SEARCH_SECTIONS[0]?.value);
1094
- const allLogs = useMemo(() => {
1095
- const logs = [];
1096
- requests.forEach((req) => logs.push({ ...req, type: "request" }));
1097
- responses.forEach((res) => logs.push({ ...res, type: "response" }));
1098
- errors.forEach((err) => logs.push({ ...err, type: "error" }));
1099
- heldRequests.forEach((req) => logs.push({ ...req, type: "request", holdStatus: "held" }));
1100
- heldResponses.forEach((res) => logs.push({ ...res, type: "response", holdStatus: "held" }));
1101
- heldErrors.forEach((err) => logs.push({ ...err, type: "error", holdStatus: "held" }));
1102
- logs.sort((a, b) => {
1103
- const aInfo = getLogInfo(a);
1104
- const bInfo = getLogInfo(b);
1105
- const aTime = "startTime" in aInfo ? aInfo.startTime : 0;
1106
- const bTime = "startTime" in bInfo ? bInfo.startTime : 0;
1107
- return bTime - aTime;
1108
- });
1109
- return logs;
1110
- }, [requests, responses, errors, heldRequests, heldResponses, heldErrors]);
1111
- const filteredLogs = useMemo(() => {
1112
- if (!searchTerm) {
1113
- return allLogs;
1114
- }
1115
- const lowercasedTerm = searchTerm.toLowerCase();
1116
- return allLogs.filter((log) => {
1117
- const logInfo = getLogInfo(log);
1118
- switch (searchSection) {
1119
- case "url":
1120
- return logInfo.url?.toLowerCase().includes(lowercasedTerm);
1121
- case "headers":
1122
- return "headers" in logInfo && logInfo.headers && JSON.stringify(logInfo.headers)?.toLowerCase().includes(lowercasedTerm);
1123
- case "params":
1124
- return "params" in logInfo && logInfo.params && JSON.stringify(logInfo.params)?.toLowerCase().includes(lowercasedTerm);
1125
- case "data":
1126
- return "data" in logInfo && logInfo.data && log.type === "request" && JSON.stringify(logInfo.data)?.toLowerCase().includes(lowercasedTerm);
1127
- case "response":
1128
- return "data" in logInfo && logInfo.data && log.type === "response" && JSON.stringify(logInfo.data)?.toLowerCase().includes(lowercasedTerm);
1129
- case "error":
1130
- return log.type === "error" && JSON.stringify(logInfo)?.toLowerCase().includes(lowercasedTerm);
1131
- case "all":
1132
- default:
1133
- return JSON.stringify(logInfo).toLowerCase().includes(lowercasedTerm);
1134
- }
1135
- });
1136
- }, [allLogs, searchTerm, searchSection]);
1137
- const renderLogSummary = (log) => {
1138
- const logInfo = getLogInfo(log);
1139
- const prefix = log.holdStatus === "held" ? "[HELD] " : "";
1140
- if (log.type === "request") {
1141
- return `${prefix}[REQ] ${logInfo.method.toUpperCase()} ${logInfo.url}`;
1142
- }
1143
- if (log.type === "response" && "status" in logInfo) {
1144
- return `${prefix}[RES] ${logInfo.method.toUpperCase()} ${logInfo.url} - ${logInfo.status}`;
807
+ const cx$5 = classNames.bind(styles$1);
808
+ const StepIndicator = ({
809
+ items,
810
+ onClickItem,
811
+ currentIndex = 0,
812
+ defaultValue = "",
813
+ dotCount = 3,
814
+ isLoading
815
+ }) => {
816
+ const [steps, setSteps] = React.useState(
817
+ Array.from({ length: 10 }).map(() => ({ label: "-", value: "" }))
818
+ );
819
+ const [current, setCurrent] = React.useState(currentIndex);
820
+ React.useEffect(() => {
821
+ if (items.length > 0) {
822
+ setSteps(items);
823
+ items.map((item, idx) => {
824
+ if (item.value === defaultValue) {
825
+ setCurrent(idx);
826
+ }
827
+ });
1145
828
  }
1146
- if (log.type === "error" && "message" in logInfo) {
1147
- return `${prefix}[ERR] ${logInfo.method.toUpperCase()} ${logInfo.url} - ${logInfo.message}`;
829
+ }, [items, defaultValue]);
830
+ const handleClickStep = (item) => {
831
+ const index = steps.findIndex((step) => step.value === item.value);
832
+ if (index === -1) {
833
+ console.error("error not found index");
834
+ return;
1148
835
  }
1149
- return "Unknown Log";
1150
- };
1151
- const renderLogContent = (log) => {
1152
- const logInfo = getLogInfo(log);
1153
- return /* @__PURE__ */ jsx("pre", { children: JSON.stringify(logInfo, null, 2) });
1154
- };
1155
- return /* @__PURE__ */ jsxs(Modal.Root, { isOpen: true, onClose, modalSize: "full-screen", children: [
1156
- /* @__PURE__ */ jsx(Modal.Overlay, {}),
1157
- /* @__PURE__ */ jsxs(Modal.Content, { children: [
1158
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uB124\uD2B8\uC6CC\uD06C \uB85C\uADF8", showCloseButton: true }),
1159
- /* @__PURE__ */ jsxs(Modal.Body, { children: [
1160
- /* @__PURE__ */ jsxs("div", { className: styles$3["search-container"], children: [
1161
- /* @__PURE__ */ jsx(Select, { value: searchSection, onChange: (value) => setSearchSection(value), size: "xsmall", children: SEARCH_SECTIONS.map((option) => /* @__PURE__ */ jsx(Select.Option, { value: option.value, children: option.label }, option.value)) }),
1162
- /* @__PURE__ */ jsx(
1163
- FormField.TextField,
1164
- {
1165
- placeholder: "\uAC80\uC0C9...",
1166
- value: searchTerm,
1167
- size: "xsmall",
1168
- onChange: (e) => setSearchTerm(e.target.value)
1169
- }
1170
- ),
1171
- /* @__PURE__ */ jsx(Checkbox, { id: "hold-checkbox", checked: isHold, onChange: toggleHold, size: "small", variant: "main", children: "Hold" }),
1172
- /* @__PURE__ */ jsx(Button, { variant: "neutral", appearance: "outline", size: "xsmall", onClick: clear, children: "clear" })
1173
- ] }),
1174
- isHold && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "row" }, children: [
1175
- /* @__PURE__ */ jsx(Button, { size: "xsmall", onClick: () => playAllRequests(), variant: "primary", appearance: "outline", children: "REQ Resolve" }),
1176
- /* @__PURE__ */ jsx(Button, { size: "xsmall", onClick: () => playAllResponses(), variant: "primary", appearance: "outline", children: "RES Resolve" })
1177
- ] }),
1178
- /* @__PURE__ */ jsx("div", { className: styles$3["log-list"], children: filteredLogs.length === 0 ? /* @__PURE__ */ jsx("p", { children: "\uD45C\uC2DC\uD560 \uB85C\uADF8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) : /* @__PURE__ */ jsx(Accordion.Root, { children: filteredLogs.map((log, index) => /* @__PURE__ */ jsxs(Accordion.Item, { children: [
1179
- /* @__PURE__ */ jsx(Accordion.HeaderButton, { children: /* @__PURE__ */ jsx("p", { className: styles$3["log-summary"], children: renderLogSummary(log) }) }),
1180
- /* @__PURE__ */ jsx(Accordion.Content, { variant: "text", children: /* @__PURE__ */ jsx("div", { className: styles$3["log-content"], children: renderLogContent(log) }) })
1181
- ] }, index)) }) })
1182
- ] })
1183
- ] })
1184
- ] });
1185
- };
1186
-
1187
- const PageNavigationPanel = ({ onClose }) => {
1188
- const [url, setUrl] = useState("");
1189
- const handleNavigate = () => {
1190
- if (url) {
1191
- self.location.href = url;
836
+ if (steps[index < 1 ? index : index - 1]?.isCompleted) {
837
+ onClickItem?.(item);
838
+ } else {
839
+ ModalUtils.alert("\uC774\uC804 \uB2E8\uACC4\uB97C \uBAA8\uB450 \uC644\uB8CC\uD574\uC57C \uC120\uD0DD\uD55C \uB2E8\uACC4\uB85C\n\uC774\uB3D9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", "\uC774\uC804 \uB2E8\uACC4\uB97C \uBA3C\uC800 \uC9C4\uD589\uD574\uC8FC\uC138\uC694");
1192
840
  }
1193
841
  };
1194
- return /* @__PURE__ */ jsx(Modal.Root, { isOpen: true, onClose, modalSize: "full-screen", children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1195
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uD398\uC774\uC9C0 \uC774\uB3D9", showCloseButton: true }),
1196
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs("div", { className: styles$2["page-navigation-content"], children: [
842
+ return /* @__PURE__ */ jsxs("div", { className: cx$5("stepper-layout", { loading: isLoading }), children: [
843
+ /* @__PURE__ */ jsx("div", { className: cx$5("stepper"), children: steps.map((item, idx) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
1197
844
  /* @__PURE__ */ jsx(
1198
- FormField.TextField,
845
+ "div",
1199
846
  {
1200
- size: "xsmall",
1201
- type: "text",
1202
- value: url,
1203
- onChange: (e) => setUrl(e.target.value),
1204
- placeholder: "\uC774\uB3D9\uD560 URL\uC744 \uC785\uB825\uD558\uC138\uC694 (\uC608: /main)",
1205
- rootProps: { style: { flex: 1 } }
847
+ className: cx$5(
848
+ "circle",
849
+ { completed: item.isCompleted ?? false },
850
+ { active: defaultValue === item.value || current === idx }
851
+ ),
852
+ onClick: () => handleClickStep?.(item),
853
+ children: item.isCompleted ? /* @__PURE__ */ jsx("span", { className: cx$5("completed-icon") }) : idx + 1
1206
854
  }
1207
855
  ),
1208
- /* @__PURE__ */ jsx(Button, { variant: "primary", appearance: "filled", size: "xsmall", onClick: handleNavigate, children: "\uC774\uB3D9" })
1209
- ] }) })
1210
- ] }) });
856
+ idx < steps.length - 1 && Array.from({ length: dotCount }).map((_, dotIdx) => /* @__PURE__ */ jsx("span", { className: cx$5("dot") }, `dot-${idx}-${dotIdx}`))
857
+ ] }, `num-${idx}`)) }),
858
+ /* @__PURE__ */ jsx("ul", { className: cx$5("step-labels"), children: steps.map((item, idx) => /* @__PURE__ */ jsx(
859
+ "li",
860
+ {
861
+ className: cx$5(
862
+ { completed: steps[idx < 1 ? idx : idx - 1]?.isCompleted ?? false },
863
+ { active: defaultValue === item.value || current === idx }
864
+ ),
865
+ onClick: () => handleClickStep?.(item),
866
+ children: /* @__PURE__ */ jsx("span", { className: "text-ellipsis", children: item.label ?? item.value })
867
+ },
868
+ `label-${idx}`
869
+ )) })
870
+ ] });
1211
871
  };
1212
872
 
1213
- const safeStringify = (obj) => {
1214
- try {
1215
- const replacer = (key, value) => typeof value === "bigint" ? value.toString() : value;
1216
- return JSON.stringify(obj, replacer, 2);
1217
- } catch (e) {
1218
- return "[Unserializable Object]";
873
+ const cx$4 = classNames.bind(styles$2);
874
+ function Attachment({
875
+ photos,
876
+ onAddPhoto,
877
+ onRemovePhoto,
878
+ show,
879
+ type = "multiple",
880
+ buttonText
881
+ }) {
882
+ const handleAddPhoto = () => {
883
+ onAddPhoto();
884
+ };
885
+ const handleRemovePhoto = (id) => {
886
+ onRemovePhoto(id);
887
+ };
888
+ const renderPhotoSingle = () => {
889
+ if (photos.length === 0) {
890
+ return /* @__PURE__ */ jsx("div", { className: cx$4("single-photo-item", "add-photo-item"), children: /* @__PURE__ */ jsxs("button", { className: cx$4("add-photo-button-single"), onClick: handleAddPhoto, children: [
891
+ /* @__PURE__ */ jsx(Icon, { name: "illust/camera" }),
892
+ /* @__PURE__ */ jsx("span", { children: buttonText || "\uC0AC\uC9C4 \uCCA8\uBD80\uD558\uAE30" })
893
+ ] }) });
894
+ }
895
+ return photos.map((photo) => /* @__PURE__ */ jsxs("div", { className: cx$4("single-photo-item"), children: [
896
+ /* @__PURE__ */ jsx("div", { className: cx$4("photo-placeholder"), children: /* @__PURE__ */ jsx("img", { src: photo.src, alt: photo.name, className: cx$4("photo-image") }) }),
897
+ /* @__PURE__ */ jsx("button", { className: cx$4("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
898
+ ] }, photo.id));
899
+ };
900
+ const renderPhotoGrid = () => {
901
+ const maxPhotos = type === "single" ? 1 : 4;
902
+ const gridItems = [];
903
+ if (photos.length < maxPhotos) {
904
+ gridItems.push(
905
+ /* @__PURE__ */ jsx("div", { className: cx$4("photo-item", "add-photo-item"), children: /* @__PURE__ */ jsxs("button", { className: cx$4("add-photo-button"), onClick: handleAddPhoto, children: [
906
+ /* @__PURE__ */ jsx(Icon, { name: "illust/camera" }),
907
+ /* @__PURE__ */ jsx("span", { children: buttonText || "\uCCA8\uBD80\uD558\uAE30" }),
908
+ /* @__PURE__ */ jsxs("span", { className: cx$4("photo-count"), children: [
909
+ "(",
910
+ /* @__PURE__ */ jsx("span", { className: cx$4("photo-count-number"), children: photos.length }),
911
+ "/",
912
+ maxPhotos,
913
+ ")"
914
+ ] })
915
+ ] }) }, "add-photo")
916
+ );
917
+ }
918
+ photos.forEach((photo) => {
919
+ gridItems.push(
920
+ /* @__PURE__ */ jsxs("div", { className: cx$4("photo-item"), children: [
921
+ /* @__PURE__ */ jsx("div", { className: cx$4("photo-placeholder"), children: /* @__PURE__ */ jsx("img", { src: photo.src, alt: photo.name, className: cx$4("photo-image") }) }),
922
+ /* @__PURE__ */ jsx("button", { className: cx$4("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
923
+ ] }, photo.id)
924
+ );
925
+ });
926
+ return gridItems;
927
+ };
928
+ const isVisible = show || !show && photos.length > 0;
929
+ if (!isVisible) {
930
+ return null;
1219
931
  }
1220
- };
1221
- const ResultMessage = ({ log }) => {
1222
- const messageParts = log.message.map((part) => {
1223
- if (typeof part === "object" && part !== null) {
1224
- return safeStringify(part);
932
+ if (type === "single") {
933
+ return /* @__PURE__ */ jsx("div", { className: cx$4("photo-single"), children: renderPhotoSingle() });
934
+ }
935
+ return /* @__PURE__ */ jsx("div", { className: cx$4("photo-grid", { linear: type === "linear" }), children: renderPhotoGrid() });
936
+ }
937
+
938
+ const maxImageSize = 3 * 1024 * 1024;
939
+ function resize(image, options = { ext: "jpeg", filesize: maxImageSize }) {
940
+ return new Promise((resolve, reject) => {
941
+ const canvas = document.createElement("canvas");
942
+ const ctx = canvas.getContext("2d");
943
+ if (!ctx) {
944
+ reject(new Error("Canvas context\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
945
+ return;
1225
946
  }
1226
- return String(part);
1227
- });
1228
- const prefix = log.type === "return" ? "\u21A9 " : "";
1229
- return /* @__PURE__ */ jsxs("pre", { className: `${styles$2["log-message"]} ${styles$2[`log-${log.type}`]}`, children: [
1230
- prefix,
1231
- messageParts.join(" ")
1232
- ] });
1233
- };
1234
- const ScriptExecutorPanel = ({ onClose }) => {
1235
- const [code, setCode] = useState('// \uC5EC\uAE30\uC5D0 \uC2E4\uD589\uD560 \uCF54\uB4DC\uB97C \uC785\uB825\uD558\uC138\uC694\nconsole.log("Hello, World!");');
1236
- const [results, setResults] = useState([]);
1237
- const addResult = (type, ...args) => {
1238
- setResults((prevResults) => [
1239
- ...prevResults,
1240
- {
1241
- id: Date.now() + Math.random(),
1242
- type,
1243
- timestamp: (/* @__PURE__ */ new Date()).toLocaleTimeString(),
1244
- message: args
947
+ const img = new Image();
948
+ img.crossOrigin = "anonymous";
949
+ img.onload = () => {
950
+ let { width, height } = img;
951
+ const { filesize, ext } = options;
952
+ if (filesize) {
953
+ const originalSize = width * height * 4;
954
+ if (originalSize > filesize) {
955
+ const ratio = Math.sqrt(filesize / originalSize);
956
+ width = Math.floor(width * ratio);
957
+ height = Math.floor(height * ratio);
958
+ }
959
+ } else {
960
+ const { width: targetWidth, height: targetHeight } = options;
961
+ if (targetWidth && targetHeight) {
962
+ width = targetWidth;
963
+ height = targetHeight;
964
+ } else if (targetWidth) {
965
+ const ratio = targetWidth / width;
966
+ width = targetWidth;
967
+ height = Math.floor(height * ratio);
968
+ } else if (targetHeight) {
969
+ const ratio = targetHeight / height;
970
+ height = targetHeight;
971
+ width = Math.floor(width * ratio);
972
+ }
1245
973
  }
1246
- ]);
1247
- };
1248
- const handleExecute = () => {
1249
- const originalConsole = { ...console };
1250
- const newConsole = {
1251
- log: (...args) => {
1252
- originalConsole.log(...args);
1253
- addResult("log", ...args);
1254
- },
1255
- warn: (...args) => {
1256
- originalConsole.warn(...args);
1257
- addResult("warn", ...args);
1258
- },
1259
- error: (...args) => {
1260
- originalConsole.error(...args);
1261
- addResult("error", ...args);
974
+ canvas.width = width;
975
+ canvas.height = height;
976
+ ctx.drawImage(img, 0, 0, width, height);
977
+ if (typeof image === "string") {
978
+ const mimeType = ext === "png" ? "image/png" : "image/jpeg";
979
+ const quality = ext === "png" ? 1 : 0.8;
980
+ const base64 = canvas.toDataURL(mimeType, quality);
981
+ resolve(base64);
982
+ } else {
983
+ canvas.toBlob(
984
+ (blob) => {
985
+ if (!blob) {
986
+ reject(new Error("Blob\uC744 \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
987
+ return;
988
+ }
989
+ const mimeType = ext === "png" ? "image/png" : "image/jpeg";
990
+ const fileName = image.name ? `${image.name.replace(/\.[^/.]+$/, "")}.${ext}` : `resized.${ext}`;
991
+ const resizedFile = new File([blob], fileName, { type: mimeType });
992
+ resolve(resizedFile);
993
+ },
994
+ ext === "png" ? "image/png" : "image/jpeg",
995
+ ext === "png" ? 1 : 0.8
996
+ );
1262
997
  }
1263
998
  };
1264
- try {
1265
- Object.assign(console, newConsole);
1266
- const result = new Function(code)();
1267
- if (result !== void 0) {
1268
- addResult("return", result);
999
+ img.onerror = () => {
1000
+ reject(new Error("\uC774\uBBF8\uC9C0\uB97C \uB85C\uB4DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
1001
+ };
1002
+ if (typeof image === "string") {
1003
+ img.src = image;
1004
+ } else {
1005
+ const reader = new FileReader();
1006
+ reader.onload = (e) => {
1007
+ if (e.target?.result) {
1008
+ img.src = e.target.result;
1009
+ } else {
1010
+ reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
1011
+ }
1012
+ };
1013
+ reader.onerror = () => {
1014
+ reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
1015
+ };
1016
+ reader.readAsDataURL(image);
1017
+ }
1018
+ });
1019
+ }
1020
+
1021
+ const genImageId = () => `camera-${Date.now()}-${Math.random()}`;
1022
+ function useCamera({
1023
+ onChange,
1024
+ resize: resizeOption,
1025
+ cameraOnly,
1026
+ onDelete,
1027
+ show,
1028
+ type = "multiple",
1029
+ buttonText
1030
+ } = {}) {
1031
+ const [attachedPhotos, setAttachedPhotos] = useState([]);
1032
+ const findImage = (imageId) => {
1033
+ return attachedPhotos.find((image) => image.id === imageId);
1034
+ };
1035
+ const onClick = () => {
1036
+ const input = document.createElement("input");
1037
+ input.type = "file";
1038
+ input.accept = "image/*";
1039
+ if (cameraOnly) {
1040
+ input.capture = "camera";
1041
+ }
1042
+ input.addEventListener("change", async (event) => {
1043
+ const target = event.target;
1044
+ const { files } = target;
1045
+ if (files && files.length > 0) {
1046
+ const file = files[0];
1047
+ if (file) {
1048
+ const resizedFile = await resize(file, resizeOption);
1049
+ const newPhoto = {
1050
+ id: genImageId(),
1051
+ src: URL.createObjectURL(resizedFile),
1052
+ name: `\uC11C\uB958\uC0AC\uC9C4_${attachedPhotos.length + 1}`
1053
+ };
1054
+ if (type === "single") {
1055
+ setAttachedPhotos([newPhoto]);
1056
+ } else {
1057
+ setAttachedPhotos([...attachedPhotos, newPhoto]);
1058
+ }
1059
+ onChange && onChange(file);
1060
+ }
1269
1061
  }
1270
- } catch (e) {
1271
- addResult("error", e.name, e.message);
1272
- } finally {
1273
- Object.assign(console, originalConsole);
1062
+ document.body.removeChild(input);
1063
+ });
1064
+ input.style.display = "none";
1065
+ document.body.appendChild(input);
1066
+ input.click();
1067
+ };
1068
+ const deleteImage = (imageId) => {
1069
+ const imageIndex = attachedPhotos.findIndex((image) => image.id === imageId);
1070
+ if (imageIndex > -1) {
1071
+ const item = attachedPhotos.splice(imageIndex, 1);
1072
+ item[0] && URL.revokeObjectURL(item[0].src);
1073
+ setAttachedPhotos([...attachedPhotos]);
1074
+ onDelete && onDelete(imageId);
1274
1075
  }
1275
1076
  };
1276
- const handleClear = () => {
1277
- setResults([]);
1077
+ const CameraComponent = () => /* @__PURE__ */ jsx(
1078
+ Attachment,
1079
+ {
1080
+ show: !!show,
1081
+ onAddPhoto: onClick,
1082
+ onRemovePhoto: deleteImage,
1083
+ photos: attachedPhotos,
1084
+ type,
1085
+ buttonText
1086
+ }
1087
+ );
1088
+ useEffect(() => {
1089
+ return () => {
1090
+ attachedPhotos.forEach((image) => {
1091
+ URL.revokeObjectURL(image.src);
1092
+ });
1093
+ };
1094
+ }, []);
1095
+ return {
1096
+ onClick,
1097
+ getImage: findImage,
1098
+ deleteImage,
1099
+ attachedPhotos,
1100
+ Attachment: CameraComponent
1278
1101
  };
1279
- return /* @__PURE__ */ jsx(Modal.Root, { isOpen: true, onClose, modalSize: "full-screen", children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1280
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uC2A4\uD06C\uB9BD\uD2B8 \uC2E4\uD589", showCloseButton: true }),
1281
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx("div", { className: `${styles$2["debug-feature-panel"]} ${styles$2["script-executor-panel"]}`, children: /* @__PURE__ */ jsxs("div", { className: styles$2["script-executor-content"], children: [
1282
- /* @__PURE__ */ jsxs("div", { className: styles$2["script-input-section"], children: [
1283
- /* @__PURE__ */ jsx(
1284
- "textarea",
1285
- {
1286
- className: styles$2["script-textarea"],
1287
- value: code,
1288
- onChange: (e) => setCode(e.target.value),
1289
- spellCheck: "false"
1290
- }
1291
- ),
1292
- /* @__PURE__ */ jsxs("div", { className: styles$2["script-actions"], children: [
1293
- /* @__PURE__ */ jsx(Button, { variant: "neutral", appearance: "outline", size: "xsmall", onClick: handleExecute, children: "\uC2E4\uD589 (\u25B6)" }),
1294
- /* @__PURE__ */ jsx(Button, { variant: "neutral", appearance: "outline", size: "xsmall", onClick: handleClear, children: "\uACB0\uACFC \uC9C0\uC6B0\uAE30" })
1295
- ] })
1296
- ] }),
1297
- /* @__PURE__ */ jsxs("div", { className: styles$2["script-output-section"], children: [
1298
- /* @__PURE__ */ jsx("div", { className: styles$2["panel-header"], children: /* @__PURE__ */ jsx("h3", { children: "\uACB0\uACFC" }) }),
1299
- /* @__PURE__ */ jsx("div", { className: styles$2["log-list-container"], children: results.map((log) => /* @__PURE__ */ jsxs("div", { className: styles$2["log-item"], children: [
1300
- /* @__PURE__ */ jsx("span", { className: styles$2["log-timestamp"], children: log.timestamp }),
1301
- /* @__PURE__ */ jsx(ResultMessage, { log })
1302
- ] }, log.id)) })
1303
- ] })
1304
- ] }) }) })
1305
- ] }) });
1306
- };
1102
+ }
1307
1103
 
1308
- const setCookie = (name, value) => {
1309
- document.cookie = `${name}=${encodeURIComponent(value)};path=/`;
1310
- };
1311
- const removeCookie = (name) => {
1312
- document.cookie = `${name}=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
1104
+ const HISTORY_SIZE = 100;
1105
+ const DEFAULT_DOWNLOAD_PROPS = {
1106
+ fileExtendsion: "png",
1107
+ fileName: "image",
1108
+ transparent: true,
1109
+ backgroundColor: "white",
1110
+ width: 500,
1111
+ height: 500
1313
1112
  };
1314
- const useStorage = (storageType) => {
1315
- const [items, setItems] = useState([]);
1316
- const loadItems = useCallback(() => {
1317
- const newItems = [];
1318
- if (storageType === "localStorage") {
1319
- for (let i = 0; i < localStorage.length; i++) {
1320
- const key = localStorage.key(i);
1321
- if (key) {
1322
- newItems.push({ key, value: localStorage.getItem(key) || "" });
1323
- }
1113
+ function useCanvasPaint(paintProps = {}) {
1114
+ const { pen = { strokeWeight: 5, strokeColor: "black" }, onChange, onStart, onEnd } = paintProps;
1115
+ const [canvasRefState, setCanvasRefState] = useState(null);
1116
+ const contextRef = useRef(null);
1117
+ const [isPainting, setIsPainting] = useState(false);
1118
+ const [history, setHistory] = useState([]);
1119
+ const [historyIndex, setHistoryIndex] = useState(-1);
1120
+ const saveState = useCallback(() => {
1121
+ if (!canvasRefState) {
1122
+ return;
1123
+ }
1124
+ const dataUrl = canvasRefState.toDataURL();
1125
+ const newHistory = history.slice(0, historyIndex + 1);
1126
+ if (newHistory.length >= HISTORY_SIZE) {
1127
+ newHistory.shift();
1128
+ }
1129
+ newHistory.push(dataUrl);
1130
+ setHistory(newHistory);
1131
+ setHistoryIndex(newHistory.length - 1);
1132
+ onChange && onChange();
1133
+ }, [history, historyIndex, onChange, canvasRefState]);
1134
+ const restoreState = useCallback(
1135
+ (index) => {
1136
+ const context = contextRef.current;
1137
+ if (!canvasRefState || !context || !history[index]) {
1138
+ return;
1324
1139
  }
1325
- } else {
1326
- const cookies = document.cookie.split(";");
1327
- cookies.forEach((cookie) => {
1328
- const parts = cookie.split("=");
1329
- const key = parts.shift()?.trim();
1330
- if (key) {
1331
- newItems.push({ key, value: decodeURIComponent(parts.join("=")) });
1332
- }
1333
- });
1140
+ const dataUrl = history[index];
1141
+ const img = new Image();
1142
+ img.onload = () => {
1143
+ context.clearRect(0, 0, canvasRefState.width, canvasRefState.height);
1144
+ context.drawImage(img, 0, 0);
1145
+ };
1146
+ img.src = dataUrl;
1147
+ onChange && onChange();
1148
+ },
1149
+ [history, onChange, canvasRefState]
1150
+ );
1151
+ useEffect(() => {
1152
+ if (!canvasRefState) {
1153
+ return;
1154
+ }
1155
+ const context = canvasRefState.getContext("2d", { willReadFrequently: true });
1156
+ if (!context) {
1157
+ return;
1334
1158
  }
1335
- setItems(newItems);
1336
- }, [storageType]);
1159
+ contextRef.current = context;
1160
+ const initialDataUrl = canvasRefState.toDataURL();
1161
+ setHistory([initialDataUrl]);
1162
+ setHistoryIndex(0);
1163
+ }, [canvasRefState]);
1337
1164
  useEffect(() => {
1338
- loadItems();
1339
- }, [loadItems]);
1340
- const setItem = useCallback(
1341
- (key, value) => {
1342
- if (storageType === "localStorage") {
1343
- localStorage.setItem(key, value);
1165
+ const context = contextRef.current;
1166
+ if (context) {
1167
+ context.lineWidth = pen.strokeWeight;
1168
+ context.strokeStyle = pen.strokeColor;
1169
+ }
1170
+ }, [pen]);
1171
+ const getEventPosition = useCallback(
1172
+ (event) => {
1173
+ if (!canvasRefState) {
1174
+ return null;
1175
+ }
1176
+ const rect = canvasRefState.getBoundingClientRect();
1177
+ const scaleX = canvasRefState.width / rect.width;
1178
+ const scaleY = canvasRefState.height / rect.height;
1179
+ let clientX;
1180
+ let clientY;
1181
+ if (event instanceof MouseEvent) {
1182
+ clientX = event.clientX;
1183
+ clientY = event.clientY;
1184
+ } else if (event instanceof TouchEvent) {
1185
+ const touch = event.touches[0];
1186
+ if (!touch) {
1187
+ return null;
1188
+ }
1189
+ clientX = touch.clientX;
1190
+ clientY = touch.clientY;
1344
1191
  } else {
1345
- setCookie(key, value);
1192
+ return null;
1346
1193
  }
1347
- loadItems();
1194
+ const offsetX = (clientX - rect.left) * scaleX;
1195
+ const offsetY = (clientY - rect.top) * scaleY;
1196
+ return { offsetX, offsetY };
1348
1197
  },
1349
- [storageType, loadItems]
1198
+ [canvasRefState]
1350
1199
  );
1351
- const removeItem = useCallback(
1352
- (key) => {
1353
- if (storageType === "localStorage") {
1354
- localStorage.removeItem(key);
1355
- } else {
1356
- removeCookie(key);
1200
+ const startPainting = useCallback(
1201
+ (event) => {
1202
+ event.preventDefault();
1203
+ const context = contextRef.current;
1204
+ if (!context) {
1205
+ return;
1206
+ }
1207
+ const pos = getEventPosition(event);
1208
+ if (!pos) {
1209
+ return;
1357
1210
  }
1358
- loadItems();
1211
+ onStart && onStart();
1212
+ const { offsetX, offsetY } = pos;
1213
+ context.beginPath();
1214
+ context.moveTo(offsetX, offsetY);
1215
+ setIsPainting(true);
1359
1216
  },
1360
- [storageType, loadItems]
1217
+ [onStart, getEventPosition]
1361
1218
  );
1362
- return { items, setItem, removeItem, loadItems };
1363
- };
1364
-
1365
- const ValueDisplay = ({ value }) => {
1366
- try {
1367
- const parsed = JSON.parse(value);
1368
- if (typeof parsed === "object" && parsed !== null) {
1369
- return /* @__PURE__ */ jsx("pre", { className: styles$2["log-content"], children: JSON.stringify(parsed, null, 2) });
1370
- }
1371
- } catch (e) {
1372
- }
1373
- return /* @__PURE__ */ jsx("div", { className: styles$2["log-content"], children: value });
1374
- };
1375
- const EditableRow = ({ item, onSave, onRemove }) => {
1376
- const [isEditing, setIsEditing] = useState(false);
1377
- const [value, setValue] = useState(item.value);
1378
- const handleSave = () => {
1379
- onSave(item.key, value);
1380
- setIsEditing(false);
1381
- };
1382
- const handleEdit = () => {
1383
- setValue(item.value);
1384
- setIsEditing(true);
1385
- };
1386
- return /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsxs(Accordion.Item, { children: [
1387
- /* @__PURE__ */ jsxs(Accordion.HeaderButton, { children: [
1388
- " ",
1389
- item.key
1390
- ] }),
1391
- /* @__PURE__ */ jsxs(Accordion.Content, { variant: "text", style: { flex: 1, display: "flex", flexDirection: "column" }, children: [
1392
- isEditing ? /* @__PURE__ */ jsx(Button, { variant: "neutral", appearance: "outline", size: "xsmall", onClick: handleSave, children: "Save" }) : /* @__PURE__ */ jsx(Button, { variant: "neutral", appearance: "outline", size: "xsmall", onClick: handleEdit, children: "Edit" }),
1393
- /* @__PURE__ */ jsx(Button, { variant: "neutral", appearance: "outline", size: "xsmall", onClick: () => onRemove(item.key), children: "Remove" }),
1394
- isEditing ? /* @__PURE__ */ jsx("textarea", { value, onChange: (e) => setValue(e.target.value) }) : /* @__PURE__ */ jsx(ValueDisplay, { value: item.value })
1395
- ] })
1396
- ] }) });
1397
- };
1398
- const StoragePanel = ({ onClose, storageType }) => {
1399
- const { items, setItem, removeItem } = useStorage(storageType);
1400
- const [filter, setFilter] = useState("");
1401
- const filteredItems = useMemo(() => {
1402
- if (!filter) {
1403
- return items;
1219
+ const stopPainting = useCallback(() => {
1220
+ const context = contextRef.current;
1221
+ if (!context || !isPainting) {
1222
+ return;
1404
1223
  }
1405
- return items.filter(
1406
- (item) => item.key.toLowerCase().includes(filter.toLowerCase()) || item.value.toLowerCase().includes(filter.toLowerCase())
1407
- );
1408
- }, [items, filter]);
1409
- return /* @__PURE__ */ jsx(Modal.Root, { isOpen: true, onClose, modalSize: "full-screen", children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1410
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: storageType === "localStorage" ? "Local Storage" : "Cookies", showCloseButton: true }),
1411
- /* @__PURE__ */ jsxs(Modal.Body, { children: [
1412
- /* @__PURE__ */ jsx("div", { className: styles$2["panel-toolbar"], children: /* @__PURE__ */ jsx(
1413
- FormField.TextField,
1414
- {
1415
- placeholder: "Search key or value...",
1416
- size: "xsmall",
1417
- value: filter,
1418
- onChange: (e) => setFilter(e.target.value),
1419
- rootProps: { style: { width: "100%" } }
1420
- }
1421
- ) }),
1422
- /* @__PURE__ */ jsx("ul", { children: filteredItems.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(EditableRow, { item, onSave: setItem, onRemove: removeItem }) }, item.key)) })
1423
- ] })
1424
- ] }) });
1425
- };
1426
-
1427
- const loginTypes = [
1428
- {
1429
- id: "fp",
1430
- label: "FP \uB85C\uADF8\uC778",
1431
- fields: [{ name: "employeeId", label: "\uC0AC\uBC88", type: "text", placeholder: "\uC0AC\uBC88\uC744 \uC785\uB825\uD558\uC138\uC694" }]
1432
- },
1433
- {
1434
- id: "customer",
1435
- label: "\uACE0\uAC1D \uB85C\uADF8\uC778",
1436
- fields: [
1437
- { name: "name", label: "\uC774\uB984", type: "text", placeholder: "\uC774\uB984" },
1438
- { name: "phone", label: "\uC804\uD654\uBC88\uD638", type: "tel", placeholder: "\uC804\uD654\uBC88\uD638" },
1439
- { name: "residentNumber", label: "\uC8FC\uBBFC\uBC88\uD638", type: "text", placeholder: "\uC8FC\uBBFC\uBC88\uD638 \uC55E 7\uC790\uB9AC" },
1440
- { name: "userId", label: "\uC544\uC774\uB514", type: "text", placeholder: "\uC544\uC774\uB514" },
1441
- { name: "password", label: "\uBE44\uBC00\uBC88\uD638", type: "password", placeholder: "\uBE44\uBC00\uBC88\uD638" }
1442
- ]
1443
- }
1444
- ];
1445
- const menuItems = [
1446
- {
1447
- id: "network-log",
1448
- label: "\uB124\uD2B8\uC6CC\uD06C \uB85C\uADF8",
1449
- component: NetworkLog,
1450
- display: true
1451
- },
1452
- {
1453
- id: "console-log",
1454
- label: "\uCF58\uC194 \uB85C\uADF8 \uD655\uC778",
1455
- component: ConsoleLogPanel,
1456
- display: true
1457
- },
1458
- {
1459
- id: "local-storage",
1460
- label: "\uB85C\uCEEC \uC2A4\uD1A0\uB9AC\uC9C0 \uAD00\uB9AC",
1461
- // StoragePanel은 재사용 가능한 컴포넌트이므로, props를 통해 어떤 스토리지를 다룰지 지정합니다.
1462
- component: (props) => /* @__PURE__ */ jsx(StoragePanel, { ...props, storageType: "localStorage" }),
1463
- display: true
1464
- },
1465
- {
1466
- id: "cookie-management",
1467
- label: "\uCFE0\uD0A4 \uAD00\uB9AC",
1468
- component: (props) => /* @__PURE__ */ jsx(StoragePanel, { ...props, storageType: "cookie" }),
1469
- display: true
1470
- },
1471
- {
1472
- id: "quick-login",
1473
- label: "\uAC04\uD3B8 \uB85C\uADF8\uC778",
1474
- component: LoginPanel,
1475
- display: true
1476
- // 실제 표시는 DebugTool.tsx에서 onLogin prop 존재 여부에 따라 결정됩니다.
1477
- },
1478
- {
1479
- id: "script-executor",
1480
- label: "\uC2A4\uD06C\uB9BD\uD2B8 \uC2E4\uD589",
1481
- component: ScriptExecutorPanel,
1482
- display: true
1483
- },
1484
- {
1485
- id: "page-navigation",
1486
- label: "\uD398\uC774\uC9C0 \uC774\uB3D9",
1487
- component: PageNavigationPanel,
1488
- display: true
1489
- }
1490
- ];
1491
-
1492
- const useEnvironment = () => {
1493
- const [envInfo, setEnvInfo] = useState({
1494
- env: "prd"
1495
- });
1496
- useEffect(() => {
1497
- const { hostname } = window.location;
1498
- setEnvInfo({ env: getEnvironmentFromHostname(hostname) });
1499
- }, []);
1500
- return envInfo;
1501
- };
1502
-
1503
- const DebugTool = ({ onLogin, envOverride, menuItemsOverride }) => {
1224
+ context.closePath();
1225
+ setIsPainting(false);
1226
+ onEnd && onEnd();
1227
+ saveState();
1228
+ }, [isPainting, onEnd, saveState]);
1229
+ const paint = useCallback(
1230
+ (event) => {
1231
+ event.preventDefault();
1232
+ if (!isPainting || !contextRef.current) {
1233
+ return;
1234
+ }
1235
+ const pos = getEventPosition(event);
1236
+ if (!pos) {
1237
+ return;
1238
+ }
1239
+ const { offsetX, offsetY } = pos;
1240
+ contextRef.current.lineTo(offsetX, offsetY);
1241
+ contextRef.current.stroke();
1242
+ },
1243
+ [isPainting, getEventPosition]
1244
+ );
1504
1245
  useEffect(() => {
1505
- initializeConsoleLogOverride();
1246
+ if (!canvasRefState) {
1247
+ return;
1248
+ }
1249
+ canvasRefState.addEventListener("mousedown", startPainting);
1250
+ canvasRefState.addEventListener("mouseup", stopPainting);
1251
+ canvasRefState.addEventListener("mousemove", paint);
1252
+ canvasRefState.addEventListener("mouseleave", stopPainting);
1253
+ canvasRefState.addEventListener("touchstart", startPainting);
1254
+ canvasRefState.addEventListener("touchend", stopPainting);
1255
+ canvasRefState.addEventListener("touchmove", paint);
1256
+ canvasRefState.addEventListener("touchcancel", stopPainting);
1506
1257
  return () => {
1507
- restoreConsoleLog();
1258
+ canvasRefState.removeEventListener("mousedown", startPainting);
1259
+ canvasRefState.removeEventListener("mouseup", stopPainting);
1260
+ canvasRefState.removeEventListener("mousemove", paint);
1261
+ canvasRefState.removeEventListener("mouseleave", stopPainting);
1262
+ canvasRefState.removeEventListener("touchstart", startPainting);
1263
+ canvasRefState.removeEventListener("touchend", stopPainting);
1264
+ canvasRefState.removeEventListener("touchmove", paint);
1265
+ canvasRefState.removeEventListener("touchcancel", stopPainting);
1508
1266
  };
1509
- }, []);
1510
- const environment = useEnvironment();
1511
- const env = envOverride || environment.env;
1512
- const menuItems$1 = menuItemsOverride || menuItems;
1513
- const [isMenuOpen, setMenuOpen] = useState(false);
1514
- const [activeFeature, setActiveFeature] = useState(null);
1515
- const isVisible = ["local", "dev", "stg"].includes(env);
1516
- const handleMenuClick = (itemComponent) => {
1517
- setActiveFeature(() => itemComponent);
1518
- setMenuOpen(false);
1267
+ }, [startPainting, stopPainting, paint, canvasRefState]);
1268
+ const clear = () => {
1269
+ const context = contextRef.current;
1270
+ if (canvasRefState && context) {
1271
+ context.clearRect(0, 0, canvasRefState.width, canvasRefState.height);
1272
+ const initialDataUrl = canvasRefState.toDataURL();
1273
+ setHistory([initialDataUrl]);
1274
+ setHistoryIndex(0);
1275
+ onChange && onChange();
1276
+ }
1277
+ };
1278
+ const undo = () => {
1279
+ if (historyIndex > 0) {
1280
+ const newIndex = historyIndex - 1;
1281
+ setHistoryIndex(newIndex);
1282
+ restoreState(newIndex);
1283
+ }
1519
1284
  };
1520
- const handleCloseFeature = () => {
1521
- setActiveFeature(null);
1285
+ const redo = () => {
1286
+ if (historyIndex < history.length - 1) {
1287
+ const newIndex = historyIndex + 1;
1288
+ setHistoryIndex(newIndex);
1289
+ restoreState(newIndex);
1290
+ }
1522
1291
  };
1523
- if (!isVisible) {
1524
- return null;
1525
- }
1526
- const toggleMenu = () => {
1527
- setMenuOpen((prev) => !prev);
1528
- if (!isMenuOpen) {
1529
- setActiveFeature(null);
1292
+ const loadImage = (base64String) => {
1293
+ const context = contextRef.current;
1294
+ if (!canvasRefState || !context) {
1295
+ return;
1530
1296
  }
1297
+ const img = new Image();
1298
+ img.onload = () => {
1299
+ context.clearRect(0, 0, canvasRefState.width, canvasRefState.height);
1300
+ context.drawImage(img, 0, 0, canvasRefState.width, canvasRefState.height);
1301
+ saveState();
1302
+ };
1303
+ img.src = base64String;
1531
1304
  };
1532
- const availableMenuItems = menuItems$1.filter(
1533
- (item) => item.display && // config에서 display가 true인 항목만 필터링합니다.
1534
- // 'quick-login' 기능은 onLogin prop이 제공된 경우에만 활성화합니다.
1535
- (item.id !== "quick-login" || item.id === "quick-login" && onLogin)
1536
- );
1537
- if (activeFeature) {
1538
- const FeatureComponent = activeFeature;
1539
- return /* @__PURE__ */ jsx(FeatureComponent, { onClose: handleCloseFeature, onLogin });
1540
- }
1541
- return /* @__PURE__ */ jsxs("div", { className: "debug-tool-container", children: [
1542
- /* @__PURE__ */ jsx(FloatingButton, { onClick: toggleMenu }),
1543
- isMenuOpen && /* @__PURE__ */ jsx(
1544
- MenuPanel,
1545
- {
1546
- menuItems: availableMenuItems,
1547
- onMenuItemClick: handleMenuClick,
1548
- onClose: () => setMenuOpen(false)
1549
- }
1550
- )
1551
- ] });
1552
- };
1553
-
1554
- const highlightOnSearchKeyword = (originalText, targetString) => {
1555
- if (originalText?.includes(targetString)) {
1556
- const replacedText = [];
1557
- const splitText = originalText.split(targetString);
1558
- for (let i = 0; i < splitText.length; i++) {
1559
- replacedText.push(splitText[i]);
1560
- if (i !== splitText.length - 1) {
1561
- replacedText.push(/* @__PURE__ */ jsx("span", { className: "text-primary", children: targetString }));
1562
- }
1305
+ const getBase64String = (imageProps) => {
1306
+ const props = { ...DEFAULT_DOWNLOAD_PROPS, ...imageProps };
1307
+ const { fileExtendsion, transparent, backgroundColor, width, height } = props;
1308
+ const originalCanvas = canvasRefState;
1309
+ if (!originalCanvas) {
1310
+ return;
1563
1311
  }
1564
- return replacedText;
1565
- }
1566
- return originalText;
1567
- };
1568
-
1569
- const cx$7 = classNames.bind(styles$4);
1570
- const { InputBox, Input } = FormCore;
1571
- const AddressSearchInitialText = () => {
1572
- return /* @__PURE__ */ jsxs("div", { children: [
1573
- /* @__PURE__ */ jsx("p", { className: cx$7("guide-title"), children: "\uC774\uB807\uAC8C \uAC80\uC0C9\uD574 \uBCF4\uC138\uC694." }),
1574
- /* @__PURE__ */ jsxs("ul", { className: cx$7("guide"), children: [
1575
- /* @__PURE__ */ jsx("li", { children: "\uB3C4\uB85C\uBA85/\uC9C0\uBA85\uACFC \uAC74\uBB3C\uBC88\uD638\uB97C \uD568\uAED8 \uC785\uB825\uD574\uC8FC\uC138\uC694" }),
1576
- /* @__PURE__ */ jsx("li", { children: "\uC608) 63\uB85C 50, \uC5EC\uC758\uB3C4\uB3D9 60" }),
1577
- /* @__PURE__ */ jsx("li", { children: "\uC9C0\uBA85\uC740 \uB3D9/\uC74D/\uBA74/\uB9AC\uB85C \uC785\uB825\uD574\uC8FC\uC138\uC694" }),
1578
- /* @__PURE__ */ jsx("li", { children: "\uC608) \uC5EC\uC758\uB3C4\uB3D9, \uC5ED\uC0BC\uB3D9" }),
1579
- /* @__PURE__ */ jsx("li", { children: "\uC6B0\uD3B8\uBC88\uD638 \uB2E4\uC12F\uC790\uB9AC\uB97C \uBAA8\uB450 \uC785\uB825\uD574\uC8FC\uC138\uC694" }),
1580
- /* @__PURE__ */ jsx("li", { children: "\uC608) 07345, 06232" })
1581
- ] })
1582
- ] });
1583
- };
1584
- const AddressSearchResult = ({
1585
- addressSearchList,
1586
- onChange,
1587
- searchKeyword,
1588
- selectedAddress
1589
- }) => {
1590
- const [filterList, setFilterList] = useState([]);
1591
- useEffect(() => {
1592
- const filterList2 = addressSearchList.filter(
1593
- (item) => item.address.includes(searchKeyword) || item.oldAddress.includes(searchKeyword)
1594
- ) || [];
1595
- setFilterList(filterList2);
1596
- }, [addressSearchList, searchKeyword]);
1597
- return /* @__PURE__ */ jsxs("div", { children: [
1598
- /* @__PURE__ */ jsxs("p", { className: cx$7("guide-title"), children: [
1599
- "\uCD1D ",
1600
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: filterList.length }),
1601
- "\uAC74\uC758 \uAC80\uC0C9\uACB0\uACFC"
1602
- ] }),
1603
- filterList.length > 0 && /* @__PURE__ */ jsx(
1604
- RadioGroup,
1605
- {
1606
- items: filterList.map((item) => ({
1607
- value: item.address,
1608
- select: item.address === selectedAddress?.address && item.zipCode === selectedAddress?.zipCode,
1609
- label: /* @__PURE__ */ jsxs("div", { className: cx$7("search-result"), children: [
1610
- /* @__PURE__ */ jsxs("div", { className: cx$7("zipcode"), children: [
1611
- " ",
1612
- highlightOnSearchKeyword(item.zipCode, searchKeyword)
1613
- ] }),
1614
- /* @__PURE__ */ jsx("div", { className: cx$7("divider") }),
1615
- /* @__PURE__ */ jsxs("div", { className: cx$7("address-info"), children: [
1616
- /* @__PURE__ */ jsx("span", { className: cx$7("address"), children: highlightOnSearchKeyword(item.address, searchKeyword) }),
1617
- /* @__PURE__ */ jsx("span", { className: cx$7("old-address"), children: highlightOnSearchKeyword(item.oldAddress, searchKeyword) })
1618
- ] })
1619
- ] }),
1620
- id: item.address
1621
- })),
1622
- className: cx$7("radio-group"),
1623
- name: "address-search",
1624
- size: "medium",
1625
- defaultValue: "",
1626
- onChange
1312
+ const tempCanvas = document.createElement("canvas");
1313
+ tempCanvas.width = width;
1314
+ tempCanvas.height = height;
1315
+ const tempCtx = tempCanvas.getContext("2d");
1316
+ if (tempCtx) {
1317
+ if (!transparent) {
1318
+ tempCtx.fillStyle = backgroundColor || "white";
1319
+ tempCtx.fillRect(0, 0, width, height);
1627
1320
  }
1628
- ),
1629
- filterList.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1630
- "`",
1631
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: searchKeyword }),
1632
- "`\uC5D0 \uB300\uD55C \uAC80\uC0C9\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
1633
- ] })
1634
- ] });
1635
- };
1636
- const AddressSearchDetailInput = ({
1637
- selectedAddress,
1638
- onDetailChange,
1639
- step,
1640
- detailAddressInput
1641
- }) => {
1642
- return /* @__PURE__ */ jsxs("div", { children: [
1643
- /* @__PURE__ */ jsxs("div", { children: [
1644
- /* @__PURE__ */ jsxs("div", { children: [
1645
- " ",
1646
- selectedAddress.zipCode
1647
- ] }),
1648
- /* @__PURE__ */ jsxs("div", { children: [
1649
- "|",
1650
- /* @__PURE__ */ jsx("span", { children: `${selectedAddress.address}` })
1651
- ] })
1652
- ] }),
1653
- /* @__PURE__ */ jsxs("div", { children: [
1654
- /* @__PURE__ */ jsx(FormField.Label, { id: "detail", style: { width: "90px" }, children: "\uC0C1\uC138\uC8FC\uC18C" }),
1655
- /* @__PURE__ */ jsx(
1656
- Input,
1657
- {
1658
- placeholder: "\uC0C1\uC138\uC8FC\uC18C \uC785\uB825",
1659
- onChange: onDetailChange,
1660
- size: "large",
1661
- value: detailAddressInput,
1662
- ...step === "detail-input" && { autoFocus: true }
1663
- }
1664
- )
1665
- ] })
1666
- ] });
1667
- };
1668
- function AddressComponent({ isOpen, onClose, setValue }) {
1669
- const {
1670
- onAddressSearchClear,
1671
- addressSearchKeyword,
1672
- addressSearchStep,
1673
- onAddressSearchNext,
1674
- nextButtonDisabled,
1675
- detailAddressInput,
1676
- addressSearchList,
1677
- onSearch,
1678
- onKeyUp,
1679
- onSelectChange,
1680
- setDetail,
1681
- search,
1682
- searchInput,
1683
- selectedAddress
1684
- } = useSearchAddress({
1685
- setValue,
1686
- onClose,
1687
- isOpen
1688
- });
1689
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Modal.Root, { isOpen, onClose, modalSize: "full-screen", children: [
1690
- /* @__PURE__ */ jsx(Modal.Overlay, {}),
1691
- /* @__PURE__ */ jsxs(Modal.Content, { children: [
1692
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uC8FC\uC18C \uAC80\uC0C9", showCloseButton: true }),
1693
- /* @__PURE__ */ jsxs(Modal.Body, { children: [
1694
- /* @__PURE__ */ jsx(
1695
- InputBox,
1696
- {
1697
- clearable: true,
1698
- endElement: /* @__PURE__ */ jsx(Icon, { name: "sub-ui/search", onClick: search }),
1699
- onClear: onAddressSearchClear,
1700
- children: /* @__PURE__ */ jsx(
1701
- Input,
1702
- {
1703
- ...addressSearchStep !== "detail-input" && { autoFocus: true },
1704
- onChange: onSearch,
1705
- onKeyUp,
1706
- value: searchInput,
1707
- placeholder: "\uC9C0\uBC88, \uB3C4\uB85C\uBA85, \uAC74\uBB3C\uBA85, \uC6B0\uD3B8\uBC88\uD638 \uC785\uB825",
1708
- size: "large"
1709
- }
1710
- )
1711
- }
1712
- ),
1713
- addressSearchStep === "initial" && /* @__PURE__ */ jsx(AddressSearchInitialText, {}),
1714
- addressSearchStep === "search-result" && /* @__PURE__ */ jsx(
1715
- AddressSearchResult,
1716
- {
1717
- onChange: onSelectChange,
1718
- addressSearchList: addressSearchList || [],
1719
- searchKeyword: addressSearchKeyword,
1720
- selectedAddress
1721
- }
1722
- ),
1723
- addressSearchStep === "detail-input" && selectedAddress && /* @__PURE__ */ jsx(
1724
- AddressSearchDetailInput,
1725
- {
1726
- selectedAddress,
1727
- onDetailChange: setDetail,
1728
- step: addressSearchStep,
1729
- detailAddressInput
1730
- }
1731
- )
1732
- ] }),
1733
- /* @__PURE__ */ jsx(Modal.Footer, { children: addressSearchStep !== "initial" && /* @__PURE__ */ jsxs(
1734
- Button,
1735
- {
1736
- onClick: onAddressSearchNext,
1737
- variant: "primary",
1738
- size: "medium",
1739
- appearance: "filled",
1740
- width: "full",
1741
- disabled: nextButtonDisabled,
1742
- children: [
1743
- addressSearchStep === "search-result" && "\uB2E4\uC74C(1/2)",
1744
- addressSearchStep === "detail-input" && "\uD655\uC778(2/2)"
1745
- ]
1746
- }
1747
- ) })
1748
- ] })
1749
- ] }) });
1750
- }
1751
-
1752
- function useSearchAddress({ setValue, onClose, isOpen }) {
1753
- const [searchKeyword, setSearchKeyword] = useState("");
1754
- const [step, setStep] = useState("initial");
1755
- const [selectedAddress, setSelectedAddress] = useState(null);
1756
- const [searchInput, setSearchInput] = useState("");
1757
- const [detailAddressInput, setDetailAddressInput] = useState("");
1758
- const { data: addressList } = useSearchModalAddressQuery({ searchKeyword });
1759
- const [nextButtonDisabled, setNextButtonDisabled] = useState(false);
1760
- const onNext = () => {
1761
- if (step === "search-result") {
1762
- setStep("detail-input");
1763
- setNextButtonDisabled(true);
1764
- } else {
1765
- setValue({
1766
- address: selectedAddress?.address || "",
1767
- oldAddress: selectedAddress?.oldAddress || "",
1768
- zipCode: selectedAddress?.zipCode || "",
1769
- detail: detailAddressInput || ""
1770
- });
1771
- onClose();
1321
+ tempCtx.drawImage(originalCanvas, 0, 0, width, height);
1322
+ return tempCanvas.toDataURL(`image/${fileExtendsion}`);
1772
1323
  }
1773
1324
  };
1774
- const onSearch = (e) => {
1775
- const typeStr = e.target.value;
1776
- setSearchInput(typeStr);
1777
- };
1778
- const search = () => {
1779
- if (searchInput === "") {
1780
- onClear();
1325
+ const download = (downloadProps) => {
1326
+ const props = { ...DEFAULT_DOWNLOAD_PROPS, ...downloadProps };
1327
+ const { fileName, fileExtendsion, transparent, backgroundColor, width, height } = props;
1328
+ const originalCanvas = canvasRefState;
1329
+ if (!originalCanvas) {
1781
1330
  return;
1782
1331
  }
1783
- if (searchInput && searchInput.length > 1) {
1784
- setSearchKeyword(searchInput);
1785
- setStep("search-result");
1786
- setSelectedAddress(null);
1787
- setDetailAddressInput("");
1788
- setNextButtonDisabled(true);
1332
+ const tempCanvas = document.createElement("canvas");
1333
+ tempCanvas.width = width;
1334
+ tempCanvas.height = height;
1335
+ const tempCtx = tempCanvas.getContext("2d");
1336
+ if (tempCtx) {
1337
+ if (!transparent) {
1338
+ tempCtx.fillStyle = backgroundColor || "white";
1339
+ tempCtx.fillRect(0, 0, width, height);
1340
+ }
1341
+ tempCtx.drawImage(originalCanvas, 0, 0, width, height);
1342
+ const link = document.createElement("a");
1343
+ link.download = `${fileName}.${fileExtendsion}`;
1344
+ link.href = tempCanvas.toDataURL(`image/${fileExtendsion}`);
1345
+ link.click();
1789
1346
  }
1790
1347
  };
1791
- const onKeyUp = (e) => {
1792
- if (e.key === "Enter") {
1793
- search();
1348
+ const isCanvasBlank = () => {
1349
+ if (!canvasRefState) {
1350
+ return true;
1794
1351
  }
1795
- };
1796
- const onSelectChange = (e) => {
1797
- const selectedAddress2 = e.target.value;
1798
- if (selectedAddress2) {
1799
- const adr = addressList?.find((addr) => {
1800
- return addr.address === selectedAddress2;
1801
- });
1802
- setSelectedAddress(adr || null);
1803
- setNextButtonDisabled(false);
1352
+ const { width, height } = canvasRefState;
1353
+ const ctx = canvasRefState.getContext("2d");
1354
+ if (!ctx) {
1355
+ console.error("2D context not available");
1356
+ return true;
1804
1357
  }
1805
- };
1806
- const onClear = useCallback(() => {
1807
- setSearchKeyword("");
1808
- setSearchInput("");
1809
- setSelectedAddress(null);
1810
- setDetailAddressInput("");
1811
- setStep("initial");
1812
- }, []);
1813
- const setDetail = (e) => {
1814
- const detail = e.target.value;
1815
- setDetailAddressInput(detail);
1816
- if (detail) {
1817
- setNextButtonDisabled(false);
1818
- } else {
1819
- setNextButtonDisabled(true);
1358
+ const imageData = ctx.getImageData(0, 0, width, height);
1359
+ const { data } = imageData;
1360
+ for (let i = 0; i < data.length; i += 4) {
1361
+ if (data[i + 3] !== 0) {
1362
+ return false;
1363
+ }
1820
1364
  }
1365
+ return true;
1821
1366
  };
1822
- useEffect(() => {
1823
- if (isOpen) {
1824
- setSelectedAddress(null);
1825
- setDetailAddressInput("");
1826
- setStep("initial");
1827
- setSearchKeyword("");
1828
- }
1829
- }, [isOpen]);
1830
1367
  return {
1831
- onAddressSearchClear: onClear,
1832
- onAddressSearchNext: onNext,
1833
- addressSearchKeyword: searchKeyword,
1834
- addressSearchList: addressList,
1835
- addressSearchStep: step,
1836
- selectedAddress,
1837
- addressSearchOnValueChange: onSelectChange,
1838
- nextButtonDisabled,
1839
- detailAddressInput,
1840
- onSearch,
1841
- onKeyUp,
1842
- onSelectChange,
1843
- setDetail,
1844
- search,
1845
- searchInput
1368
+ clear,
1369
+ undo,
1370
+ redo,
1371
+ loadImage,
1372
+ download,
1373
+ getBase64String,
1374
+ isCanvasBlank,
1375
+ setCanvasRefState,
1376
+ canvasRefState
1846
1377
  };
1847
1378
  }
1848
- const useAddressComponent = () => {
1849
- const [fullAddress, setFullAddress] = useState(null);
1850
- const { isOpen, closeModal, openModal } = useModalState();
1851
- const AddressSearchComponent = () => /* @__PURE__ */ jsx(AddressComponent, { isOpen, onClose: closeModal, setValue: setFullAddress });
1852
- return {
1853
- fullAddress,
1854
- openModal,
1855
- AddressSearchComponent
1856
- };
1857
- };
1858
1379
 
1859
- const cx$6 = classNames.bind(styles$5);
1860
- const JobVehicleSearchGrade = ({ riskGrade, hospitalizationGrade }) => {
1861
- return /* @__PURE__ */ jsxs("div", { className: cx$6("grade-section"), children: [
1862
- /* @__PURE__ */ jsxs("div", { className: cx$6("icon-title"), children: [
1863
- /* @__PURE__ */ jsx(Icon, { name: "illust/grade" }),
1864
- /* @__PURE__ */ jsx("span", { className: "typo-title5 text-body", children: "\uB4F1\uAE09" })
1865
- ] }),
1866
- /* @__PURE__ */ jsx("p", { className: "typo-body2 text-body_3", children: "\uC9C1\uC885, \uC6B4\uC804 \uC5EC\uBD80 \uC120\uD0DD\uC2DC \uC790\uB3D9\uC73C\uB85C \uC0B0\uC815\uB429\uB2C8\uB2E4." }),
1867
- /* @__PURE__ */ jsxs("div", { className: cx$6("grade-list"), children: [
1868
- /* @__PURE__ */ jsxs("div", { className: cx$6("grade"), children: [
1869
- /* @__PURE__ */ jsx("span", { children: "\uC704\uD5D8\uB4F1\uAE09" }),
1870
- /* @__PURE__ */ jsx("span", { className: "text-primary typo-subtitle3", children: riskGrade || "-" })
1871
- ] }),
1872
- /* @__PURE__ */ jsxs("div", { className: cx$6("grade"), children: [
1873
- /* @__PURE__ */ jsx("span", { children: "\uC785\uC6D0\uB4F1\uAE09" }),
1874
- /* @__PURE__ */ jsx("span", { className: "text-primary typo-subtitle3", children: hospitalizationGrade || "-" })
1875
- ] })
1380
+ const testSignatureBase64Data = "data:image/png;base64,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";
1381
+
1382
+ const cx$3 = classNames.bind(styles$3);
1383
+ const { InputBox, Input } = FormCore;
1384
+ const AddressSearchInitialText = () => {
1385
+ return /* @__PURE__ */ jsxs("div", { children: [
1386
+ /* @__PURE__ */ jsx("p", { className: cx$3("guide-title"), children: "\uC774\uB807\uAC8C \uAC80\uC0C9\uD574 \uBCF4\uC138\uC694." }),
1387
+ /* @__PURE__ */ jsxs("ul", { className: cx$3("guide"), children: [
1388
+ /* @__PURE__ */ jsx("li", { children: "\uB3C4\uB85C\uBA85/\uC9C0\uBA85\uACFC \uAC74\uBB3C\uBC88\uD638\uB97C \uD568\uAED8 \uC785\uB825\uD574\uC8FC\uC138\uC694" }),
1389
+ /* @__PURE__ */ jsx("li", { children: "\uC608) 63\uB85C 50, \uC5EC\uC758\uB3C4\uB3D9 60" }),
1390
+ /* @__PURE__ */ jsx("li", { children: "\uC9C0\uBA85\uC740 \uB3D9/\uC74D/\uBA74/\uB9AC\uB85C \uC785\uB825\uD574\uC8FC\uC138\uC694" }),
1391
+ /* @__PURE__ */ jsx("li", { children: "\uC608) \uC5EC\uC758\uB3C4\uB3D9, \uC5ED\uC0BC\uB3D9" }),
1392
+ /* @__PURE__ */ jsx("li", { children: "\uC6B0\uD3B8\uBC88\uD638 \uB2E4\uC12F\uC790\uB9AC\uB97C \uBAA8\uB450 \uC785\uB825\uD574\uC8FC\uC138\uC694" }),
1393
+ /* @__PURE__ */ jsx("li", { children: "\uC608) 07345, 06232" })
1876
1394
  ] })
1877
1395
  ] });
1878
1396
  };
1879
-
1880
- const JOB_SEARCH_TABS = [
1881
- { value: "jobName", label: "\uC9C1\uC885\uBA85 \uAC80\uC0C9" },
1882
- { value: "jobCode", label: "\uBD84\uB958\uB85C \uAC80\uC0C9" }
1883
- ];
1884
-
1885
- const cx$5 = classNames.bind(styles$6);
1886
- function JobSearchCategory({ filteredJobs, onJobSelect, searchTerm }) {
1887
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: cx$5("category-section"), children: [
1888
- /* @__PURE__ */ jsxs("p", { className: cx$5("result-title"), children: [
1889
- "\uCD1D ",
1890
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: filteredJobs.length }),
1891
- "\uAC74\uC758 \uAC80\uC0C9\uACB0\uACFC"
1892
- ] }),
1893
- /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsx(Radio.Root, { name: "job-selection", size: "small", className: cx$5("job-radio-root"), onToggle: () => {
1894
- }, children: filteredJobs.map((job, index) => /* @__PURE__ */ jsxs(
1895
- Accordion.Item,
1896
- {
1897
- id: `item-${job.occupationIndustryCode}-${index}-accordion`,
1898
- children: [
1899
- /* @__PURE__ */ jsx(Accordion.HeaderDiv, { children: /* @__PURE__ */ jsx("div", { style: { flex: 1 }, children: /* @__PURE__ */ jsxs(Radio.Item, { size: "small", value: job.occupationIndustryCode, onChange: () => onJobSelect(job), children: [
1900
- highlightOnSearchKeyword(job.occupationIndustryName, searchTerm),
1901
- "(",
1902
- job.occupationIndustryCode,
1903
- ")"
1904
- ] }) }) }),
1905
- /* @__PURE__ */ jsx(Accordion.Content, { variant: "text", children: /* @__PURE__ */ jsx(Table, { variant: "horizontal", children: /* @__PURE__ */ jsxs("tbody", { children: [
1906
- /* @__PURE__ */ jsxs("tr", { children: [
1907
- /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1" }),
1908
- /* @__PURE__ */ jsx("td", { className: "px-24", children: "1\uD589 1\uBC88\uC9F8" }),
1909
- /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1-2" }),
1910
- /* @__PURE__ */ jsx("td", { className: "px-24 ", children: "1\uD589 2\uBC88\uC9F8" })
1911
- ] }),
1912
- /* @__PURE__ */ jsxs("tr", { children: [
1913
- /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 2" }),
1914
- /* @__PURE__ */ jsx("td", { className: "pl-24 pr-16", colSpan: 3, children: /* @__PURE__ */ jsxs("p", { className: "d-flex-center-center", children: [
1915
- "2\uD589 1\uBC88\uC9F8 ",
1916
- /* @__PURE__ */ jsx("span", { className: "flex-1 pipe-left", children: "\uC11C\uBE0C\uD14D\uC2A4\uD2B8" }),
1917
- /* @__PURE__ */ jsx(Button, { variant: "neutral", size: "xsmall", appearance: "outline", children: "\uBC84\uD2BC\uBA85" })
1918
- ] }) })
1919
- ] })
1920
- ] }) }) })
1921
- ]
1922
- },
1923
- `item-${job.occupationIndustryCode}-${index}`
1924
- )) }) }),
1925
- filteredJobs.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1926
- "`",
1927
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: searchTerm }),
1928
- "`\uC5D0 \uB300\uD55C \uAC80\uC0C9\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
1929
- ] })
1930
- ] }) });
1931
- }
1932
-
1933
- const cx$4 = classNames.bind(styles$6);
1934
- function JobSearchFavorite({ filteredJobs, onJobSelect }) {
1935
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: cx$4("popular-jobs"), children: [
1936
- /* @__PURE__ */ jsx("p", { children: "\uB9CE\uC774 \uCC3E\uB294 \uC9C1\uC885" }),
1937
- /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsx(Radio.Root, { name: "job-selection", size: "small", className: cx$4("job-radio-root"), children: filteredJobs.map((job, index) => /* @__PURE__ */ jsxs(
1938
- Accordion.Item,
1939
- {
1940
- id: `item-${job.occupationIndustryCode}-${index}`,
1941
- className: cx$4("accordion-item"),
1942
- children: [
1943
- /* @__PURE__ */ jsx(Accordion.HeaderDiv, { className: cx$4("accordion-header-item"), children: /* @__PURE__ */ jsxs(
1944
- Radio.Item,
1945
- {
1946
- size: "small",
1947
- value: job.occupationIndustryCode,
1948
- onChange: () => onJobSelect(job),
1949
- className: cx$4("radio-item"),
1950
- children: [
1951
- job.occupationIndustryName,
1952
- "(",
1953
- job.occupationIndustryCode,
1954
- ")"
1955
- ]
1956
- }
1957
- ) }),
1958
- /* @__PURE__ */ jsx(Accordion.Content, { variant: "text", children: "\uD56D\uBAA9 1 \uB0B4\uC6A9" })
1959
- ]
1960
- },
1961
- `item-${job.occupationIndustryCode}-${index}`
1962
- )) }) })
1963
- ] }) });
1964
- }
1965
-
1966
- const cx$3 = classNames.bind(styles$6);
1967
- function JobSearchResult({ filteredJobs, onJobSelect, searchTerm }) {
1968
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: cx$3("popular-jobs"), children: [
1969
- /* @__PURE__ */ jsxs("p", { className: cx$3("result-title"), children: [
1397
+ const AddressSearchResult = ({
1398
+ addressSearchList,
1399
+ onChange,
1400
+ searchKeyword,
1401
+ selectedAddress
1402
+ }) => {
1403
+ const [filterList, setFilterList] = useState([]);
1404
+ useEffect(() => {
1405
+ const filterList2 = addressSearchList.filter(
1406
+ (item) => item.address.includes(searchKeyword) || item.oldAddress.includes(searchKeyword)
1407
+ ) || [];
1408
+ setFilterList(filterList2);
1409
+ }, [addressSearchList, searchKeyword]);
1410
+ return /* @__PURE__ */ jsxs("div", { children: [
1411
+ /* @__PURE__ */ jsxs("p", { className: cx$3("guide-title"), children: [
1970
1412
  "\uCD1D ",
1971
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: filteredJobs.length }),
1413
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: filterList.length }),
1972
1414
  "\uAC74\uC758 \uAC80\uC0C9\uACB0\uACFC"
1973
1415
  ] }),
1974
- /* @__PURE__ */ jsx(Accordion.Root, { children: /* @__PURE__ */ jsx(Radio.Root, { name: "job-selection", size: "small", className: cx$3("job-radio-root"), children: filteredJobs.map((job) => /* @__PURE__ */ jsxs(
1975
- Accordion.Item,
1416
+ filterList.length > 0 && /* @__PURE__ */ jsx(
1417
+ RadioGroup,
1976
1418
  {
1977
- id: `item-${job.occupationIndustryCode}`,
1978
- children: [
1979
- /* @__PURE__ */ jsx(Accordion.HeaderDiv, { children: /* @__PURE__ */ jsx("div", { style: { flex: 1 }, children: /* @__PURE__ */ jsx(
1980
- Radio.Item,
1981
- {
1982
- id: `item-${job.occupationIndustryCode}`,
1983
- size: "small",
1984
- value: job.occupationIndustryCode,
1985
- onChange: () => {
1986
- onJobSelect(job);
1987
- },
1988
- children: highlightOnSearchKeyword(job.occupationIndustryName, searchTerm)
1989
- }
1990
- ) }) }),
1991
- /* @__PURE__ */ jsx(Accordion.Content, { variant: "text", children: /* @__PURE__ */ jsx(Table, { variant: "horizontal", children: /* @__PURE__ */ jsxs("tbody", { children: [
1992
- /* @__PURE__ */ jsxs("tr", { children: [
1993
- /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1" }),
1994
- /* @__PURE__ */ jsx("td", { className: "px-24", children: "1\uD589 1\uBC88\uC9F8" }),
1995
- /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 1-2" }),
1996
- /* @__PURE__ */ jsx("td", { className: "px-24 ", children: "1\uD589 2\uBC88\uC9F8" })
1419
+ items: filterList.map((item) => ({
1420
+ value: item.address,
1421
+ select: item.address === selectedAddress?.address && item.zipCode === selectedAddress?.zipCode,
1422
+ label: /* @__PURE__ */ jsxs("div", { className: cx$3("search-result"), children: [
1423
+ /* @__PURE__ */ jsxs("div", { className: cx$3("zipcode"), children: [
1424
+ " ",
1425
+ highlightOnSearchKeyword(item.zipCode, searchKeyword)
1997
1426
  ] }),
1998
- /* @__PURE__ */ jsxs("tr", { children: [
1999
- /* @__PURE__ */ jsx("th", { children: "\uD5E4\uB354 2" }),
2000
- /* @__PURE__ */ jsx("td", { className: "pl-24 pr-16", colSpan: 3, children: /* @__PURE__ */ jsxs("p", { className: "d-flex-center-center", children: [
2001
- "2\uD589 1\uBC88\uC9F8 ",
2002
- /* @__PURE__ */ jsx("span", { className: "flex-1 pipe-left", children: "\uC11C\uBE0C\uD14D\uC2A4\uD2B8" }),
2003
- /* @__PURE__ */ jsx(Button, { variant: "neutral", size: "xsmall", appearance: "outline", children: "\uBC84\uD2BC\uBA85" })
2004
- ] }) })
1427
+ /* @__PURE__ */ jsx("div", { className: cx$3("divider") }),
1428
+ /* @__PURE__ */ jsxs("div", { className: cx$3("address-info"), children: [
1429
+ /* @__PURE__ */ jsx("span", { className: cx$3("address"), children: highlightOnSearchKeyword(item.address, searchKeyword) }),
1430
+ /* @__PURE__ */ jsx("span", { className: cx$3("old-address"), children: highlightOnSearchKeyword(item.oldAddress, searchKeyword) })
2005
1431
  ] })
2006
- ] }) }) })
2007
- ]
2008
- },
2009
- job.occupationIndustryCode
2010
- )) }) }),
2011
- filteredJobs.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1432
+ ] }),
1433
+ id: item.address
1434
+ })),
1435
+ className: cx$3("radio-group"),
1436
+ name: "address-search",
1437
+ size: "medium",
1438
+ defaultValue: "",
1439
+ onChange
1440
+ }
1441
+ ),
1442
+ filterList.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2012
1443
  "`",
2013
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: searchTerm }),
1444
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: searchKeyword }),
2014
1445
  "`\uC5D0 \uB300\uD55C \uAC80\uC0C9\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
2015
1446
  ] })
2016
- ] }) });
2017
- }
2018
-
2019
- const { TextField } = FormField;
2020
- const cx$2 = classNames.bind(styles$6);
2021
- const { Option } = Select;
2022
- function JobSearch({
2023
- activeTab,
2024
- onTabChange,
2025
- searchTerm,
2026
- setSearchInput,
2027
- filteredJobs,
2028
- onJobSelect,
2029
- setSearchTerm,
2030
- searchInput,
2031
- firstCategory,
2032
- setFirstCategory,
2033
- secondCategory,
2034
- setSecondCategory,
2035
- firstCategoryList,
2036
- secondCategoryList
2037
- }) {
2038
- const onKeyUp = (e) => {
2039
- if (e.key === "Enter") {
2040
- setSearchTerm(searchInput);
2041
- }
2042
- };
2043
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2044
- /* @__PURE__ */ jsx(
2045
- Tab.Root,
2046
- {
2047
- defaultValue: activeTab,
2048
- onValueChange: onTabChange,
2049
- scroll: "fixed",
2050
- size: "small",
2051
- variant: "sub",
2052
- style: { gap: 0, overflow: "visible" },
2053
- children: JOB_SEARCH_TABS.map((tab) => /* @__PURE__ */ jsx(Tab.Item, { value: tab.value, children: tab.label }, tab.value))
2054
- }
2055
- ),
1447
+ ] });
1448
+ };
1449
+ const AddressSearchDetailInput = ({
1450
+ selectedAddress,
1451
+ onDetailChange,
1452
+ step,
1453
+ detailAddressInput
1454
+ }) => {
1455
+ return /* @__PURE__ */ jsxs("div", { children: [
1456
+ /* @__PURE__ */ jsxs("div", { children: [
1457
+ /* @__PURE__ */ jsxs("div", { children: [
1458
+ " ",
1459
+ selectedAddress.zipCode
1460
+ ] }),
1461
+ /* @__PURE__ */ jsxs("div", { children: [
1462
+ "|",
1463
+ /* @__PURE__ */ jsx("span", { children: `${selectedAddress.address}` })
1464
+ ] })
1465
+ ] }),
2056
1466
  /* @__PURE__ */ jsxs("div", { children: [
2057
- activeTab === "jobName" && /* @__PURE__ */ jsxs("div", { className: cx$2("favorite-jobs-section"), children: [
1467
+ /* @__PURE__ */ jsx(FormField.Label, { id: "detail", style: { width: "90px" }, children: "\uC0C1\uC138\uC8FC\uC18C" }),
1468
+ /* @__PURE__ */ jsx(
1469
+ Input,
1470
+ {
1471
+ placeholder: "\uC0C1\uC138\uC8FC\uC18C \uC785\uB825",
1472
+ onChange: onDetailChange,
1473
+ size: "large",
1474
+ value: detailAddressInput,
1475
+ ...step === "detail-input" && { autoFocus: true }
1476
+ }
1477
+ )
1478
+ ] })
1479
+ ] });
1480
+ };
1481
+ function AddressComponent({ isOpen, onClose, setValue }) {
1482
+ const {
1483
+ onAddressSearchClear,
1484
+ addressSearchKeyword,
1485
+ addressSearchStep,
1486
+ onAddressSearchNext,
1487
+ nextButtonDisabled,
1488
+ detailAddressInput,
1489
+ addressSearchList,
1490
+ onSearch,
1491
+ onKeyUp,
1492
+ onSelectChange,
1493
+ setDetail,
1494
+ search,
1495
+ searchInput,
1496
+ selectedAddress
1497
+ } = useSearchAddress({
1498
+ setValue,
1499
+ onClose,
1500
+ isOpen
1501
+ });
1502
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Modal.Root, { isOpen, onClose, modalSize: "full-screen", children: [
1503
+ /* @__PURE__ */ jsx(Modal.Overlay, {}),
1504
+ /* @__PURE__ */ jsxs(Modal.Content, { children: [
1505
+ /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uC8FC\uC18C \uAC80\uC0C9", showCloseButton: true }),
1506
+ /* @__PURE__ */ jsxs(Modal.Body, { children: [
2058
1507
  /* @__PURE__ */ jsx(
2059
- TextField,
1508
+ InputBox,
2060
1509
  {
2061
- placeholder: "\uC9C1\uC885\uBA85 \uAC80\uC0C9",
2062
- value: searchInput,
2063
- onKeyUp,
2064
- onChange: (e) => setSearchInput(e.target.value),
2065
- className: styles$6.searchInput,
2066
- size: "medium",
2067
- rootProps: {
2068
- endElement: /* @__PURE__ */ jsx(Icon, { name: "sub-ui/search", onClick: () => setSearchTerm(searchInput) }),
2069
- onClear: () => {
2070
- setSearchTerm("");
2071
- setSearchInput("");
1510
+ clearable: true,
1511
+ endElement: /* @__PURE__ */ jsx(Icon, { name: "sub-ui/search", onClick: search }),
1512
+ onClear: onAddressSearchClear,
1513
+ children: /* @__PURE__ */ jsx(
1514
+ Input,
1515
+ {
1516
+ ...addressSearchStep !== "detail-input" && { autoFocus: true },
1517
+ onChange: onSearch,
1518
+ onKeyUp,
1519
+ value: searchInput,
1520
+ placeholder: "\uC9C0\uBC88, \uB3C4\uB85C\uBA85, \uAC74\uBB3C\uBA85, \uC6B0\uD3B8\uBC88\uD638 \uC785\uB825",
1521
+ size: "large"
2072
1522
  }
2073
- }
1523
+ )
2074
1524
  }
2075
1525
  ),
2076
- !searchTerm && /* @__PURE__ */ jsx(JobSearchFavorite, { filteredJobs, onJobSelect }),
2077
- searchTerm && /* @__PURE__ */ jsx(JobSearchResult, { filteredJobs, onJobSelect, searchTerm })
1526
+ addressSearchStep === "initial" && /* @__PURE__ */ jsx(AddressSearchInitialText, {}),
1527
+ addressSearchStep === "search-result" && /* @__PURE__ */ jsx(
1528
+ AddressSearchResult,
1529
+ {
1530
+ onChange: onSelectChange,
1531
+ addressSearchList: addressSearchList || [],
1532
+ searchKeyword: addressSearchKeyword,
1533
+ selectedAddress
1534
+ }
1535
+ ),
1536
+ addressSearchStep === "detail-input" && selectedAddress && /* @__PURE__ */ jsx(
1537
+ AddressSearchDetailInput,
1538
+ {
1539
+ selectedAddress,
1540
+ onDetailChange: setDetail,
1541
+ step: addressSearchStep,
1542
+ detailAddressInput
1543
+ }
1544
+ )
2078
1545
  ] }),
2079
- activeTab === "jobCode" && /* @__PURE__ */ jsxs("div", { className: cx$2("select-jobs-section"), children: [
2080
- /* @__PURE__ */ jsxs("div", { className: cx$2("category-section"), children: [
2081
- /* @__PURE__ */ jsx(
2082
- Select,
2083
- {
2084
- name: "first_category",
2085
- onChange: (value) => {
2086
- setFirstCategory(value);
2087
- setSecondCategory("");
2088
- },
2089
- placeholder: "\uB300\uBD84\uB958 \uC120\uD0DD",
2090
- rootProps: {
2091
- style: {
2092
- // width: '300px'
2093
- }
2094
- },
2095
- size: "large",
2096
- value: firstCategory,
2097
- children: firstCategoryList.map((option, index) => /* @__PURE__ */ jsx(Option, { value: option.occupationIndustryCode, children: option.occupationIndustryName }, `${index}-${option.occupationIndustryCode}`))
2098
- }
2099
- ),
2100
- /* @__PURE__ */ jsx(
2101
- Select,
2102
- {
2103
- name: "second_category",
2104
- onChange: setSecondCategory,
2105
- placeholder: "\uC911\uBD84\uB958 \uC120\uD0DD",
2106
- rootProps: {
2107
- style: {
2108
- // width: '300px'
2109
- }
2110
- },
2111
- size: "large",
2112
- value: secondCategory,
2113
- disabled: !firstCategory,
2114
- children: secondCategoryList.map((option, index) => /* @__PURE__ */ jsx(Option, { value: option.occupationIndustryCode, children: option.occupationIndustryName }, `${index}-${option.occupationIndustryCode}`))
2115
- }
2116
- )
2117
- ] }),
2118
- firstCategory && secondCategory && /* @__PURE__ */ jsx(JobSearchCategory, { filteredJobs, onJobSelect, searchTerm })
2119
- ] })
1546
+ /* @__PURE__ */ jsx(Modal.Footer, { children: addressSearchStep !== "initial" && /* @__PURE__ */ jsxs(
1547
+ Button,
1548
+ {
1549
+ onClick: onAddressSearchNext,
1550
+ variant: "primary",
1551
+ size: "medium",
1552
+ appearance: "filled",
1553
+ width: "full",
1554
+ disabled: nextButtonDisabled,
1555
+ children: [
1556
+ addressSearchStep === "search-result" && "\uB2E4\uC74C(1/2)",
1557
+ addressSearchStep === "detail-input" && "\uD655\uC778(2/2)"
1558
+ ]
1559
+ }
1560
+ ) })
2120
1561
  ] })
2121
- ] });
2122
- }
2123
-
2124
- const initData = [
2125
- {
2126
- occupationIndustryCode: "430101",
2127
- occupationIndustryName: "\uD68C\uC0AC \uC0AC\uBB34\uC9C1 \uC885\uC0AC\uC790",
2128
- occupationTypeCode: null,
2129
- historySequence: 0
2130
- },
2131
- {
2132
- occupationIndustryCode: "400301",
2133
- occupationIndustryName: "\uACBD\uC601\uC9C0\uC6D0 \uC0AC\uBB34\uC9C1 \uAD00\uB9AC\uC790",
2134
- occupationTypeCode: null,
2135
- historySequence: 0
2136
- },
2137
- {
2138
- occupationIndustryCode: "510201",
2139
- occupationIndustryName: "\uC804\uC5C5\uC8FC\uBD80",
2140
- occupationTypeCode: null,
2141
- historySequence: 0
2142
- },
2143
- {
2144
- occupationIndustryCode: "442501",
2145
- occupationIndustryName: "\uC8FC\uBC29\uC7A5 \uBC0F \uC870\uB9AC\uC0AC(\uC120\uBC15 \uC870\uB9AC\uC0AC \uC81C\uC678)",
2146
- occupationTypeCode: null,
2147
- historySequence: 0
2148
- },
2149
- {
2150
- occupationIndustryCode: "450303",
2151
- occupationIndustryName: "\uBCF4\uD5D8\uC124\uACC4\uC0AC(\uB2F9\uC0AC)",
2152
- occupationTypeCode: null,
2153
- historySequence: 0
2154
- }
2155
- ];
2156
- const useJobSearch = () => {
2157
- const [activeTab, setActiveTab] = useState(JOB_SEARCH_TABS[0]?.value ?? "");
2158
- const [selectedJob, setSelectedJob] = useState(null);
2159
- const [searchTerm, setSearchTerm] = useState("");
1562
+ ] }) });
1563
+ }
1564
+
1565
+ function useSearchAddress({ setValue, onClose, isOpen }) {
1566
+ const [searchKeyword, setSearchKeyword] = useState("");
1567
+ const [step, setStep] = useState("initial");
1568
+ const [selectedAddress, setSelectedAddress] = useState(null);
2160
1569
  const [searchInput, setSearchInput] = useState("");
2161
- const handleJobSelect = (job) => {
2162
- setSelectedJob(job);
1570
+ const [detailAddressInput, setDetailAddressInput] = useState("");
1571
+ const { data: addressList } = useSearchModalAddressQuery({ searchKeyword });
1572
+ const [nextButtonDisabled, setNextButtonDisabled] = useState(false);
1573
+ const onNext = () => {
1574
+ if (step === "search-result") {
1575
+ setStep("detail-input");
1576
+ setNextButtonDisabled(true);
1577
+ } else {
1578
+ setValue({
1579
+ address: selectedAddress?.address || "",
1580
+ oldAddress: selectedAddress?.oldAddress || "",
1581
+ zipCode: selectedAddress?.zipCode || "",
1582
+ detail: detailAddressInput || ""
1583
+ });
1584
+ onClose();
1585
+ }
2163
1586
  };
2164
- const [firstCategory, setFirstCategory] = useState("");
2165
- const [secondCategory, setSecondCategory] = useState("");
2166
- const [jobList, setJobList] = useState(initData);
2167
- const [firstCategoryList, setFirstCategoryList] = useState([]);
2168
- const [secondCategoryList, setSecondCategoryList] = useState([]);
2169
- const { data } = useSearchOccupationQuery({
2170
- occupationMajorCategoryCode: firstCategory,
2171
- occupationSearchTypeCode: searchTerm ? "4" : "3",
2172
- occupationSubCategoryCode: secondCategory,
2173
- searchOccupationIndustryName: searchTerm
2174
- });
2175
- const { data: firstCategoryData } = useSearchOccupationQuery({
2176
- occupationMajorCategoryCode: "",
2177
- occupationSearchTypeCode: "1",
2178
- occupationSubCategoryCode: "",
2179
- searchOccupationIndustryName: ""
2180
- });
2181
- const { data: secondCategoryData } = useSearchOccupationQuery({
2182
- occupationMajorCategoryCode: firstCategory,
2183
- occupationSearchTypeCode: "2",
2184
- occupationSubCategoryCode: "",
2185
- searchOccupationIndustryName: ""
2186
- });
2187
- useEffect(() => {
2188
- if (data && searchTerm && activeTab === "jobName") {
2189
- const filteredJobs = data.data.occupationList.filter((job) => job.occupationIndustryName.includes(searchTerm));
2190
- setJobList(filteredJobs);
2191
- } else if (!data && searchTerm && activeTab === "jobName") {
2192
- setJobList([]);
2193
- } else if (!searchTerm && activeTab === "jobName") {
2194
- setJobList(initData);
2195
- } else if (activeTab === "jobCode" && firstCategory && secondCategory) {
2196
- setJobList(data?.data.occupationList || []);
1587
+ const onSearch = (e) => {
1588
+ const typeStr = e.target.value;
1589
+ setSearchInput(typeStr);
1590
+ };
1591
+ const search = () => {
1592
+ if (searchInput === "") {
1593
+ onClear();
1594
+ return;
2197
1595
  }
2198
- }, [searchTerm, data, firstCategory, secondCategory, secondCategoryData, activeTab]);
2199
- useEffect(() => {
2200
- console.log("jobList", jobList);
2201
- }, [jobList]);
2202
- useEffect(() => {
2203
- if (firstCategoryData) {
2204
- setFirstCategoryList(firstCategoryData.data.occupationList);
1596
+ if (searchInput && searchInput.length > 1) {
1597
+ setSearchKeyword(searchInput);
1598
+ setStep("search-result");
1599
+ setSelectedAddress(null);
1600
+ setDetailAddressInput("");
1601
+ setNextButtonDisabled(true);
2205
1602
  }
2206
- }, [firstCategoryData]);
2207
- useEffect(() => {
2208
- if (secondCategoryData) {
2209
- setSecondCategoryList(secondCategoryData.data.occupationList);
1603
+ };
1604
+ const onKeyUp = (e) => {
1605
+ if (e.key === "Enter") {
1606
+ search();
2210
1607
  }
2211
- }, [secondCategoryData]);
2212
- return {
2213
- activeTab,
2214
- setActiveTab,
2215
- selectedJob,
2216
- searchTerm,
2217
- setSearchTerm,
2218
- handleJobSelect,
2219
- filteredJobs: jobList,
2220
- searchInput,
2221
- setSearchInput,
2222
- firstCategory,
2223
- setFirstCategory,
2224
- secondCategory,
2225
- setSecondCategory,
2226
- secondCategoryList,
2227
- firstCategoryList
2228
1608
  };
2229
- };
2230
- function useJobSearchModal() {
2231
- const {
2232
- activeTab,
2233
- setActiveTab,
2234
- searchTerm,
2235
- setSearchTerm,
2236
- filteredJobs,
2237
- handleJobSelect,
2238
- selectedJob,
2239
- searchInput,
2240
- setSearchInput,
2241
- firstCategory,
2242
- setFirstCategory,
2243
- secondCategory,
2244
- setSecondCategory,
2245
- firstCategoryList,
2246
- secondCategoryList
2247
- } = useJobSearch();
2248
- const { isOpen, openModal, closeModal } = useModalState();
2249
- const onTabChange = (value) => {
2250
- setSearchTerm("");
2251
- setFirstCategory("");
2252
- setSecondCategory("");
2253
- setActiveTab(value);
1609
+ const onSelectChange = (e) => {
1610
+ const selectedAddress2 = e.target.value;
1611
+ if (selectedAddress2) {
1612
+ const adr = addressList?.find((addr) => {
1613
+ return addr.address === selectedAddress2;
1614
+ });
1615
+ setSelectedAddress(adr || null);
1616
+ setNextButtonDisabled(false);
1617
+ }
1618
+ };
1619
+ const onClear = useCallback(() => {
1620
+ setSearchKeyword("");
1621
+ setSearchInput("");
1622
+ setSelectedAddress(null);
1623
+ setDetailAddressInput("");
1624
+ setStep("initial");
1625
+ }, []);
1626
+ const setDetail = (e) => {
1627
+ const detail = e.target.value;
1628
+ setDetailAddressInput(detail);
1629
+ if (detail) {
1630
+ setNextButtonDisabled(false);
1631
+ } else {
1632
+ setNextButtonDisabled(true);
1633
+ }
2254
1634
  };
1635
+ useEffect(() => {
1636
+ if (isOpen) {
1637
+ setSelectedAddress(null);
1638
+ setDetailAddressInput("");
1639
+ setStep("initial");
1640
+ setSearchKeyword("");
1641
+ }
1642
+ }, [isOpen]);
2255
1643
  return {
2256
- JobSearchModal: /* @__PURE__ */ jsxs(Modal.Root, { isOpen, onClose: closeModal, modalSize: "xlarge", children: [
2257
- /* @__PURE__ */ jsx(Modal.Overlay, {}),
2258
- /* @__PURE__ */ jsxs(Modal.Content, { style: { height: "697px" }, children: [
2259
- /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uC9C1\uC885 \uAC80\uC0C9", showCloseButton: true }),
2260
- /* @__PURE__ */ jsx(Modal.Body, { raw: true, children: /* @__PURE__ */ jsx(
2261
- JobSearch,
2262
- {
2263
- firstCategory,
2264
- firstCategoryList,
2265
- secondCategoryList,
2266
- setFirstCategory,
2267
- secondCategory,
2268
- activeTab,
2269
- onTabChange,
2270
- searchTerm,
2271
- setSearchInput,
2272
- filteredJobs: filteredJobs || [],
2273
- onJobSelect: handleJobSelect,
2274
- searchInput,
2275
- setSearchTerm,
2276
- setSecondCategory
2277
- }
2278
- ) }),
2279
- /* @__PURE__ */ jsx(Modal.Footer, { children: /* @__PURE__ */ jsx(Button, { variant: "primary", size: "medium", appearance: "filled", width: "full", onClick: closeModal, children: "\uD655\uC778" }) })
2280
- ] })
2281
- ] }),
2282
- JobSearchComponent: /* @__PURE__ */ jsx(
2283
- JobSearch,
2284
- {
2285
- firstCategoryList,
2286
- secondCategoryList,
2287
- firstCategory,
2288
- setFirstCategory,
2289
- secondCategory,
2290
- setSecondCategory,
2291
- activeTab,
2292
- onTabChange,
2293
- searchTerm,
2294
- setSearchInput,
2295
- filteredJobs: filteredJobs || [],
2296
- onJobSelect: handleJobSelect,
2297
- searchInput,
2298
- setSearchTerm
2299
- }
2300
- ),
2301
- isJobSearchOpen: isOpen,
2302
- openJobSearchModal: openModal,
2303
- closeJobSearchModal: closeModal,
2304
- selectedJob
1644
+ onAddressSearchClear: onClear,
1645
+ onAddressSearchNext: onNext,
1646
+ addressSearchKeyword: searchKeyword,
1647
+ addressSearchList: addressList,
1648
+ addressSearchStep: step,
1649
+ selectedAddress,
1650
+ addressSearchOnValueChange: onSelectChange,
1651
+ nextButtonDisabled,
1652
+ detailAddressInput,
1653
+ onSearch,
1654
+ onKeyUp,
1655
+ onSelectChange,
1656
+ setDetail,
1657
+ search,
1658
+ searchInput
2305
1659
  };
2306
1660
  }
1661
+ const useAddressComponent = () => {
1662
+ const [fullAddress, setFullAddress] = useState(null);
1663
+ const { isOpen, closeModal, openModal } = useModalState();
1664
+ const AddressSearchComponent = () => /* @__PURE__ */ jsx(AddressComponent, { isOpen, onClose: closeModal, setValue: setFullAddress });
1665
+ return {
1666
+ fullAddress,
1667
+ openModal,
1668
+ AddressSearchComponent
1669
+ };
1670
+ };
1671
+
1672
+ const cx$2 = classNames.bind(styles$4);
1673
+ const JobVehicleSearchGrade = ({ riskGrade, hospitalizationGrade }) => {
1674
+ return /* @__PURE__ */ jsxs("div", { className: cx$2("grade-section"), children: [
1675
+ /* @__PURE__ */ jsxs("div", { className: cx$2("icon-title"), children: [
1676
+ /* @__PURE__ */ jsx(Icon, { name: "illust/grade" }),
1677
+ /* @__PURE__ */ jsx("span", { className: "typo-title5 text-body", children: "\uB4F1\uAE09" })
1678
+ ] }),
1679
+ /* @__PURE__ */ jsx("p", { className: "typo-body2 text-body_3", children: "\uC9C1\uC885, \uC6B4\uC804 \uC5EC\uBD80 \uC120\uD0DD\uC2DC \uC790\uB3D9\uC73C\uB85C \uC0B0\uC815\uB429\uB2C8\uB2E4." }),
1680
+ /* @__PURE__ */ jsxs("div", { className: cx$2("grade-list"), children: [
1681
+ /* @__PURE__ */ jsxs("div", { className: cx$2("grade"), children: [
1682
+ /* @__PURE__ */ jsx("span", { children: "\uC704\uD5D8\uB4F1\uAE09" }),
1683
+ /* @__PURE__ */ jsx("span", { className: "text-primary typo-subtitle3", children: riskGrade || "-" })
1684
+ ] }),
1685
+ /* @__PURE__ */ jsxs("div", { className: cx$2("grade"), children: [
1686
+ /* @__PURE__ */ jsx("span", { children: "\uC785\uC6D0\uB4F1\uAE09" }),
1687
+ /* @__PURE__ */ jsx("span", { className: "text-primary typo-subtitle3", children: hospitalizationGrade || "-" })
1688
+ ] })
1689
+ ] })
1690
+ ] });
1691
+ };
2307
1692
 
2308
- const cx$1 = classNames.bind(styles$7);
1693
+ const cx$1 = classNames.bind(styles$5);
2309
1694
  function VehicleSearch({ vehicles, onVehicleSelect }) {
2310
1695
  return /* @__PURE__ */ jsxs("div", { className: cx$1("vehicle-search-section"), children: [
2311
1696
  /* @__PURE__ */ jsx("p", { children: "\uC6B4\uC804 \uCC28\uC885" }),
@@ -2371,7 +1756,7 @@ const useJobVehicleSearch = () => {
2371
1756
  };
2372
1757
  };
2373
1758
 
2374
- const cx = classNames.bind(styles$5);
1759
+ const cx = classNames.bind(styles$4);
2375
1760
  function useJobVehicleSearchModal() {
2376
1761
  const {
2377
1762
  selectedVehicle,
@@ -2464,5 +1849,17 @@ function useJobVehicleSearchModal() {
2464
1849
  };
2465
1850
  }
2466
1851
 
2467
- export { Attachment, DebugTool, FormCheckbox, FormCheckboxButton, FormDatePicker, FormDateRangePicker, FormSegmentGroup, FormTextField, StepIndicator, resize, testSignatureBase64Data, useAddressComponent, useCamera, useCanvasPaint, useJobVehicleSearchModal, useSearchAddress };
1852
+ const JobSearchModal = ({ onClose }) => {
1853
+ const { JobSearchComponent } = useJobSearchModal();
1854
+ return /* @__PURE__ */ jsxs(Modal.Root, { isOpen: true, onClose, modalSize: "xlarge", children: [
1855
+ /* @__PURE__ */ jsx(Modal.Overlay, {}),
1856
+ /* @__PURE__ */ jsxs(Modal.Content, { style: { height: "697px" }, children: [
1857
+ /* @__PURE__ */ jsx(Modal.Header, { headerTitle: "\uC9C1\uC885 \uAC80\uC0C9", showCloseButton: true }),
1858
+ /* @__PURE__ */ jsx(Modal.Body, { raw: true, children: JobSearchComponent }),
1859
+ /* @__PURE__ */ jsx(Modal.Footer, { children: /* @__PURE__ */ jsx(Button, { variant: "primary", size: "medium", appearance: "filled", width: "full", onClick: onClose, children: "\uD655\uC778" }) })
1860
+ ] })
1861
+ ] });
1862
+ };
1863
+
1864
+ export { Attachment, FormCheckbox, FormCheckboxButton, FormDatePicker, FormDateRangePicker, FormSearchJobField, FormSegmentGroup, FormSelect, FormTextField, JobSearchModal, StepIndicator, resize, testSignatureBase64Data, useAddressComponent, useCamera, useCanvasPaint, useJobVehicleSearchModal, useSearchAddress };
2468
1865
  //# sourceMappingURL=index.esm.js.map