diff --git a/package.json b/package.json index 5355cae6..260bfe8e 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "prettier": "^3.3.3", "prisma": "^5.18.0", "react-color-palette": "^7.2.2", + "react-dropdown-select": "^4.11.3", "sass": "^1.77.8", "tailwindcss": "^3.4.1" } diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index c73e442f..becf821b 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -75,7 +75,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { const y2 = this.top + this.height * scaleY const dx = x2 - x1 const dy = y2 - y1 - this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10 + this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) }, addLengthText() { @@ -109,7 +109,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { const maxY = this.top + this.length const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI - const text = new fabric.Textbox(this.length.toFixed(0).toString(), { + const text = new fabric.Textbox(Number(this.length.toFixed(1) * 10).toString(), { left: left, top: top, fontSize: this.fontSize, diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index fec9e227..360c9ddc 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -169,8 +169,9 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { attributes: { offset: 0, }, + parent: this, direction: getDirectionByPoint(point, nextPoint), - idx: i, + idx: i + 1, }) line.startPoint = point line.endPoint = nextPoint diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 3abebd85..98f5f36d 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -12,7 +12,7 @@ import { sessionStore } from '@/store/commonAtom' export default function CanvasLayout() { const [objectNo, setObjectNo] = useState('test123240822001') // 이후 삭제 필요 - const [addCanvasPlans, setAddCanvasPlans] = useState([]) + const [plans, setPlans] = useState([]) const [planNum, setPlanNum] = useState(0) const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const [initCanvasPlans, setInitCanvasPlans] = useRecoilState(initCanvasPlansState) @@ -21,25 +21,54 @@ export default function CanvasLayout() { const { getMessage } = useMessage() const { swalFire } = useSwal() - const { getCanvasByObjectNo, delCanvasById } = usePlan() + const { getCanvasByObjectNo, delCanvasById, checkModifiedCanvasPlan, saveCanvas } = usePlan() const handleCurrentPlan = (newCurrentId) => { + // console.log('currentPlan newCurrentId: ', newCurrentId) + if (!currentCanvasPlan?.id || currentCanvasPlan.id !== newCurrentId) { - setInitCanvasPlans((plans) => - plans.map((plan) => { - return { ...plan, isCurrent: plan.id === newCurrentId } - }), - ) - setAddCanvasPlans((plans) => - plans.map((plan) => { - return { ...plan, isCurrent: plan.id === newCurrentId } - }), - ) + if (currentCanvasPlan?.id && checkModifiedCanvasPlan()) { + swalFire({ + html: getMessage('common.message.confirm.save') + `
${currentCanvasPlan.name}`, + type: 'confirm', + confirmFn: async () => { + saveCanvas(sessionState.userId) + /** + * TODO: 신규 canvas plan 저장 시 id, name 등 데이터 동기화 필요 (40~51Line) + */ + initCanvasPlans.map((initPlan) => { + if ('isNew' in initPlan) { + // console.log('================ isNew initPlan: ', initPlan) + setPlans((plans) => + plans.map((plan) => { + initPlan.isNew === plan.id + ? { ...plan, id: initPlan.id, name: initPlan.name, canvasStatus: initPlan.canvasStatus, isCurrent: plan.id === newCurrentId } + : { ...plan, isCurrent: plan.id === newCurrentId } + }), + ) + } + }) + }, + denyFn: () => { + setPlans((plans) => + plans.map((plan) => { + return { ...plan, isCurrent: plan.id === newCurrentId } + }), + ) + }, + }) + } else { + setPlans((plans) => + plans.map((plan) => { + return { ...plan, isCurrent: plan.id === newCurrentId } + }), + ) + } } } useEffect(() => { - setCurrentCanvasPlan([...initCanvasPlans, ...addCanvasPlans].find((plan) => plan.isCurrent) || null) - }, [initCanvasPlans, addCanvasPlans]) + setCurrentCanvasPlan(plans.find((plan) => plan.isCurrent) || null) + }, [plans]) const handleDeletePlan = (e, id) => { e.stopPropagation() // 이벤트 버블링 방지 @@ -48,20 +77,21 @@ export default function CanvasLayout() { delCanvasById(id) .then((res) => { swalFire({ text: getMessage('common.message.delete') }) - console.log('[DELETE] canvas-statuses res :::::::: %o', res) + // console.log('[DELETE] canvas-statuses res :::::::: %o', res) setInitCanvasPlans((initCanvasPlans) => initCanvasPlans.filter((plan) => plan.id !== id)) + setPlans((plans) => plans.filter((plan) => plan.id !== id)) }) .catch((error) => { swalFire({ text: error.message, icon: 'error' }) - console.error('[DELETE] canvas-statuses res error :::::::: %o', error) + // console.error('[DELETE] canvas-statuses res error :::::::: %o', error) }) } else { - setAddCanvasPlans(addCanvasPlans.filter((plan) => plan.id !== id)) + setPlans(plans.filter((plan) => plan.id !== id)) swalFire({ text: getMessage('common.message.delete') }) } // 삭제 후 last 데이터에 포커싱 - const lastPlan = [...initCanvasPlans, ...addCanvasPlans].filter((plan) => plan.id !== id).at(-1) + const lastPlan = plans.filter((plan) => plan.id !== id).at(-1) if (!lastPlan) { setPlanNum(0) setCurrentCanvasPlan(null) @@ -71,7 +101,7 @@ export default function CanvasLayout() { } const addNewPlan = () => { - setAddCanvasPlans([...addCanvasPlans, { id: planNum, name: `Plan ${planNum + 1}`, objectNo: `${objectNo}` }]) + setPlans([...plans, { id: planNum, name: `Plan ${planNum + 1}`, objectNo: `${objectNo}` }]) handleCurrentPlan(planNum) setPlanNum(planNum + 1) } @@ -81,6 +111,7 @@ export default function CanvasLayout() { console.log('canvas 목록 ', res) if (res.length > 0) { setInitCanvasPlans(res) + setPlans(res) handleCurrentPlan(res.at(-1).id) // last 데이터에 포커싱 setPlanNum(res.length) } else { @@ -93,7 +124,7 @@ export default function CanvasLayout() {
- {[...initCanvasPlans, ...addCanvasPlans].map((plan) => ( + {plans.map((plan) => (
- plan.isCurrent === true)} /> + plan.isCurrent === true)} />
) } diff --git a/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx index 17999df2..f906a67e 100644 --- a/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx +++ b/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx @@ -1,25 +1,73 @@ -import { useMessage } from '@/hooks/useMessage' import WithDraggable from '@/components/common/draggable/WithDraggable' import Ridge from '@/components/floor-plan/modal/roofShape/type/Ridge' import Pattern from '@/components/floor-plan/modal/roofShape/type/Pattern' import Side from '@/components/floor-plan/modal/roofShape/type/Side' -import { useState } from 'react' import Image from 'next/image' import Direction from '@/components/floor-plan/modal/roofShape/type/Direction' +import { useRoofShapeSetting } from '@/hooks/roofcover/useRoofShapeSetting' +import { useMessage } from '@/hooks/useMessage' export default function RoofShapeSetting({ setShowRoofShapeSettingModal }) { const { getMessage } = useMessage() - const [shapeNum, setShapeNum] = useState(1) - const shapeMenu = [ - { id: 1, name: getMessage('modal.roof.shape.setting.ridge') }, // 용마루 - { id: 2, name: getMessage('modal.roof.shape.setting.patten.a') }, // 패턴A - { id: 3, name: getMessage('modal.roof.shape.setting.patten.b') }, // 패턴B - { id: 4, name: getMessage('modal.roof.shape.setting.side') }, // 변별로 설정 - { id: 5, name: getMessage('commons.west') }, // 서 - { id: 6, name: getMessage('commons.east') }, // 서 - { id: 7, name: getMessage('commons.south') }, // 서 - { id: 8, name: getMessage('commons.north') }, // 북 - ] + const { + shapeNum, + setShapeNum, + shapeMenu, + handleSave, + pitch, + setPitch, + eavesOffset, + setEavesOffset, + gableOffset, + setGableOffset, + sleeveOffset, + setSleeveOffset, + jerkinHeadWidth, + setJerkinHeadWidth, + jerkinHeadPitch, + setJerkinHeadPitch, + hipAndGableWidth, + setHipAndGableWidth, + shedWidth, + setShedWidth, + hasSleeve, + setHasSleeve, + buttonAct, + setButtonAct, + buttonMenu, + handleConfirm, + handleRollBack, + } = useRoofShapeSetting() + + const ridgeProps = { pitch, setPitch, eavesOffset, setEavesOffset } + const patternProps = { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset } + const sideProps = { + pitch, + setPitch, + eavesOffset, + setEavesOffset, + gableOffset, + setGableOffset, + sleeveOffset, + setSleeveOffset, + jerkinHeadWidth, + setJerkinHeadWidth, + jerkinHeadPitch, + setJerkinHeadPitch, + hipAndGableWidth, + setHipAndGableWidth, + shedWidth, + setShedWidth, + hasSleeve, + setHasSleeve, + buttonAct, + setButtonAct, + buttonMenu, + handleConfirm, + handleRollBack, + } + + const directionProps = { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth } return ( @@ -43,13 +91,15 @@ export default function RoofShapeSetting({ setShowRoofShapeSettingModal }) {
{getMessage('setting')}
- {shapeNum === 1 && } - {(shapeNum === 2 || shapeNum === 3) && } - {shapeNum === 4 && } - {(shapeNum === 5 || shapeNum === 6 || shapeNum === 7 || shapeNum === 8) && } + {shapeNum === 1 && } + {(shapeNum === 2 || shapeNum === 3) && } + {shapeNum === 4 && } + {(shapeNum === 5 || shapeNum === 6 || shapeNum === 7 || shapeNum === 8) && }
- +
diff --git a/src/components/floor-plan/modal/roofShape/type/Direction.jsx b/src/components/floor-plan/modal/roofShape/type/Direction.jsx index a02258f9..51faffcb 100644 --- a/src/components/floor-plan/modal/roofShape/type/Direction.jsx +++ b/src/components/floor-plan/modal/roofShape/type/Direction.jsx @@ -1,6 +1,7 @@ import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' -export default function Direction() { +export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth }) { const { getMessage } = useMessage() return (
@@ -9,7 +10,7 @@ export default function Direction() { {getMessage('slope')}
- + onlyNumberWithDotInputChange(e, setPitch)} />
{getMessage('size')}
@@ -18,7 +19,7 @@ export default function Direction() { {getMessage('eaves.offset')}
- + onlyNumberInputChange(e, setEavesOffset)} />
mm @@ -27,7 +28,7 @@ export default function Direction() { {getMessage('gable.offset')}
- + onlyNumberInputChange(e, setGableOffset)} />
mm @@ -36,7 +37,7 @@ export default function Direction() { {getMessage('windage.width')}
- + onlyNumberInputChange(e, setShedWidth)} />
mm diff --git a/src/components/floor-plan/modal/roofShape/type/Pattern.jsx b/src/components/floor-plan/modal/roofShape/type/Pattern.jsx index 606c154d..0c086fbe 100644 --- a/src/components/floor-plan/modal/roofShape/type/Pattern.jsx +++ b/src/components/floor-plan/modal/roofShape/type/Pattern.jsx @@ -1,7 +1,9 @@ import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' -export default function Pattern() { +export default function Pattern(props) { const { getMessage } = useMessage() + const { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset } = props return (
@@ -9,7 +11,7 @@ export default function Pattern() { {getMessage('slope')}
- + onlyNumberWithDotInputChange(e, setPitch)} />
{getMessage('size')}
@@ -18,7 +20,7 @@ export default function Pattern() { {getMessage('eaves.offset')}
- + onlyNumberInputChange(e, setEavesOffset)} />
mm
@@ -27,7 +29,7 @@ export default function Pattern() { {getMessage('gable.offset')}
- +
mm diff --git a/src/components/floor-plan/modal/roofShape/type/Ridge.jsx b/src/components/floor-plan/modal/roofShape/type/Ridge.jsx index 7897046c..13dab6f3 100644 --- a/src/components/floor-plan/modal/roofShape/type/Ridge.jsx +++ b/src/components/floor-plan/modal/roofShape/type/Ridge.jsx @@ -1,7 +1,11 @@ import { useMessage } from '@/hooks/useMessage' +import { useEffect } from 'react' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' -export default function Ridge() { +export default function Ridge(props) { const { getMessage } = useMessage() + const { pitch, setPitch, eavesOffset, setEavesOffset } = props + return (
@@ -9,7 +13,7 @@ export default function Ridge() { {getMessage('slope')}
- + onlyNumberWithDotInputChange(e, setPitch)} />
{getMessage('size')}
@@ -18,7 +22,7 @@ export default function Ridge() { {getMessage('eaves.offset')}
- + onlyNumberInputChange(e, setEavesOffset)} />
mm
diff --git a/src/components/floor-plan/modal/roofShape/type/Side.jsx b/src/components/floor-plan/modal/roofShape/type/Side.jsx index 3fc1737c..b2f032ba 100644 --- a/src/components/floor-plan/modal/roofShape/type/Side.jsx +++ b/src/components/floor-plan/modal/roofShape/type/Side.jsx @@ -7,39 +7,68 @@ import Wall from '@/components/floor-plan/modal/roofShape/type/option/Wall' import Jerkinhead from '@/components/floor-plan/modal/roofShape/type/option/Jerkinhead' import Shed from '@/components/floor-plan/modal/roofShape/type/option/Shed' -export default function Side() { - const [buttonAct, setButtonAct] = useState(1) +export default function Side(props) { + const { + pitch, + setPitch, + eavesOffset, + setEavesOffset, + gableOffset, + setGableOffset, + sleeveOffset, + setSleeveOffset, + jerkinHeadWidth, + setJerkinHeadWidth, + jerkinHeadPitch, + setJerkinHeadPitch, + hipAndGableWidth, + setHipAndGableWidth, + shedWidth, + setShedWidth, + hasSleeve, + setHasSleeve, + buttonAct, + setButtonAct, + buttonMenu, + handleConfirm, + handleRollBack, + } = props + + const eavesProps = { pitch, setPitch, eavesOffset, setEavesOffset } + const gableProps = { gableOffset, setGableOffset } + const wallProps = { sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve } + const hipAndGableProps = { pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth } + const jerkinheadProps = { gableOffset, setGableOffset, jerkinHeadWidth, setJerkinHeadWidth, jerkinHeadPitch, setJerkinHeadPitch } + const shedProps = { shedWidth, setShedWidth } + const { getMessage } = useMessage() - const buttonMenu = [ - { id: 1, name: getMessage('eaves') }, - { id: 2, name: getMessage('gable') }, - { id: 3, name: getMessage('wall') }, - { id: 4, name: getMessage('hipandgable') }, - { id: 5, name: getMessage('jerkinhead') }, - { id: 6, name: getMessage('shed') }, - ] + return (
- {buttonMenu.map((item) => ( - ))}
- {buttonAct === 1 && } - {buttonAct === 2 && } - {buttonAct === 3 && } - {buttonAct === 4 && } - {buttonAct === 5 && } - {buttonAct === 6 && } + {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } + {buttonAct === 5 && } + {buttonAct === 6 && }
- - + +
) diff --git a/src/components/floor-plan/modal/roofShape/type/option/Eaves.jsx b/src/components/floor-plan/modal/roofShape/type/option/Eaves.jsx index 303dad55..8d061a7b 100644 --- a/src/components/floor-plan/modal/roofShape/type/option/Eaves.jsx +++ b/src/components/floor-plan/modal/roofShape/type/option/Eaves.jsx @@ -1,6 +1,7 @@ import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' -export default function Eaves() { +export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset }) { const { getMessage } = useMessage() return ( <> @@ -9,7 +10,7 @@ export default function Eaves() { {getMessage('slope')}
- + onlyNumberWithDotInputChange(e, setPitch)} />
{getMessage('size')} @@ -18,7 +19,7 @@ export default function Eaves() { {getMessage('eaves.offset')}
- + onlyNumberInputChange(e, setEavesOffset)} />
mm diff --git a/src/components/floor-plan/modal/roofShape/type/option/Gable.jsx b/src/components/floor-plan/modal/roofShape/type/option/Gable.jsx index 63092550..08e503d2 100644 --- a/src/components/floor-plan/modal/roofShape/type/option/Gable.jsx +++ b/src/components/floor-plan/modal/roofShape/type/option/Gable.jsx @@ -1,13 +1,16 @@ import { useMessage } from '@/hooks/useMessage' +import { useEffect } from 'react' +import { onlyNumberInputChange } from '@/util/input-utils' -export default function Gable() { +export default function Gable({ gableOffset, setGableOffset }) { const { getMessage } = useMessage() + return ( <>
{getMessage('gable.offset')}
- + onlyNumberInputChange(e, setGableOffset)} />
mm
diff --git a/src/components/floor-plan/modal/roofShape/type/option/HipAndGable.jsx b/src/components/floor-plan/modal/roofShape/type/option/HipAndGable.jsx index ed2e1b60..ce4a57cc 100644 --- a/src/components/floor-plan/modal/roofShape/type/option/HipAndGable.jsx +++ b/src/components/floor-plan/modal/roofShape/type/option/HipAndGable.jsx @@ -1,6 +1,7 @@ import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' -export default function HipAndGable() { +export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth }) { const { getMessage } = useMessage() return ( <> @@ -9,7 +10,7 @@ export default function HipAndGable() { {getMessage('slope')}
- + onlyNumberWithDotInputChange(e, setPitch)} />
{getMessage('size')} @@ -18,16 +19,21 @@ export default function HipAndGable() { {getMessage('eaves.offset')}
- + onlyNumberInputChange(e, setEavesOffset)} />
mm
- {getMessage('gable.offset')} + {getMessage('hipandgable.width')}
- + onlyNumberInputChange(e, setHipAndGableWidth)} + />
mm
diff --git a/src/components/floor-plan/modal/roofShape/type/option/Jerkinhead.jsx b/src/components/floor-plan/modal/roofShape/type/option/Jerkinhead.jsx index d5737470..be846e94 100644 --- a/src/components/floor-plan/modal/roofShape/type/option/Jerkinhead.jsx +++ b/src/components/floor-plan/modal/roofShape/type/option/Jerkinhead.jsx @@ -1,6 +1,7 @@ import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils' -export default function Jerkinhead() { +export default function Jerkinhead({ gableOffset, setGableOffset, jerkinHeadWidth, setJerkinHeadWidth, jerkinHeadPitch, setJerkinHeadPitch }) { const { getMessage } = useMessage() return ( <> @@ -9,7 +10,7 @@ export default function Jerkinhead() { {getMessage('gable.offset')}
- + onlyNumberInputChange(e, setGableOffset)} />
mm @@ -18,7 +19,7 @@ export default function Jerkinhead() { {getMessage('jerkinhead.width')}
- + onlyNumberInputChange(e, setJerkinHeadWidth)} />
mm @@ -27,7 +28,12 @@ export default function Jerkinhead() { {getMessage('jerkinhead.slope')}
- + onlyNumberWithDotInputChange(e, setJerkinHeadPitch)} + />
{getMessage('size')} diff --git a/src/components/floor-plan/modal/roofShape/type/option/Shed.jsx b/src/components/floor-plan/modal/roofShape/type/option/Shed.jsx index c4fd4333..40ccdbef 100644 --- a/src/components/floor-plan/modal/roofShape/type/option/Shed.jsx +++ b/src/components/floor-plan/modal/roofShape/type/option/Shed.jsx @@ -1,13 +1,14 @@ import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange } from '@/util/input-utils' -export default function Shed() { +export default function Shed({ shedWidth, setShedWidth }) { const { getMessage } = useMessage() return ( <>
{getMessage('shed.width')}
- + onlyNumberInputChange(e, setShedWidth)} />
mm
diff --git a/src/components/floor-plan/modal/roofShape/type/option/Wall.jsx b/src/components/floor-plan/modal/roofShape/type/option/Wall.jsx index 6b716892..c7b04b2d 100644 --- a/src/components/floor-plan/modal/roofShape/type/option/Wall.jsx +++ b/src/components/floor-plan/modal/roofShape/type/option/Wall.jsx @@ -1,8 +1,8 @@ import { useState } from 'react' import { useMessage } from '@/hooks/useMessage' +import { onlyNumberInputChange } from '@/util/input-utils' -export default function Wall() { - const [hasSleeve, setHasSleeve] = useState('0') +export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) { const { getMessage } = useMessage() return ( <> @@ -26,7 +26,13 @@ export default function Wall() {
- + onlyNumberInputChange(e, setSleeveOffset)} + readOnly={hasSleeve === '0'} + />
mm
diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index bfda6d62..f509b3f8 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -12,20 +12,28 @@ import { queryStringFormatter, isEmptyArray } from '@/util/common-utils' import dayjs from 'dayjs' import isLeapYear from 'dayjs/plugin/isLeapYear' // 윤년 판단 플러그인 dayjs.extend(isLeapYear) -import { globalLocaleStore } from '@/store/localeAtom' +import { convertNumberToPriceDecimal } from '@/util/common-utils' +import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' +import KO from '@/locales/ko.json' +import JA from '@/locales/ja.json' +import '@/styles/grid.scss' +import { sessionStore } from '@/store/commonAtom' + export default function Stuff() { + const sessionState = useRecoilValue(sessionStore) + const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore) const stuffSearchParams = useRecoilValue(stuffSearchState) const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) const { getMessage } = useMessage() const [curPage, setCurPage] = useState(1) //현재 페이지 번호 const [defaultSize, setDefaultSize] = useState(100) //페이지 당 게시물 수 + const [gridCount, setGridCount] = useState(0) //총 갯수 const [defaultSortType, setDefaultSortType] = useState('R') const globalLocaleState = useRecoilValue(globalLocaleStore) const { get } = useAxios(globalLocaleState) const gridRef = useRef() - const [gridCount, setGridCount] = useState(0) const [selectedRowData, setSelectedRowData] = useState([]) const [selectedRowDataCount, setSelectedRowDataCount] = useState(0) @@ -45,7 +53,6 @@ export default function Stuff() { //물건번호 복사버튼 옆에 영역 const onDoubleClick = (e) => { let objectNo = e.target.innerText - console.log(objectNo) if (objectNo.substring(0, 1) === 'R') { console.log('진짜') router.push(`${pathname}/detail?objectNo=${objectNo.toString()}`) @@ -70,7 +77,6 @@ export default function Stuff() { headerCheckboxSelectionCurrentPageOnly: true, //페이징시 현재 페이지만 체크되도록 checkboxSelection: true, showDisabledCheckboxes: true, - // headerClass: 'centered', //_test.scss에 추가 테스트 // .centered { // .ag-header-cell-label { // justify-content: center !important; @@ -243,7 +249,6 @@ export default function Stuff() { schAddress: '', schObjectName: '', schSaleStoreName: '', - schSpecDateYn: '', schReceiveUser: '', schDispCompanyName: '', schDateType: 'U', @@ -271,16 +276,15 @@ export default function Stuff() { // let size // let pageCount + // console.log('세션정보::::::::::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}` const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}` - await get({ url: apiUrl, }).then((res) => { if (!isEmptyArray(res)) { - // console.log('화면진입API결과::', res) - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setGridCount(res[0].totCnt) } }) } @@ -293,15 +297,16 @@ export default function Stuff() { stuffSearchParams.startRow = (curPage - 1) * defaultSize + 1 stuffSearchParams.endRow = curPage * defaultSize stuffSearchParams.schSortType = defaultSortType - // console.log('조회 눌럿을때 ::::::::::::::', stuffSearchParams) + console.log('조회누름::::::::', stuffSearchParams) async function fetchData() { + // console.log('세션정보:::::::::::::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` await get({ url: apiUrl }).then((res) => { - console.log('API결과:::::::', res) + // console.log('검색조건 변경 조회 API결과:::::::', res) if (!isEmptyArray(res)) { - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setGridCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) setGridCount(0) @@ -324,15 +329,14 @@ export default function Stuff() { startRow: startRow, endRow: curPage * e.target.value, }) - // console.log('셋팅된 검색조건:::', stuffSearchParams) - //조회API호출 + console.log('페이지 갯수 변경 때 셋팅된 검색조건:::', stuffSearchParams) + // console.log('세션정보:::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` get({ url: apiUrl }).then((res) => { - // console.log('보여줄개수바꿨을때 조회 ::::::::::', res) if (!isEmptyArray(res)) { - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setGridCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) setGridCount(0) @@ -350,20 +354,27 @@ export default function Stuff() { code: 'S', schSortType: e.target.value, }) + // console.log('세션정보::::::::::::', sessionState) // const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}` - // console.log('apiUrl::', apiUrl) get({ url: apiUrl }).then((res) => { - // console.log('정렬바꿨을때 조회 ::::::::::', res) if (!isEmptyArray(res)) { - setGridProps({ ...gridProps, gridData: res, count: res.length }) - setGridCount(res.length) + setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt }) + setGridCount(res[0].totCnt) } else { setGridProps({ ...gridProps, gridData: [], count: 0 }) setGridCount(0) } }) } + + useEffect(() => { + if (globalLocaleState === 'ko') { + setAppMessageState(KO) + } else { + setAppMessageState(JA) + } + }, [globalLocaleState]) return ( <> {/* 퍼블시작 */} @@ -374,11 +385,11 @@ export default function Stuff() {
diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 898b4176..0a743a52 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -2,15 +2,15 @@ import React, { useState, useEffect } from 'react' import { useRouter, useSearchParams } from 'next/navigation' -import { Input, RadioGroup, Radio, Button, Autocomplete, AutocompleteItem, Select, SelectItem, Checkbox, Textarea, button } from '@nextui-org/react' +import { Button } from '@nextui-org/react' +import Select from 'react-dropdown-select' import Link from 'next/link' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { queryStringFormatter, isEmptyArray } from '@/util/common-utils' -import dayjs from 'dayjs' import { useMessage } from '@/hooks/useMessage' import { useForm } from 'react-hook-form' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilValue } from 'recoil' export default function StuffDetail() { const router = useRouter() const searchParams = useSearchParams() @@ -34,14 +34,14 @@ export default function StuffDetail() { prefId: '', //도도부현 prefName: '', address: '', //주소 - powerSimArea: '', //발전량시뮬레이션지역 + areaId: '', //발전량시뮬레이션지역new windSpeed: '', //기준풍속 - snowCover: '', //수직적설량 - coldAreaChk: false, //한랭지대책시행 - surfaceType: 'Ⅲ・Ⅳ', //면조도구분(Ⅲ・Ⅳ / Ⅱ) - saltAreaChk: false, //염해지역용아이템사용 + verticalSnowCover: '', //수직적설량NEW + coldRegionFlg: false, //한랭지대책시행(true : 1 / false : 0) + surfaceType: 'III・IV', //면조도구분(III・IV / Ⅱ) + saltAreaFlg: false, //염해지역용아이템사용 (true : 1 / false : 0) installHeight: '', //설치높이 - powerConTerms: '0', //계약조건(잉여 / 전량) + conType: '0', //계약조건(잉여 / 전량) remarks: '', //메모 tempFlag: 'T', //임시저장(1) 저장(0) } @@ -56,7 +56,7 @@ export default function StuffDetail() { const [saleStoreList, setSaleStoreList] = useState([]) // 판매점 리스트 const [otherSaleStoreList, setOtherSaleStoreList] = useState([]) - const [powerSimAreaList, setPowerSimAreaList] = useState([]) //발전시뮬레이션 리스트 + const [areaIdList, setAreaIdList] = useState([]) //발전시뮬레이션 리스트 NEW const [isFormValid, setIsFormValid] = useState(false) //임시저장, 진짜저장 버튼 컨트롤 const [buttonValid, setButtonValid] = useState(false) //주소검색 활성화 컨트롤 @@ -77,14 +77,13 @@ export default function StuffDetail() { get({ url: `/api/object/${objectNo}/detail` }).then((res) => { // console.log('물건번호로 상세 API 호출') if (res != null) { - // console.log('상세res:::::::', res) setDetailData(res) // 신규 상세 공통APi // 도도부현API get({ url: '/api/object/prefecture/list' }).then((res) => { if (!isEmptyArray(res)) { - //console.log('도도부현API 결과:::', res) + console.log('도도부현API 결과:::', res) setPrefCodeList(res) } }) @@ -106,12 +105,11 @@ export default function StuffDetail() { } }) } else { - console.log('신규화면') // 신규 상세 공통APi // 도도부현API get({ url: '/api/object/prefecture/list' }).then((res) => { if (!isEmptyArray(res)) { - //console.log('도도부현API 결과:::', res) + // console.log('신규화면 도도부현API 결과:::', res) setPrefCodeList(res) } }) @@ -121,11 +119,11 @@ export default function StuffDetail() { //1차점 : X167 get({ url: `/api/object/saleStore/X167/list` }).then((res) => { if (!isEmptyArray(res)) { - console.log('판매점 결과:::::', res) + // console.log('판매점 결과:::::', res) const firstList = res.filter((row) => row.saleStoreLevel === '1') const otherList = res.filter((row) => row.saleStoreLevel !== '1') - console.log('first:::::', firstList) - console.log('otherList:::::', otherList) + // console.log('first:::::', firstList) + // console.log('otherList:::::', otherList) //1차점 셀렉트박스 setSaleStoreList(firstList) //1차 판매점 자동완성 값 셋팅 @@ -135,6 +133,8 @@ export default function StuffDetail() { //1차점 아닌 판매점 셀렉트박스 setOtherSaleStoreList(otherList) + form.setValue('otherSaleStoreId', otherList[0].saleStoreId) + form.setValue('otherSaleStoreName', otherList[0].saleStoreId) } }) } @@ -146,14 +146,17 @@ export default function StuffDetail() { form.setValue('saleStoreId', '') form.setValue('saleStoreName', '') } else { - form.setValue('saleStoreId', key) - form.setValue('saleStoreName', key) + const name = saleStoreList.find((obj) => obj.saleStoreId === key.target.value).saleStoreName + form.setValue('saleStoreId', key.target.value) + form.setValue('saleStoreName', name) } } //2차점 변경 이벤트 const onSelectionChange2 = (key) => { - console.log(key) + const name = otherSaleStoreList.find((obj) => obj.saleStoreId === key.target.value).saleStoreName + form.setValue('otherSaleStoreId', key.target.value) + form.setValue('otherSaleStoreNm', name) } // 우편번호 숫자만 체크 const _zipNo = watch('zipNo') @@ -173,26 +176,28 @@ export default function StuffDetail() { // zipNo: '', //우편번호 // prefId: '', //도도부현 // address: '', //주소 - // powerSimArea: '', //발전량시뮬레이션지역 + // areaId: '', //발전량시뮬레이션지역new // windSpeed: '', //기준풍속 - // snowCover: '', //수직적설량 - // coldAreaChk: false, //한랭지대책시행 + // verticalSnowCover: '', //수직적설량 + // coldRegionFlg: false, //한랭지대책시행 // surfaceType: 'Ⅲ・Ⅳ', //면조도구분(Ⅲ・Ⅳ / Ⅱ) - // saltAreaChk: false, //염해지역용아이템사용 + // saltAreaFlg: false, //염해지역용아이템사용 // installHeight: '', //설치높이 - // powerConTerms: '0', //계약조건(잉여 / 전량) + // conType : '0' //계약조건(잉여 / 전량) // remarks: '', //메모 // tempFlag: 'T', //임시저장(1) 저장(0) const _dispCompanyName = watch('dispCompanyName') const _objectName = watch('objectName') const _objectNameOmit = watch('objectNameOmit') const _saleStoreId = watch('saleStoreId') + const _otherSaleStoreId = watch('otherSaleStoreId') const _prefId = watch('prefId') const _address = watch('address') - const _powerSimArea = watch('powerSimArea') + const _areaId = watch('areaId') //new const _windSpeed = watch('windSpeed') - const _snowCover = watch('snowCover') + const _verticalSnowCover = watch('verticalSnowCover') const _installHeight = watch('installHeight') + useEffect(() => { // console.log('mode:::::', editMode) if (editMode === 'NEW') { @@ -212,6 +217,10 @@ export default function StuffDetail() { errors.saleStoreId = true } + // if (!_otherSaleStoreId) { + // errors.otherSaleStoreId = true + // } + if (!_zipNo || _zipNo.length != 7) { errors.zipCode = true } @@ -224,16 +233,16 @@ export default function StuffDetail() { errors.address = true } - if (!_powerSimArea) { - errors.powerSimArea = true + if (!_areaId) { + errors.areaId = true } if (!_windSpeed) { errors.windSpeed = true } - if (!_snowCover) { - errors.snowCover = true + if (!_verticalSnowCover) { + errors.verticalSnowCover = true } if (!_installHeight) { @@ -245,7 +254,20 @@ export default function StuffDetail() { } else { // console.log('상세일때 폼체크') } - }, [_dispCompanyName, _objectName, _objectNameOmit, _saleStoreId, _zipNo, _prefId, _address, _powerSimArea, _windSpeed, _snowCover, _installHeight]) + }, [ + _dispCompanyName, + _objectName, + _objectNameOmit, + _saleStoreId, + // _otherSaleStoreId, + _zipNo, + _prefId, + _address, + _areaId, + _windSpeed, + _verticalSnowCover, + _installHeight, + ]) // 주소검색 API const onSearchPostNumber = () => { @@ -257,7 +279,7 @@ export default function StuffDetail() { //9302226 if (res.status === 200) { if (res.results != null) { - // console.log('주소검색::', res.results) + console.log('주소검색::', res.results) // console.log('prefcode::', res.results[0].prefcode) // console.log('address::', res.results[0].address2 + res.results[0].address3) setPrefValue(res.results[0].prefcode) @@ -271,8 +293,8 @@ export default function StuffDetail() { form.setValue('address', '') form.setValue('zipNo', '') setPrefValue('') - setPowerSimAreaList([]) - form.setValue('powerSimArea', '') + setAreaIdList([]) + form.setValue('areaId', '') } } else { alert(res.message) @@ -287,8 +309,8 @@ export default function StuffDetail() { // /api/object/prefecture/도도부현코드/list get({ url: `/api/object/prefecture/${prefValue}/list` }).then((res) => { if (!isEmptyArray(res)) { - // console.log('발전시뮬레이션::::::::', res) - setPowerSimAreaList(res) + console.log('발전량 시뮬레이션::::::::', res) + setAreaIdList(res) } }) } @@ -307,7 +329,7 @@ export default function StuffDetail() { // const _zipNo = watch('zipNo') // const _prefId = watch('prefId') // const _address = watch('address') - // const _coldAreaChk = watch('coldAreaChk') + // const _coldRegionFlg = watch('coldRegionFlg') // console.log(_dispCompanyName) // console.log(_objectStatusId) // console.log(_objectNameOmit) @@ -315,7 +337,7 @@ export default function StuffDetail() { // console.log(_prefId) // console.log('prefValue::', prefValue) // console.log(_address) - // console.log('_coldAreaChk::', _coldAreaChk) + // console.log('_coldRegionFlg::', _coldRegionFlg) } //필수값 안넣었을때 임시저장 form required사용시 @@ -328,7 +350,6 @@ export default function StuffDetail() { // 임시저장 const onTempSave = async () => { const formData = form.getValues() - //console.log('임시저장::::::::', formData) const params = { saleStoreId: formData.saleStoreId, @@ -341,15 +362,15 @@ export default function StuffDetail() { prefId: formData.prefId, prefName: formData.prefName, address: formData.address, - powerSimArea: formData.powerSimArea, + areaId: formData.areaId, receiveUser: formData.dispCompanyName, installHeight: formData.installHeight, windSpeed: formData.windSpeed, - snowCover: formData.snowCover, + verticalSnowCover: formData.verticalSnowCover, surfaceType: formData.surfaceType, - powerConTerms: formData.powerConTerms, - saltAreaChk: formData.saltAreaChk, - coldAreaChk: formData.coldAreaChk, + conType: formData.conType, + coldRegionFlg: formData.coldRegionFlg, + saltAreaFlg: formData.saltAreaFlg, tempFlg: '1', workNo: null, workName: null, @@ -362,10 +383,11 @@ export default function StuffDetail() { } // 발전량 시뮬레이션 변경 - const handlePowerSimAreaOnChange = (e) => { + const handleAreaIdOnChange = (e) => { // console.log('가지고있는 도도부현코드:::::::::', prefValue) - // console.log('발전량시뮬레이션변경:::::::::', e.target.value) - //값 set해주고 그거 useEffect로 api호출 + console.log('발전량시뮬레이션변경:::::::::', e.target.value) + form.setValue('areaId', e.target.value) + //값 set해주고 그거 useEffect로 기준풍속, 수직적설량 api호출 } // 물건삭제 @@ -426,7 +448,7 @@ export default function StuffDetail() {
- @@ -457,16 +479,20 @@ export default function StuffDetail() {
- + {saleStoreList?.length > 0 && ( + + )}
- +
@@ -474,20 +500,34 @@ export default function StuffDetail() {
-
- 2차 판매점명 / ID * -
+
2차 판매점명 / ID
- + {otherSaleStoreList?.length > 0 && ( + + )} +
+
+
-
-
-
@@ -522,6 +562,7 @@ export default function StuffDetail() {
+ {/* {prefCodeList?.length > 0 && ( )} */} + {/* {prefCodeList?.length > 0 && ( + + )} */}
@@ -541,7 +587,19 @@ export default function StuffDetail() { 발전량시뮬레이션지역 * -
+
+ {areaIdList?.length > 0 && ( + + )} +
@@ -559,6 +617,7 @@ export default function StuffDetail() {
m/s이하 +
@@ -568,11 +627,17 @@ export default function StuffDetail() {
-
+
+ +
cm
- - + +
@@ -592,8 +657,8 @@ export default function StuffDetail() {
- - + +
@@ -622,12 +687,12 @@ export default function StuffDetail() {
- - + +
- - + +
diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 13f61bb3..0b394af3 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -1,23 +1,26 @@ 'use client' -import React, { useEffect } from 'react' -import { useState } from 'react' -import { Autocomplete, AutocompleteItem } from '@nextui-org/react' +import React, { useEffect, useRef, useState } from 'react' import { useAxios } from '@/hooks/useAxios' import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' -import { globalLocaleStore } from '@/store/localeAtom' - -import RangeDatePicker from '@/components/common/datepicker/RangeDatePicker' +import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' +import Select from 'react-dropdown-select' +import KO from '@/locales/ko.json' +import JA from '@/locales/ja.json' import { stuffSearchState } from '@/store/stuffAtom' import { isEmptyArray } from '@/util/common-utils' import dayjs from 'dayjs' -import isLeapYear from 'dayjs/plugin/isLeapYear' // 윤년 판단 플러그인 -dayjs.extend(isLeapYear) import Link from 'next/link' import SingleDatePicker from '../common/datepicker/SingleDatePicker' +import { sessionStore } from '@/store/commonAtom' +import { useMessage } from '@/hooks/useMessage' export default function StuffSearchCondition() { - const globalLocaleState = useRecoilValue(globalLocaleStore) + const sessionState = useRecoilValue(sessionStore) + const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore) + const globalLocaleState = useRecoilValue(globalLocaleStore) + const { getMessage } = useMessage() + const ref = useRef() const { get } = useAxios(globalLocaleState) //달력 props 관련 날짜 셋팅 @@ -42,7 +45,6 @@ export default function StuffSearchCondition() { const [address, setAddress] = useState('') //물건주소 const [objectName, setobjectName] = useState('') //물건명 const [saleStoreName, setSaleStoreName] = useState('') //판매대리점명 - const [specDateYn, setSpecDateYn] = useState('') //사양 확인('', 'Y', 'N') const [receiveUser, setReceiveUser] = useState('') //담당자 const [dispCompanyName, setDispCompanyName] = useState('') //견적처 const [dateType, setDateType] = useState('U') //갱신일(U)/등록일(R) @@ -53,7 +55,7 @@ export default function StuffSearchCondition() { const onSubmit = () => { let diff = dayjs(endDate).diff(startDate, 'day') if (diff > 366) { - return alert('최대1년 조회 가능합니다.') + return alert(getMessage('stuff.message.periodError')) } setStuffSearch({ @@ -62,7 +64,6 @@ export default function StuffSearchCondition() { schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address, schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName, schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName, - schSpecDateYn: stuffSearch?.schSpecDateYn ? stuffSearch.schSpecDateYn : specDateYn, schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser, schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName, schDateType: stuffSearch?.schDateType ? stuffSearch.schDateType : dateType, @@ -83,17 +84,18 @@ export default function StuffSearchCondition() { setAddress('') setobjectName('') setSaleStoreName('') - setSpecDateYn('') setReceiveUser('') setDispCompanyName('') setDateType('U') setStartDate(dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD')) setEndDate(dayjs(new Date()).format('YYYY-MM-DD')) setSchSelSaleStoreId('') + handleClear() //판매대리점선택 자동완성 클리어 resetStuffRecoil() } useEffect(() => { + // console.log('세션정보::::::::', sessionState) get({ url: `/api/object/saleStore/201TES01/list` }).then((res) => { if (!isEmptyArray(res)) { // console.log('판매점 결과:::::', res) @@ -102,15 +104,23 @@ export default function StuffSearchCondition() { }) }, []) + //초기화 눌렀을 때 자동완성도.. + const handleClear = () => { + // console.log('ref::', ref.current.state.values) + if (ref.current.state.dropDown) { + ref.current.methods.dropDown() + } else { + ref.current.state.values = [] + } + } //판매대리점 자동완성 변경 const onSelectionChange = (key) => { - // console.log('자동완성값변경', key) - if (key == null) { + if (!isEmptyArray(key)) { + setSchSelSaleStoreId(key[0].saleStoreId) + setStuffSearch({ ...stuffSearch, schSelSaleStoreId: key[0].saleStoreId }) + } else { setSchSelSaleStoreId('') setStuffSearch({ ...stuffSearch, schSelSaleStoreId: '' }) - } else { - setSchSelSaleStoreId(key) - setStuffSearch({ ...stuffSearch, schSelSaleStoreId: key }) } } @@ -119,6 +129,14 @@ export default function StuffSearchCondition() { setEndDate(stuffSearch?.schToDt ? stuffSearch.schToDt : dayjs(new Date()).format('YYYY-MM-DD')) }, [stuffSearch]) + useEffect(() => { + if (globalLocaleState === 'ko') { + setAppMessageState(KO) + } else { + setAppMessageState(JA) + } + }, [globalLocaleState]) + return ( <> {/* 퍼블적용시작 */} @@ -130,7 +148,7 @@ export default function StuffSearchCondition() {
*/} {schSelSaleStoreList?.length > 0 && ( - - {(option) => {option.saleStoreName}} - + )} @@ -314,189 +333,6 @@ export default function StuffSearchCondition() { {/* 퍼블적용끝 */} - {/*
- - - - - -
-
- {Array(4) - .fill() - .map((_, i) => { - if (i === 0) { - return ( -
- { - setObjectNo(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schObjectNo: e.target.value }) - }} - /> - { - setSaleStoreId(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schSaleStoreId: e.target.value }) - }} - /> - { - setAddress(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schAddress: e.target.value }) - }} - /> -
- ) - } else if (i === 1) { - return ( -
- { - setobjectName(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schObjectName: e.target.value }) - }} - /> - { - setSaleStoreName(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schSaleStoreName: e.target.value }) - }} - /> -
- { - setSpecDateYn(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schSpecDateYn: e.target.value }) - }} - /> - -
-
- { - setSpecDateYn(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schSpecDateYn: e.target.value }) - }} - /> - -
-
- { - setSpecDateYn(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schSpecDateYn: e.target.value }) - }} - /> - -
-
- ) - } else if (i === 2) { - return ( -
- { - setReceiveUser(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schReceiveUser: e.target.value }) - }} - /> - { - setDispCompanyName(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schDispCompanyName: e.target.value }) - }} - /> - {schSelSaleStoreList?.length > 0 && ( - - {(option) => {option.saleStoreName}} - - )} -
- ) - } else { - return ( -
-
- { - setDateType(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schDateType: e.target.value }) - }} - /> - -
-
- { - setDateType(e.target.value) - setStuffSearch({ ...stuffSearch, code: 'S', schDateType: e.target.value }) - }} - /> - -
- -
- ) - } - })} -
*/} ) } diff --git a/src/hooks/roofcover/useOuterLineWall.js b/src/hooks/roofcover/useOuterLineWall.js index 130593a0..72fdf91f 100644 --- a/src/hooks/roofcover/useOuterLineWall.js +++ b/src/hooks/roofcover/useOuterLineWall.js @@ -6,6 +6,7 @@ import { adsorptionPointModeState, adsorptionRangeState, canvasState, + currentCanvasPlanState, dotLineIntervalSelector, verticalHorizontalModeState, } from '@/store/canvasAtom' @@ -43,7 +44,7 @@ export function useOuterLineWall() { const adsorptionPointMode = useRecoilValue(adsorptionPointModeState) const adsorptionRange = useRecoilValue(adsorptionRangeState) const interval = useRecoilValue(dotLineIntervalSelector) // 가로 세로 간격 - + const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) const length1Ref = useRef(null) const length2Ref = useRef(null) const angle1Ref = useRef(null) @@ -73,14 +74,6 @@ export function useOuterLineWall() { return } - if (points.length === 0) { - // 만약 포인트가 없다면 모든 라인과 텍스트를 삭제 후 outerLines에서 point를 뽑아 points에 넣어준다. - const lengthTxts = canvas?.getObjects().filter((obj) => obj.name === 'lengthTxt') - lengthTxts.forEach((txt) => { - canvas?.remove(txt) - }) - } - addCanvasMouseEventListener('mouse:down', mouseDown) clear() }, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode]) @@ -98,6 +91,18 @@ export function useOuterLineWall() { addDocumentEventListener('keydown', document, keydown[type]) }, [type]) + useEffect(() => { + const outerLinePoints = canvas?.getObjects().filter((obj) => obj.name === 'outerLinePoint') + const newPoints = [] + if (points.length === 0 && outerLinePoints.length > 0) { + outerLinePoints.forEach((point) => { + newPoints.push({ x: point.left, y: point.top }) + }) + + setPoints(newPoints) + } + }, []) + const clear = () => { setLength1(0) setLength2(0) @@ -186,6 +191,21 @@ export function useOuterLineWall() { canvas?.add(point) } else { setOuterLineFix(false) + canvas + .getObjects() + .filter((obj) => obj.name === 'outerLinePoint') + .forEach((obj) => { + canvas.remove(obj) + }) + points.forEach((point, idx) => { + const circle = new fabric.Circle({ + left: point.x, + top: point.y, + visible: false, + name: 'outerLinePoint', + }) + canvas.add(circle) + }) points.forEach((point, idx) => { if (idx === 0) { return @@ -272,6 +292,10 @@ export function useOuterLineWall() { idx: idx, selectable: true, name: 'outerLine', + x1: point1.x, + y1: point1.y, + x2: point2.x, + y2: point2.y, }) } diff --git a/src/hooks/roofcover/usePropertiesSetting.js b/src/hooks/roofcover/usePropertiesSetting.js index d478a1bc..00ad3890 100644 --- a/src/hooks/roofcover/usePropertiesSetting.js +++ b/src/hooks/roofcover/usePropertiesSetting.js @@ -1,10 +1,11 @@ import { useEffect, useRef } from 'react' import { LINE_TYPE } from '@/common/common' -import { useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' import { canvasState, currentObjectState } from '@/store/canvasAtom' import { useMode } from '@/hooks/useMode' import { usePolygon } from '@/hooks/usePolygon' import { useLine } from '@/hooks/useLine' +import { outerLinePointsState } from '@/store/outerLineAtom' export function usePropertiesSetting() { const canvas = useRecoilValue(canvasState) @@ -12,9 +13,10 @@ export function usePropertiesSetting() { const currentObject = useRecoilValue(currentObjectState) const { drawRoofPolygon } = useMode() + const setPoints = useResetRecoilState(outerLinePointsState) const { addPolygonByLines } = usePolygon() - const { removeLine } = useLine() + const { removeLine, hideLine } = useLine() useEffect(() => { if (!currentObject) { @@ -125,7 +127,8 @@ export function usePropertiesSetting() { stroke: '#000000', strokeWidth: 4, }) - removeLine(line) + + hideLine(hideLine) }) const wall = addPolygonByLines(lines, { name: 'WallLine', fill: 'transparent', stroke: 'black' }) @@ -133,7 +136,7 @@ export function usePropertiesSetting() { wall.lines = [...lines] drawRoofPolygon(wall) - + setPoints([]) canvas.renderAll() } @@ -153,6 +156,7 @@ export function usePropertiesSetting() { }) canvas.renderAll() + setPoints([]) fn(false) } diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js new file mode 100644 index 00000000..f14148f8 --- /dev/null +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -0,0 +1,495 @@ +import { useEffect, useRef, useState } from 'react' +import { useMessage } from '@/hooks/useMessage' +import { useRecoilValue } from 'recoil' +import { canvasState, currentObjectState } from '@/store/canvasAtom' +import { LINE_TYPE } from '@/common/common' +import { usePolygon } from '@/hooks/usePolygon' +import { useMode } from '@/hooks/useMode' +import { useLine } from '@/hooks/useLine' + +export function useRoofShapeSetting() { + const [shapeNum, setShapeNum] = useState(1) + const [buttonAct, setButtonAct] = useState(1) + const { getMessage } = useMessage() + const canvas = useRecoilValue(canvasState) + const { addPolygonByLines } = usePolygon() + const [pitch, setPitch] = useState(4) + const [eavesOffset, setEavesOffset] = useState(500) // 처마출폭 + const [gableOffset, setGableOffset] = useState(300) // 케라바출폭 + const [sleeveOffset, setSleeveOffset] = useState(300) // 소매출폭 + const [jerkinHeadWidth, setJerkinHeadWidth] = useState(800) // 반절처 폭 + const [jerkinHeadPitch, setJerkinHeadPitch] = useState(4.5) // 반절처 경사 + const [hipAndGableWidth, setHipAndGableWidth] = useState(800) // 팔작지붕 폭 + const [shedWidth, setShedWidth] = useState(300) // 한쪽흐름 폭 + const [hasSleeve, setHasSleeve] = useState('0') + const currentObject = useRecoilValue(currentObjectState) + const { drawRoofPolygon } = useMode() + const { hideLine, showLine } = useLine() + + const history = useRef([]) + + useEffect(() => { + const wallLine = canvas.getObjects().find((obj) => obj.name === 'wallLine') + canvas?.remove(wallLine) + + const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + outerLines.forEach((line) => { + showLine(line) + }) + canvas?.renderAll() + }, []) + + useEffect(() => { + if (shapeNum !== 4) { + return + } + if (!currentObject) { + return + } + if (currentObject.name !== 'outerLine') { + return + } + + const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + outerLines.forEach((line) => { + line.set({ + stroke: '#000000', + strokeWidth: 4, + }) + }) + + currentObject.set({ + stroke: '#EA10AC', + strokeWidth: 4, + }) + + canvas.renderAll() + }, [currentObject]) + + useEffect(() => { + if (shapeNum === 4) { + canvas?.remove(canvas.getObjects().find((obj) => obj.name === 'wallLine')) + const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + outerLines.forEach((line) => { + showLine(line) + line.bringToFront() + }) + + canvas?.renderAll() + } + setPitch(4) + setEavesOffset(500) + setGableOffset(300) + setSleeveOffset(300) + setJerkinHeadWidth(800) + setJerkinHeadPitch(4.5) + setHipAndGableWidth(800) + setShedWidth(300) + }, [shapeNum]) + + const shapeMenu = [ + { id: 1, name: getMessage('modal.roof.shape.setting.ridge') }, // 용마루 + { id: 2, name: getMessage('modal.roof.shape.setting.patten.a') }, // 패턴A + { id: 3, name: getMessage('modal.roof.shape.setting.patten.b') }, // 패턴B + { id: 4, name: getMessage('modal.roof.shape.setting.side') }, // 변별로 설정 + { id: 5, name: getMessage('commons.west') }, // 서 + { id: 6, name: getMessage('commons.east') }, // 동 + { id: 7, name: getMessage('commons.south') }, // 남 + { id: 8, name: getMessage('commons.north') }, // 북 + ] + + const buttonMenu = [ + { id: 1, name: getMessage('eaves') }, + { id: 2, name: getMessage('gable') }, + { id: 3, name: getMessage('wall') }, + { id: 4, name: getMessage('hipandgable') }, + { id: 5, name: getMessage('jerkinhead') }, + { id: 6, name: getMessage('shed') }, + ] + + //모달 닫기위한 함수 + const handleSave = (fn) => { + //기존 wallLine 삭제 + + let outerLines + canvas?.remove(canvas.getObjects().find((obj) => obj.name === 'wallLine')) + canvas?.remove(canvas.getObjects().find((obj) => obj.name === 'roofBase')) + + switch (shapeNum) { + case 1: { + outerLines = saveRidge() + break + } + case 2: { + outerLines = saveAPattern() + break + } + case 3: { + outerLines = saveBPattern() + break + } + case 4: { + outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + outerLines.forEach((line) => { + hideLine(line) + }) + break + } + + case 5: { + // 서쪽 + initLineSetting() + outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + outerLines.forEach((line) => { + setWestAndEastRoof(line) + if (line.direction === 'bottom') { + line.attributes = { + offset: eavesOffset / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.EAVES, + } + } + + if (line.direction === 'top') { + line.attributes = { + offset: shedWidth / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.SHED, + } + } + + hideLine(line) + }) + break + } + case 6: { + initLineSetting() + outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + outerLines.forEach((line) => { + setWestAndEastRoof(line) + if (line.direction === 'top') { + line.attributes = { + offset: eavesOffset / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.EAVES, + } + } + + if (line.direction === 'bottom') { + line.attributes = { + offset: shedWidth / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.SHED, + } + } + + hideLine(line) + }) + break + } + case 7: { + initLineSetting() + outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + outerLines.forEach((line) => { + setSouthAndNorthRoof(line) + if (line.direction === 'right') { + line.attributes = { + offset: eavesOffset / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.EAVES, + } + } + + if (line.direction === 'left') { + line.attributes = { + offset: shedWidth / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.SHED, + } + } + hideLine(line) + }) + break + } + case 8: { + initLineSetting() + outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + outerLines.forEach((line) => { + setSouthAndNorthRoof(line) + + if (line.direction === 'left') { + line.attributes = { + offset: eavesOffset / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.EAVES, + } + } + + if (line.direction === 'right') { + line.attributes = { + offset: shedWidth / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.SHED, + } + } + + hideLine(line) + }) + break + } + } + + const polygon = addPolygonByLines(outerLines, { name: 'wallLine' }) + polygon.lines = [...outerLines] + + const roof = drawRoofPolygon(polygon) + + canvas?.renderAll() + roof.drawHelpLine() + fn && fn(false) + } + + const initLineSetting = () => { + const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + const tempPolygon = addPolygonByLines(outerLines) + tempPolygon.lines.forEach((line) => { + outerLines.forEach((outerLine) => { + if ( + (line.startPoint === outerLine.startPoint && line.endPoint === outerLine.endPoint) || + (line.startPoint === outerLine.endPoint && line.endPoint === outerLine.startPoint) + ) { + outerLine.direction = line.direction + outerLine.idx = line.idx + } + }) + }) + + // 첫번째 line의 방향이 right일 경우 + if (outerLines[0].direction === 'right') { + // top과 bottom의 방향을 바꾼다. + outerLines.forEach((line) => { + if (line.direction === 'top') { + line.direction = 'bottom' + } else if (line.direction === 'bottom') { + line.direction = 'top' + } + }) + } + canvas.remove(tempPolygon) + } + + // 동, 서 선택 시 가로라인을 케라바로 설정 + const setWestAndEastRoof = (line) => { + if (line.direction === 'left' || line.direction === 'right') { + line.attributes = { + offset: gableOffset / 10, + type: LINE_TYPE.WALLLINE.GABLE, + } + } + } + + // 남, 북 선택 시 세로라인을 케라바로 설정 + const setSouthAndNorthRoof = (line) => { + if (line.direction === 'top' || line.direction === 'bottom') { + line.attributes = { + offset: gableOffset / 10, + type: LINE_TYPE.WALLLINE.GABLE, + } + } + } + + const saveRidge = () => { + // 용마루 저장 + const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + outerLines.forEach((line) => { + line.attributes = { + offset: eavesOffset / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.EAVES, + } + hideLine(line) + }) + + return outerLines + } + + // 패턴 A : 가로선이 모두 케라바 + const saveAPattern = () => { + const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + outerLines + .filter((line) => line.direction === 'left' || line.direction === 'right') + .forEach((line) => { + line.attributes = { + offset: gableOffset / 10, + type: LINE_TYPE.WALLLINE.GABLE, + } + }) + + outerLines + .filter((line) => line.direction === 'top' || line.direction === 'bottom') + .forEach((line) => { + line.attributes = { + offset: eavesOffset / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.EAVES, + } + }) + + return outerLines + } + + // 패턴 B : 세로선이 모두 케라바 + const saveBPattern = () => { + const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + + outerLines + .filter((line) => line.direction === 'left' || line.direction === 'right') + .forEach((line) => { + line.attributes = { + offset: eavesOffset / 10, + pitch: pitch, + type: LINE_TYPE.WALLLINE.EAVES, + } + }) + + outerLines + .filter((line) => line.direction === 'top' || line.direction === 'bottom') + .forEach((line) => { + line.attributes = { + offset: gableOffset / 10, + type: LINE_TYPE.WALLLINE.GABLE, + } + }) + + return outerLines + } + + // 변별로 설정 팝업 내 적용 + const handleConfirm = () => { + const selectedLine = canvas?.getActiveObject() + if (!selectedLine) { + return + } + + let attributes + switch (buttonAct) { + case 1: { + // 처마 + attributes = { + type: LINE_TYPE.WALLLINE.EAVES, + pitch: pitch, + offset: eavesOffset / 10, + } + break + } + case 2: { + // 케라바 + attributes = { + type: LINE_TYPE.WALLLINE.GABLE, + offset: gableOffset / 10, + } + break + } + case 3: { + // 벽 + attributes = { + type: LINE_TYPE.WALLLINE.WALL, + offset: hasSleeve === '0' ? 0 : sleeveOffset / 10, + } + break + } + case 4: { + // 팔작지붕 + attributes = { + type: LINE_TYPE.WALLLINE.HIPANDGABLE, + pitch: pitch, + offset: eavesOffset / 10, + width: hipAndGableWidth / 10, + } + break + } + case 5: { + // 반절처 + attributes = { + type: LINE_TYPE.WALLLINE.JERKINHEAD, + offset: gableOffset / 10, + width: jerkinHeadWidth / 10, + pitch: jerkinHeadPitch, + } + break + } + case 6: { + // 한쪽흐름 + attributes = { + type: LINE_TYPE.WALLLINE.SHED, + offset: shedWidth / 10, + } + break + } + } + selectedLine.attributes = attributes + history.current.push(selectedLine) + nextLineFocus(selectedLine) + } + + const nextLineFocus = (selectedLine) => { + const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + const index = lines.findIndex((line) => line.idx === selectedLine.idx) + + const nextLine = lines[index + 1] || lines[0] + canvas.setActiveObject(nextLine) + } + + // 변별로 설정 내 일변 전으로 돌아가기 + const handleRollBack = () => { + if (history.current.length === 0) { + return + } + const lastLine = history.current.pop() + + lastLine.set({ + stroke: '#000000', + strokeWidth: 4, + }) + + canvas.setActiveObject(lastLine) + canvas.renderAll() + } + + return { + shapeNum, + setShapeNum, + shapeMenu, + handleSave, + buttonMenu, + pitch, + setPitch, + eavesOffset, + setEavesOffset, + gableOffset, + setGableOffset, + sleeveOffset, + setSleeveOffset, + jerkinHeadWidth, + setJerkinHeadWidth, + jerkinHeadPitch, + setJerkinHeadPitch, + hipAndGableWidth, + setHipAndGableWidth, + shedWidth, + setShedWidth, + hasSleeve, + setHasSleeve, + buttonAct, + setButtonAct, + handleConfirm, + handleRollBack, + } +} diff --git a/src/hooks/useAxios.js b/src/hooks/useAxios.js index 1a7cd03e..39b71769 100644 --- a/src/hooks/useAxios.js +++ b/src/hooks/useAxios.js @@ -5,32 +5,40 @@ const AxiosType = { EXTERNAL: 'External', } +/** + * axios 인스턴스 생성 후 반환 + * @param {String} lang + * @returns http request instance - get, post, put, patch, delete (promise 접수사가 붙은 함수는 promise 반환) + */ export function useAxios(lang = '') { const getInstances = (url) => { + /** + * url이 http로 시작하면 외부 서버로 판단 + */ let type = AxiosType.INTERNAL url.startsWith('http') ? (type = AxiosType.EXTERNAL) : '' + /** + * 내부 서버로 요청 시 lang 헤더 추가 + */ + let headerValue = { + Accept: 'application/json', + } + url.startsWith('https') ? '' : (headerValue['lang'] = lang) + return axios.create({ baseURL: type === AxiosType.INTERNAL ? process.env.NEXT_PUBLIC_API_SERVER_PATH : '', - headers: { - Accept: 'application/json', - lang, - }, + headers: headerValue, }) } + // request 추가 로직 axios.interceptors.request.use((config) => { - // config['Authorization'] = localStorage.getItem('token') - //TODO: 인터셉터에서 추가 로직 구현 return config }) - axios.interceptors.request.use(undefined, (error) => { - //TODO: 인터셉터에서 에러 처리 로직 구현 - // if (error.isAxiosError && e.response?.status === 401) { - // localStorage.removeItem('token') - // } - }) + // response 추가 로직 + axios.interceptors.request.use(undefined, (error) => {}) const get = async ({ url }) => { return await getInstances(url) diff --git a/src/hooks/useLine.js b/src/hooks/useLine.js index b6c8a532..f2941e33 100644 --- a/src/hooks/useLine.js +++ b/src/hooks/useLine.js @@ -14,26 +14,38 @@ export const useLine = () => { fontFamily: fontFamily, }) + if (line.length === 0) { + return null + } + canvas?.add(line) return line } - const addLineText = (line, length = getLengthByLine(line)) => { - removeLineText(line) - - const lengthTxt = isNaN(Number(length)) ? length : length.toFixed(0) - - const text = new fabric.Text(lengthTxt, { - left: (line.x2 + line.x1) / 2, - top: (line.y2 + line.y1) / 2, - parent: line, - name: 'lengthTxt', - fontSize: fontSize, - fontFamily: fontFamily, + const hideLine = (line) => { + line.set({ + visible: false, }) + canvas + ?.getObjects() + .find((obj) => obj.parent === line) + .set({ + visible: false, + }) + canvas?.renderAll() + } - canvas?.add(text) - return text + const showLine = (line) => { + line.set({ + visible: true, + }) + canvas + ?.getObjects() + .find((obj) => obj.parent === line) + .set({ + visible: true, + }) + canvas?.renderAll() } const removeLine = (line) => { @@ -62,5 +74,7 @@ export const useLine = () => { return { addLine, removeLine, + hideLine, + showLine, } } diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index fedbb3be..e861f9f8 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -6,7 +6,7 @@ import { useSwal } from '@/hooks/useSwal' export function usePlan() { const [canvas, setCanvas] = useRecoilState(canvasState) - const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) + const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const [initCanvasPlans, setInitCanvasPlans] = useRecoilState(initCanvasPlansState) const { swalFire } = useSwal() const { getMessage } = useMessage() @@ -47,6 +47,11 @@ export function usePlan() { 'minY', 'x', 'y', + 'x1', + 'x2', + 'y1', + 'y2', + 'attributes', 'stickeyPoint', ]) @@ -65,6 +70,24 @@ export function usePlan() { // }, 1000) } + /** + * 실시간 캔버스 상태와 DB에 저장된 캔버스 상태를 비교하여 수정 여부를 판단 + */ + const checkModifiedCanvasPlan = () => { + removeMouseLines() + const canvasStr = addCanvas() + const canvasStatus = dbToCanvasFormat(canvasToDbFormat(canvasStr)) + if (JSON.parse(canvasStr).objects.length === 0 && currentCanvasPlan.canvasStatus === undefined) { + // 빈 캔버스 + return false + } else if (canvasStatus === currentCanvasPlan.canvasStatus) { + // 변경사항 없는 캔버스 + return false + } else { + return true + } + } + /** * DB에 저장된 데이터를 canvas에서 사용할 수 있도록 포맷화 */ @@ -101,14 +124,14 @@ export function usePlan() { await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData }) .then((res) => { swalFire({ text: getMessage('common.message.save') }) - console.log('[PUT] canvas-statuses res :::::::: %o', res) + // console.log('[PUT] canvas-statuses res :::::::: %o', res) setInitCanvasPlans((initCanvasPlans) => initCanvasPlans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)), ) }) .catch((error) => { swalFire({ text: error.message, icon: 'error' }) - console.error('[PUT] canvas-statuses error :::::::: %o', error) + // console.error('[PUT] canvas-statuses error :::::::: %o', error) }) } else { // canvas 신규 등록 @@ -122,11 +145,15 @@ export function usePlan() { await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData }) .then((res) => { swalFire({ text: getMessage('common.message.save') }) - console.log('[POST] canvas-statuses response :::::::: %o', res) + setInitCanvasPlans([ + ...initCanvasPlans, + { id: res.data, name: currentCanvasPlan.objectNo + '-' + res.data, userId: userId, canvasStatus: canvasStatus, isNew: currentCanvasPlan.id }, + ]) + // console.log('[POST] canvas-statuses response :::::::: %o', res) }) .catch((error) => { swalFire({ text: error.message, icon: 'error' }) - console.error('[POST] canvas-statuses res error :::::::: %o', error) + // console.error('[POST] canvas-statuses res error :::::::: %o', error) }) } } @@ -165,6 +192,7 @@ export function usePlan() { removeMouseLines, saveCanvas, addCanvas, + checkModifiedCanvasPlan, getCanvasByObjectNo, delCanvasById, } diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 13b12fe1..2d981933 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -12,6 +12,8 @@ export const usePolygon = () => { const addPolygon = (points, options) => { const polygon = new QPolygon(points, { ...options, + fill: options.fill || 'transparent', + stroke: options.stroke || '#000000', fontSize: fontSize, fontFamily: fontFamily, selectable: true, diff --git a/src/hooks/useSwal.js b/src/hooks/useSwal.js index ab747756..cb18e6a7 100644 --- a/src/hooks/useSwal.js +++ b/src/hooks/useSwal.js @@ -35,7 +35,7 @@ export const useSwal = () => { }).then((result) => { if (result.isConfirmed) { confirmFn() - } else if (result.isDenied) { + } else if (result.isDismissed) { denyFn() } }) diff --git a/src/lib/Axios.js b/src/lib/Axios.js deleted file mode 100644 index d773d352..00000000 --- a/src/lib/Axios.js +++ /dev/null @@ -1,56 +0,0 @@ -'use client' - -import axios from 'axios' - -axios.defaults.baseURL = process.env.NEXT_PUBLIC_API_SERVER_PATH - -const axiosInstance = axios.create({ - // baseURL: process.env.API_SERVER_URL, - headers: { - Accept: 'application/json', - }, -}) - -axiosInstance.interceptors.request.use((config) => { - // config['Authorization'] = localStorage.getItem('token') - //TODO: 인터셉터에서 추가 로직 구현 - return config -}) - -axiosInstance.interceptors.request.use(undefined, (error) => { - //TODO: 인터셉터에서 에러 처리 로직 구현 - // if (error.isAxiosError && e.response?.status === 401) { - // localStorage.removeItem('token') - // } -}) - -export const get = ({ url }) => - axiosInstance - .get(url) - .then((res) => res.data) - .catch(console.error) - -export const post = ({ url, data }) => - axiosInstance - .post(url, data) - .then((res) => res.data) - .catch(console.error) - -export const put = ({ url, data }) => - axiosInstance - .put(url, data) - .then((res) => res.data) - .catch(console.error) - -export const patch = ({ url, data }) => - axiosInstance - .patch(url, data) - - .then((res) => res.data) - .catch(console.error) - -export const del = ({ url }) => - axiosInstance - .delete(url) - .then((res) => res.data) - .catch(console.error) diff --git a/src/locales/ja.json b/src/locales/ja.json index 1c681ff1..bfc322cf 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -288,17 +288,18 @@ "join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.", "join.complete.email_comment": "담당자 이메일 주소", "join.complete.email": "test@naver.com", - "stuff.gridHeader.lastEditDatetime": "갱신일시", - "stuff.gridHeader.objectNo": "물건번호", - "stuff.gridHeader.planTotCnt": "플랜 수", - "stuff.gridHeader.objectName": "물건명", - "stuff.gridHeader.saleStoreId": "대리점ID", - "stuff.gridHeader.saleStoreName": "대리점명", - "stuff.gridHeader.address": "물건주소", - "stuff.gridHeader.dispCompanyName": "견적처", - "stuff.gridHeader.receiveUser": "담당자", - "stuff.gridHeader.specDate": "사양확인", - "stuff.gridHeader.createDatetime": "등록일", + "stuff.gridHeader.lastEditDatetime": "更新日時", + "stuff.gridHeader.objectNo": "品番", + "stuff.gridHeader.planTotCnt": "プラン数", + "stuff.gridHeader.objectName": "商品名", + "stuff.gridHeader.saleStoreId": "代理店ID", + "stuff.gridHeader.saleStoreName": "代理店名", + "stuff.gridHeader.address": "商品アドレス", + "stuff.gridHeader.dispCompanyName": "見積もり", + "stuff.gridHeader.receiveUser": "担当者", + "stuff.gridHeader.specDate": "仕様確認日", + "stuff.gridHeader.createDatetime": "登録日", + "stuff.message.periodError": "最大1年間閲覧可能.", "length": "長さ", "slope": "傾斜", "eaves.offset": "軒の", @@ -317,6 +318,7 @@ "angle": "角度", "diagonal": "対角線", "hipandgable": "八作屋根", + "hipandgable.width": "八作屋根 出幅", "jerkinhead": "半折", "shed": "片側の流れ", "apply": "適用", diff --git a/src/locales/ko.json b/src/locales/ko.json index 4f320cdc..daae4d24 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -304,8 +304,9 @@ "stuff.gridHeader.address": "물건주소", "stuff.gridHeader.dispCompanyName": "견적처", "stuff.gridHeader.receiveUser": "담당자", - "stuff.gridHeader.specDate": "사양확인", + "stuff.gridHeader.specDate": "사양확인일", "stuff.gridHeader.createDatetime": "등록일", + "stuff.message.periodError": "최대1년 조회 가능합니다.", "length": "길이", "slope": "경사", "eaves.offset": "처마 출폭", @@ -324,6 +325,7 @@ "angle": "각도", "diagonal": "대각선", "hipandgable": "팔작지붕", + "hipandgable.width": "팔작지붕의 폭", "jerkinhead": "반절처", "shed": "한쪽흐름", "apply": "적용", diff --git a/src/store/stuffAtom.js b/src/store/stuffAtom.js index 5de2c04e..e126fb35 100644 --- a/src/store/stuffAtom.js +++ b/src/store/stuffAtom.js @@ -10,7 +10,6 @@ export const stuffSearchState = atom({ schAddress: '', //물건주소 schObjectName: '', //물건명 schSaleStoreName: '', //판매대리점명 - schSpecDateYn: '', //사양타입 ('', 'Y', 'N') schReceiveUser: '', //담당자 schDispCompanyName: '', //견적처 schDateType: 'U', //갱신일(U)/등록일(R) diff --git a/src/util/common-utils.js b/src/util/common-utils.js index 1b7cd166..9244b046 100644 --- a/src/util/common-utils.js +++ b/src/util/common-utils.js @@ -59,3 +59,10 @@ export const queryStringFormatter = (params = {}) => { }) return queries.join('&') } + +// 43000 --> 43,000 +export const convertNumberToPriceDecimal = (value) => { + if (value) return Number(value).toLocaleString() + else if (value === 0) return 0 + else return '' +} diff --git a/src/util/input-utils.js b/src/util/input-utils.js index f674e6cd..18f93425 100644 --- a/src/util/input-utils.js +++ b/src/util/input-utils.js @@ -1,6 +1,6 @@ // 숫자만 입력 가능한 input onChange 함수 export const onlyNumberInputChange = (e, callback) => { - let value = e.target.value.replace(/^0+/, '') + let value = e.target.value value = value.replace(/[^-0-9]/g, '') callback(value, e) } diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index a7bcb0e2..6605e3b3 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1197,6 +1197,7 @@ export const drawHippedRoof = (polygon, chon) => { alert('대각선이 존재합니다.') return } + drawRidgeRoof(polygon, chon) drawHips(polygon) connectLinePoint(polygon) diff --git a/yarn.lock b/yarn.lock index affc38d7..1ffd6b98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -163,6 +163,66 @@ jsonwebtoken "^9.0.0" uuid "^8.3.0" +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7" + integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g== + dependencies: + "@babel/highlight" "^7.25.7" + picocolors "^1.0.0" + +"@babel/generator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56" + integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA== + dependencies: + "@babel/types" "^7.25.7" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + +"@babel/helper-module-imports@^7.16.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472" + integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-string-parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" + integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== + +"@babel/helper-validator-identifier@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" + integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== + +"@babel/highlight@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5" + integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw== + dependencies: + "@babel/helper-validator-identifier" "^7.25.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.7.tgz#99b927720f4ddbfeb8cd195a363ed4532f87c590" + integrity sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw== + dependencies: + "@babel/types" "^7.25.7" + +"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6" + integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.20.13", "@babel/runtime@^7.24.8": version "7.25.0" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz" @@ -170,6 +230,37 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/template@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" + integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA== + dependencies: + "@babel/code-frame" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/traverse@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" + integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== + dependencies: + "@babel/code-frame" "^7.25.7" + "@babel/generator" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/template" "^7.25.7" + "@babel/types" "^7.25.7" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.7.tgz#1b7725c1d3a59f328cb700ce704c46371e6eef9b" + integrity sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ== + dependencies: + "@babel/helper-string-parser" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + to-fast-properties "^2.0.0" + "@bedrock-layout/use-forwarded-ref@^1.3.1": version "1.6.1" resolved "https://registry.npmjs.org/@bedrock-layout/use-forwarded-ref/-/use-forwarded-ref-1.6.1.tgz" @@ -182,6 +273,118 @@ resolved "https://registry.npmjs.org/@bedrock-layout/use-stateful-ref/-/use-stateful-ref-1.4.1.tgz" integrity sha512-4eKO2KdQEXcR5LI4QcxqlJykJUDQJWDeWYAukIn6sRQYoabcfI5kDl61PUi6FR6o8VFgQ8IEP7HleKqWlSe8SQ== +"@emotion/babel-plugin@^11.11.0": + version "11.12.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz#7b43debb250c313101b3f885eba634f1d723fcc2" + integrity sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.2" + "@emotion/memoize" "^0.9.0" + "@emotion/serialize" "^1.2.0" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + +"@emotion/cache@^11.11.0": + version "11.13.1" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.1.tgz#fecfc54d51810beebf05bf2a161271a1a91895d7" + integrity sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw== + dependencies: + "@emotion/memoize" "^0.9.0" + "@emotion/sheet" "^1.4.0" + "@emotion/utils" "^1.4.0" + "@emotion/weak-memoize" "^0.4.0" + stylis "4.2.0" + +"@emotion/hash@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" + integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== + +"@emotion/is-prop-valid@^1.2.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz#8d5cf1132f836d7adbe42cf0b49df7816fc88240" + integrity sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw== + dependencies: + "@emotion/memoize" "^0.9.0" + +"@emotion/memoize@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102" + integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== + +"@emotion/react@11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.0.tgz#408196b7ef8729d8ad08fc061b03b046d1460e02" + integrity sha512-ZSK3ZJsNkwfjT3JpDAWJZlrGD81Z3ytNDsxw1LKq1o+xkmO5pnWfr6gmCC8gHEFf3nSSX/09YrG67jybNPxSUw== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.2.0": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.2.tgz#e1c1a2e90708d5d85d81ccaee2dfeb3cc0cccf7a" + integrity sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA== + dependencies: + "@emotion/hash" "^0.9.2" + "@emotion/memoize" "^0.9.0" + "@emotion/unitless" "^0.10.0" + "@emotion/utils" "^1.4.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" + integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== + +"@emotion/styled@11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + +"@emotion/unitless@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745" + integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz#1a818a0b2c481efba0cf34e5ab1e0cb2dcb9dfaf" + integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw== + +"@emotion/utils@^1.2.1", "@emotion/utils@^1.4.0", "@emotion/utils@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.1.tgz#b3adbb43de12ee2149541c4f1337d2eb7774f0ad" + integrity sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA== + +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + +"@emotion/weak-memoize@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6" + integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== + "@floating-ui/core@^1.6.0": version "1.6.7" resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz" @@ -298,7 +501,7 @@ wrap-ansi "^8.1.0" wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" -"@jridgewell/gen-mapping@^0.3.2": +"@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz" integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== @@ -322,7 +525,7 @@ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.24": +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -3877,6 +4080,11 @@ dependencies: undici-types "~6.18.2" +"@types/parse-json@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== + "@types/readable-stream@^4.0.0": version "4.0.15" resolved "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.15.tgz" @@ -3969,6 +4177,13 @@ ansi-regex@^6.0.1: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + ansi-styles@^4.0.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" @@ -4035,6 +4250,15 @@ axios@^1.7.3: form-data "^4.0.0" proxy-from-env "^1.1.0" +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" @@ -4112,6 +4336,11 @@ busboy@1.6.0: dependencies: streamsearch "^1.1.0" +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + camelcase-css@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" @@ -4131,6 +4360,15 @@ canvas@^2.8.0: nan "^2.17.0" simple-get "^3.0.3" +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + "chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" @@ -4171,6 +4409,13 @@ clsx@^2.0.0, clsx@^2.1.0: resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" @@ -4178,6 +4423,11 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" @@ -4261,6 +4511,11 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0: resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== +convert-source-map@^1.5.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + convertapi@^1.14.0: version "1.14.0" resolved "https://registry.yarnpkg.com/convertapi/-/convertapi-1.14.0.tgz#a291a98cb986ae1e0f2340a130adbe17f65c8c76" @@ -4273,6 +4528,17 @@ cookie@0.6.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cosmiconfig@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + cross-spawn@^7.0.0: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" @@ -4304,6 +4570,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + d3-array@1: version "1.2.4" resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz" @@ -4347,6 +4618,13 @@ debug@4, debug@^4.3.3, debug@^4.3.4: dependencies: ms "2.1.2" +debug@^4.3.1: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + decimal.js@^10.3.1, decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz" @@ -4433,11 +4711,28 @@ emoji-regex@^9.2.2: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + escape-latex@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz" integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz" @@ -4512,6 +4807,11 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + flat@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" @@ -4649,6 +4949,11 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + graceful-fs@^4.2.11: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" @@ -4659,6 +4964,11 @@ hamt_plus@1.0.2: resolved "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz" integrity sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" @@ -4671,6 +4981,13 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +hoist-non-react-statics@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + html-encoding-sniffer@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz" @@ -4728,6 +5045,14 @@ immutable@^4.0.0: resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz" integrity sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw== +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" @@ -4777,6 +5102,11 @@ iron-webcrypto@1.2.1: resolved "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz" integrity sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg== +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" @@ -4864,7 +5194,7 @@ js-md4@^0.3.2: resolved "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz" integrity sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA== -"js-tokens@^3.0.0 || ^4.0.0": +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -4902,6 +5232,16 @@ jsdom@^19.0.0: ws "^8.2.3" xml-name-validator "^4.0.0" +jsesc@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + jsonwebtoken@^9.0.0: version "9.0.2" resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz" @@ -5155,6 +5495,11 @@ ms@2.1.2, ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + mssql@^11.0.1: version "11.0.1" resolved "https://registry.npmjs.org/mssql/-/mssql-11.0.1.tgz" @@ -5283,6 +5628,23 @@ open@^8.0.0: is-docker "^2.1.1" is-wsl "^2.2.0" +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + parse5@6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" @@ -5311,6 +5673,11 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + picocolors@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz" @@ -5523,6 +5890,14 @@ react-draggable@^4.4.6: clsx "^1.1.1" prop-types "^15.8.1" +react-dropdown-select@^4.11.3: + version "4.11.3" + resolved "https://registry.yarnpkg.com/react-dropdown-select/-/react-dropdown-select-4.11.3.tgz#b23b8906f3bedc9d6a1a2125af936b34d4057158" + integrity sha512-/mOGSqqhmKsxxrmotLM+qn1Ss3nxGN6QnYusyQ7f0wizsWrc7ZmbcZhGRtwkJwpL6JYDQVTn19EYxJU1XfXrDA== + dependencies: + "@emotion/react" "11.11.0" + "@emotion/styled" "11.11.0" + react-hook-form@^7.53.0: version "7.53.0" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.53.0.tgz#3cf70951bf41fa95207b34486203ebefbd3a05ab" @@ -5533,7 +5908,7 @@ react-icons@^5.3.0: resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c" integrity sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg== -react-is@^16.13.1: +react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -5654,7 +6029,12 @@ requires-port@^1.0.0: resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -resolve@^1.1.7, resolve@^1.22.2: +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.1.7, resolve@^1.19.0, resolve@^1.22.2: version "1.22.8" resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -5820,6 +6200,11 @@ skmeans@0.9.7: resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== +source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + source-map@~0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" @@ -5907,6 +6292,11 @@ styled-jsx@5.1.1: dependencies: client-only "0.0.1" +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + sucrase@^3.32.0: version "3.35.0" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz" @@ -5920,6 +6310,13 @@ sucrase@^3.32.0: pirates "^4.0.1" ts-interface-checker "^0.1.9" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" @@ -6049,6 +6446,11 @@ tinyqueue@^2.0.0, tinyqueue@^2.0.3: resolved "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz" integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA== +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" @@ -6294,6 +6696,11 @@ yallist@^4.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + yaml@^2.3.4: version "2.4.5" resolved "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz"