+import { Button } from '@nextui-org/react'
+import { useRecoilState } from 'recoil'
+import { modalContent, modalState } from '@/store/modalAtom'
+
+export default function Login(props) {
+ const { currentLocale } = props
+ const { getMessage } = useMessage()
+
+ // login process
+ const loginProcess = async (formData) => {
+ const param = {
+ langCd: currentLocale,
+ lastEditUser: formData.get('id'),
+ loginId: formData.get('id'),
+ pwd: formData.get('password'),
+ }
+
+ await post({ url: '/api/login/v1.0/login', data: param }).then((res) => {
+ if (res) {
+ if (res.result.resultCode == 'S') {
+ // console.log('res.data', res.data)
+ // ๋น๋ฐ๋ฒํธ ์ด๊ธฐํ๊ฐ ํ์ํ ๊ฒฝ์ฐ
+ // if (res.data.pwdInitYn != 'Y') {
+ // alert('๋น๋ฐ๋ฒํธ ์ด๊ธฐํ๊ฐ ํ์ํ ๊ฒฝ์ฐ')
+ // } else {
+ setSession(res.data)
+ redirect('/')
+ // }
+ } else {
+ alert(res.result.resultMsg)
+ }
+ }
+ })
+ }
+
+ // ๋น๋ฐ๋ฒํธ ์ด๊ธฐํ ๊ด๋ จ
+ const [open, setOpen] = useRecoilState(modalState)
+ const [contents, setContent] = useRecoilState(modalContent)
+
+ const initPasswordProcess = async (formData) => {
+ const param = {
+ langCd: currentLocale,
+ lastEditUser: formData.get('checkId'),
+ loginId: formData.get('checkId'),
+ email: formData.get('checkEmail'),
+ }
+
+ await patch({ url: '/api/login/v1.0/user/init-password', data: param }).then((res) => {
+ if (res) {
+ if (res.result.resultCode == 'S') {
+ alert(getMessage('login.init_password.complete_message'))
+ redirect('/login')
+ } else {
+ alert(res.result.resultMsg)
+ }
+ }
+ })
+ }
+
+ const initPasswordContent = (
+
+
-
+
+
diff --git a/src/components/common/context-menu/QContextMenu.jsx b/src/components/common/context-menu/QContextMenu.jsx
index 9a805ba1..4658ef6f 100644
--- a/src/components/common/context-menu/QContextMenu.jsx
+++ b/src/components/common/context-menu/QContextMenu.jsx
@@ -12,9 +12,11 @@ export default function QContextMenu(props) {
let contextType = ''
if (activeObject) {
- //์ด๊ฑด ๋ฐ๋ ๊ฐ๋ฅ์ฑ์ด ์์
- if (activeObject.initOptions.name.indexOf('guide') > -1) {
- contextType = 'surface' //๋ฉดํ์
+ if (activeObject.initOptions) {
+ //์ด๊ฑด ๋ฐ๋ ๊ฐ๋ฅ์ฑ์ด ์์
+ if (activeObject.initOptions.name.indexOf('guide') > -1) {
+ contextType = 'surface' //๋ฉดํ์
+ }
}
}
diff --git a/src/components/common/datepicker/RangeDatePicker.jsx b/src/components/common/datepicker/RangeDatePicker.jsx
index ad802f49..de80221f 100644
--- a/src/components/common/datepicker/RangeDatePicker.jsx
+++ b/src/components/common/datepicker/RangeDatePicker.jsx
@@ -14,6 +14,7 @@ export default function RangeDatePicker(props) {
setDateRange(update)
}}
isClearable={true}
+ // showMonthYearPicker={true}
/>
)
}
diff --git a/src/components/common/draggable/withDraggable.jsx b/src/components/common/draggable/withDraggable.jsx
new file mode 100644
index 00000000..9f322583
--- /dev/null
+++ b/src/components/common/draggable/withDraggable.jsx
@@ -0,0 +1,22 @@
+'use client'
+
+import { useState } from 'react'
+import Draggable from 'react-draggable'
+
+export default function WithDraggable({ isShow, children }) {
+ const [position, setPosition] = useState({ x: 0, y: 0 })
+
+ const handleOnDrag = (data) => {
+ setPosition({ x: data.x, y: data.y })
+ }
+
+ return (
+ <>
+ {isShow && (
+
handleOnDrag(data)}>
+ {children}
+
+ )}
+ >
+ )
+}
diff --git a/src/components/common/select/QSelectBox.jsx b/src/components/common/select/QSelectBox.jsx
new file mode 100644
index 00000000..6e77a539
--- /dev/null
+++ b/src/components/common/select/QSelectBox.jsx
@@ -0,0 +1,19 @@
+'use client'
+import { useState } from 'react'
+
+export default function QSelectBox({ title, option }) {
+ const [selectAct, setSelectAct] = useState(false)
+
+ return (
+
setSelectAct(!selectAct)}>
+
{title}
+
+ {option.map((el, idx) => (
+ -
+
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js
index 0991fd84..84e57974 100644
--- a/src/components/fabric/QPolygon.js
+++ b/src/components/fabric/QPolygon.js
@@ -119,6 +119,9 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
this.on('modified', (e) => {
this.addLengthText()
+ if (this.arrow) {
+ drawDirectionArrow(this)
+ }
})
this.on('selected', () => {
@@ -136,6 +139,17 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
this.canvas.remove(text)
})
this.texts = null
+
+ if (this.arrow) {
+ this.canvas.remove(this.arrow)
+ this.canvas
+ .getObjects()
+ .filter((obj) => obj.name === 'directionText' && obj.parent === this.arrow)
+ .forEach((text) => {
+ this.canvas.remove(text)
+ })
+ this.arrow = null
+ }
})
// polygon.fillCell({ width: 50, height: 30, padding: 10 })
diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx
new file mode 100644
index 00000000..5923888f
--- /dev/null
+++ b/src/components/floor-plan/CanvasFrame.jsx
@@ -0,0 +1,7 @@
+export default function CanvasFrame () {
+ return(
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx
new file mode 100644
index 00000000..5be6a114
--- /dev/null
+++ b/src/components/floor-plan/CanvasLayout.jsx
@@ -0,0 +1,45 @@
+'use client'
+
+import { useState } from "react"
+import CanvasFrame from "./CanvasFrame";
+
+export default function CanvasLayout () {
+ const [plans, setPlans] = useState([{ id: 0, name: 'Plan 1' }, { id: 1, name: 'Plan 2' }, { id: 2, name: 'Plan 3' }]);
+ const [idxNum, setIdxNum] = useState(null);
+
+ const onClickPlane = (num) => {
+ setIdxNum(num);
+ }
+
+ const handleDeletePlan = (e, id) => {
+ e.stopPropagation(); // ์ด๋ฒคํธ ๋ฒ๋ธ๋ง ๋ฐฉ์ง
+ setPlans(plans.filter(plan => plan.id !== id)); // ์ญ์ ํ ์์ด๋์ ๋ค๋ฅธ ์์ดํ
๋ง ๋จ๊น
+ }
+
+ const addNewPlan = () => {
+ setPlans([...plans, { id: plans.length, name: `Plan ${plans.length + 1}` }]);
+ }
+
+ return(
+
+
+
+ {plans.map((plan, idx) => (
+
+ ))}
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx
new file mode 100644
index 00000000..4533747a
--- /dev/null
+++ b/src/components/floor-plan/CanvasMenu.jsx
@@ -0,0 +1,97 @@
+'use client'
+import { useState } from 'react'
+import MenuDepth01 from './MenuDepth01'
+import QSelectBox from '@/components/common/select/QSelectBox'
+
+export default function CanvasMenu({ setModalOpen }) {
+ const [menuNumber, setMenuNumber] = useState(null)
+ const [vertical, setVertical] = useState(true)
+ const SelectOption = [{ name: '็ฆ53A' }, { name: '็ฆ53A' }]
+ const onClickNav = (number) => {
+ setMenuNumber(number)
+ if (menuNumber === number) {
+ setMenuNumber(null)
+ }
+ }
+ return (
+
+
+
+ - onClickNav(0)}>
+
+
+ - onClickNav(1)}>
+
+
+ - onClickNav(2)}>
+
+
+ - onClickNav(3)}>
+
+
+ - onClickNav(4)}>
+
+
+ - onClickNav(5)}>
+
+
+ - onClickNav(6)}>
+
+
+
+
+
+
+
+
+
+
+ ๅ็ดๆฐดๅนณใขใผใ
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+
+
+
+
+
+
+
+
+
+
+ {menuNumber === 0 && }
+ {menuNumber === 1 && }
+ {menuNumber === 2 && }
+ {menuNumber === 3 && }
+ {menuNumber === 4 && }
+ {menuNumber === 5 && }
+ {menuNumber === 6 && }
+
+
+ )
+}
diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx
new file mode 100644
index 00000000..fecffea7
--- /dev/null
+++ b/src/components/floor-plan/FloorPlan.jsx
@@ -0,0 +1,21 @@
+'use client'
+
+import CanvasMenu from '@/components/floor-plan/CanvasMenu'
+import CanvasLayout from '@/components/floor-plan/CanvasLayout'
+import SettingModal01 from '@/components/floor-plan/modal/settoing01/SettingModal01'
+import { useState } from 'react'
+
+export default function FloorPlan() {
+ const [modalOpen, setModalOpen] = useState('option')
+ return (
+ <>
+
+
+
+
+ {modalOpen === 'option' && }
+
+
+ >
+ )
+}
diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx
new file mode 100644
index 00000000..90ba4e60
--- /dev/null
+++ b/src/components/floor-plan/MenuDepth01.jsx
@@ -0,0 +1,44 @@
+'use client'
+
+import { ToggleonMouse } from '@/components/header/Header'
+
+export default function MenuDepth01() {
+ return (
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ - ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}>
+
+
+ - ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}>
+
+
+ - ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}>
+
+
+
+
+ )
+}
diff --git a/src/components/floor-plan/modal/settoing01/FirstOption.jsx b/src/components/floor-plan/modal/settoing01/FirstOption.jsx
new file mode 100644
index 00000000..e91f81ab
--- /dev/null
+++ b/src/components/floor-plan/modal/settoing01/FirstOption.jsx
@@ -0,0 +1,39 @@
+import { useRecoilState } from 'recoil'
+import { settingModalFirstOptionsState } from '@/store/settingAtom'
+
+export default function FirstOption() {
+ const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalFirstOptionsState)
+ const { option1, option2 } = settingsModalOptions
+ const onClickOption = (option) => {
+ option.selected = !option.selected
+
+ setSettingModalOptions({ option1, option2 })
+ }
+
+ return (
+ <>
+
+
โปๅณ้ขใซ่กจ็คบใใ้
็ฎใใฏใชใใฏใใใจ้ฉ็จใใใพใใ
+
+ {settingsModalOptions?.option1?.map((item) => (
+
+ ))}
+
+
+
+
็ป้ข่กจ็คบ
+
+ {settingsModalOptions?.option2?.map((item) => (
+
+ ))}
+
+
+ >
+ )
+}
diff --git a/src/components/floor-plan/modal/settoing01/SecondOption.jsx b/src/components/floor-plan/modal/settoing01/SecondOption.jsx
new file mode 100644
index 00000000..5b417f2b
--- /dev/null
+++ b/src/components/floor-plan/modal/settoing01/SecondOption.jsx
@@ -0,0 +1,45 @@
+import { useRecoilState } from 'recoil'
+import { settingModalSecondOptionsState } from '@/store/settingAtom'
+
+export default function SecondOption() {
+ const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalSecondOptionsState)
+ const { option1, option2 } = settingsModalOptions
+ const onClickOption = (option) => {
+ option.selected = !option.selected
+
+ setSettingModalOptions({ option1: option1, option2: option2 })
+ }
+ return (
+ <>
+
+
ใใฉใณใใจใตใคใบใฎๅคๆด
+
+ {settingsModalOptions.option1.map((item) => (
+
+ ))}
+
+
+
+
ๅธ็็ฏๅฒใฎ่จญๅฎ
+
+ {settingsModalOptions.option2.map((item) => (
+
+ ))}
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/src/components/floor-plan/modal/settoing01/SettingModal01.jsx b/src/components/floor-plan/modal/settoing01/SettingModal01.jsx
new file mode 100644
index 00000000..5a79c795
--- /dev/null
+++ b/src/components/floor-plan/modal/settoing01/SettingModal01.jsx
@@ -0,0 +1,44 @@
+'use client'
+
+import { useState } from 'react'
+import FirstOption from './FirstOption'
+import WithDraggable from '@/components/common/draggable/withDraggable'
+import SecondOption from '@/components/floor-plan/modal/settoing01/SecondOption'
+
+export default function SettingModal01({ modalOpen, setModalOpen }) {
+ const [buttonAct, setButtonAct] = useState(1)
+ const [close, setClose] = useState(false)
+ const HandleClickClose = () => {
+ setClose(true)
+ setTimeout(() => {
+ setModalOpen('')
+ setClose(false)
+ }, 180)
+ }
+
+ return (
+
+
+
+
Canvas่จญๅฎ
+
+
+
+
+
+
+
+
+ {buttonAct === 1 &&
}
+ {buttonAct === 2 &&
}
+
+
+
+ )
+}
diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx
new file mode 100644
index 00000000..028ef6ed
--- /dev/null
+++ b/src/components/header/Header.jsx
@@ -0,0 +1,117 @@
+'use client'
+import Link from 'next/link'
+import QSelectBox from '@/components/common/select/QSelectBox'
+import { usePathname } from 'next/navigation'
+
+export const ToggleonMouse = (e, act, target) => {
+ const listWrap = e.target.closest(target)
+ const ListItem = Array.from(listWrap.childNodes)
+ ListItem.forEach((el) => {
+ if (act === 'add') {
+ el.classList.add('mouse')
+ } else {
+ el.classList.remove('mouse')
+ }
+ })
+ if (act === 'add') {
+ e.target.parentElement.classList.remove('mouse')
+ }
+}
+
+export default function Header() {
+ const pathName = usePathname()
+ if (pathName.includes('login') || pathName.includes('join')) {
+ return null
+ }
+ const SelectOption = [{ name: 'ใชใณใฉใคใณไฟ่จผใท' }, { name: 'ในใใ ' }]
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx
index da7b834d..f8467027 100644
--- a/src/components/management/Stuff.jsx
+++ b/src/components/management/Stuff.jsx
@@ -1,7 +1,361 @@
+'use client'
+
+import React, { useEffect, useState, useRef } from 'react'
+import { useRouter, usePathname } from 'next/navigation'
+import { Button } from '@nextui-org/react'
+import { useAxios } from '@/hooks/useAxios'
+import { useMessage } from '@/hooks/useMessage'
+import StuffQGrid from './StuffQGrid'
+import { useRecoilValue } from 'recoil'
+import { stuffSearchState } from '@/store/stuffAtom'
+import { queryStringFormatter } from '@/util/common-utils'
+import dayjs from 'dayjs'
+import isLeapYear from 'dayjs/plugin/isLeapYear' // ์ค๋
ํ๋จ ํ๋ฌ๊ทธ์ธ
+dayjs.extend(isLeapYear)
+
export default function Stuff() {
+ const stuffSearchParams = useRecoilValue(stuffSearchState)
+ const { getMessage } = useMessage()
+ const [curPage, setCurPage] = useState(1) //ํ์ฌ ํ์ด์ง ๋ฒํธ
+ const [size, setSize] = useState(100) //ํ์ด์ง ๋น ๊ฒ์๋ฌผ ์
+ const { get, del } = useAxios()
+ const gridRef = useRef()
+
+ const [gridCount, setGridCount] = useState(0)
+ const [selectedRowData, setSelectedRowData] = useState([])
+ const [selectedRowDataCount, setSelectedRowDataCount] = useState(0)
+
+ const router = useRouter()
+ const pathname = usePathname()
+
+ //๊ทธ๋ฆฌ๋ ๋ด๋ถ ๋ณต์ฌ๋ฒํผ
+ const copyNo = async (value) => {
+ try {
+ await navigator.clipboard.writeText(value)
+ alert('๋ฌผ๊ฑด๋ฒํธ๊ฐ ๋ณต์ฌ๋์์ต๋๋ค.')
+ } catch (error) {
+ alert('๋ฌผ๊ฑด๋ฒํธ ๋ณต์ฌ์ ์คํจํ์ต๋๋ค.')
+ }
+ }
+
+ const [gridProps, setGridProps] = useState({
+ gridData: [],
+ isPageable: false,
+ // sets 10 rows per page (default is 100)
+ paginationPageSize: 100,
+ // allows the user to select the page size from a predefined list of page sizes
+ paginationPageSizeSelector: [100, 200, 300, 400],
+ gridColumns: [
+ {
+ field: 'lastEditDatetime',
+ headerName: getMessage('stuff.gridHeader.lastEditDatetime'),
+ headerCheckboxSelection: true,
+ headerCheckboxSelectionCurrentPageOnly: true, //ํ์ด์ง์ ํ์ฌ ํ์ด์ง๋ง ์ฒดํฌ๋๋๋ก
+ checkboxSelection: true,
+ showDisabledCheckboxes: true,
+ // headerClass: 'centered', //_test.scss์ ์ถ๊ฐ ํ
์คํธ
+ // .centered {
+ // .ag-header-cell-label {
+ // justify-content: center !important;
+ // }
+ // }
+ cellStyle: { textAlign: 'center' },
+ //suppressMovable: true, //ํค๋ ๋ชป์์ง์ด๊ฒ
+ // width : 100
+ // minWidth : 100
+ // maxWidth : 100
+ valueFormatter: function (params) {
+ if (params.value) {
+ return dayjs(params?.value).format('YYYY.MM.DD HH:mm:ss')
+ } else {
+ return null
+ }
+ },
+ },
+ {
+ field: 'objectNo',
+ headerName: getMessage('stuff.gridHeader.objectNo'),
+ // headerClass: 'centered', //_test.scss์ ์ถ๊ฐ ํ
์คํธ
+ cellRenderer: function (params) {
+ if (params.data.objectNo) {
+ return (
+
+
+ {params.value}
+
+ )
+ }
+ },
+ cellRendererParams: {
+ onPress: copyNo,
+ },
+ },
+ {
+ field: 'planTotCnt',
+ headerName: getMessage('stuff.gridHeader.planTotCnt'),
+ cellStyle: { textAlign: 'right' },
+ },
+ { field: 'objectName', headerName: getMessage('stuff.gridHeader.objectName'), cellStyle: { textAlign: 'left' } },
+ {
+ field: 'saleStoreId',
+ headerName: getMessage('stuff.gridHeader.saleStoreId'),
+ cellStyle: { textAlign: 'left' },
+ },
+ { field: 'saleStoreName', headerName: getMessage('stuff.gridHeader.saleStoreName'), cellStyle: { textAlign: 'left' } },
+ { field: 'address', headerName: getMessage('stuff.gridHeader.address'), cellStyle: { textAlign: 'left' } },
+ { field: 'dispCompanyName', headerName: getMessage('stuff.gridHeader.dispCompanyName'), cellStyle: { textAlign: 'left' } },
+ { field: 'receiveUser', headerName: getMessage('stuff.gridHeader.receiveUser'), cellStyle: { textAlign: 'left' } },
+ {
+ field: 'specDate',
+ headerName: getMessage('stuff.gridHeader.specDate'),
+ valueFormatter: function (params) {
+ if (params.value) {
+ return dayjs(params?.value).format('YYYY.MM.DD')
+ } else {
+ return null
+ }
+ },
+ cellStyle: { textAlign: 'center' },
+ },
+ {
+ field: 'createDatetime',
+ headerName: getMessage('stuff.gridHeader.createDatetime'),
+ valueFormatter: function (params) {
+ if (params.value) {
+ return dayjs(params?.value).format('YYYY.MM.DD')
+ } else {
+ return null
+ }
+ },
+ cellStyle: { textAlign: 'center' },
+ },
+ ],
+ gridCount: 0,
+ })
+
+ //๊ทธ๋ฆฌ๋ ๋๋ธํด๋ฆญ
+ const getCellDoubleClicked = (event) => {
+ if (event.column.colId === 'objectNo') {
+ return
+ } else {
+ console.log(' ์์ธ์ด๋::::::::', event.data)
+ if (event.data.objectNo) {
+ router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`)
+ }
+ }
+ }
+
+ //๊ทธ๋ฆฌ๋ ์ฒดํฌ๋ฐ์ค ์ ํ์
+ const getSelectedRowdata = (data) => {
+ setSelectedRowData(data)
+ setSelectedRowDataCount(data.length)
+ }
+
+ //๋ฌผ๊ฑด์ญ์
+ const fnDeleteRowData = (data) => {
+ console.log('๋ฌผ๊ฑด์ญ์ :::::::::::')
+ if (data.length === 0) {
+ return alert('์ญ์ ํ ๋ฐ์ดํฐ๋ฅผ ์ ํํ์ธ์')
+ }
+ let errCount = 0
+ data.forEach((cell) => {
+ if (!cell.objectNo) {
+ if (errCount === 0) {
+ alert('๋ฌผ๊ฑด์ ๋ณด๊ฐ ์๋ ํ๋ง ์ญ์ ๋ฉ๋๋ค')
+ }
+ errCount++
+ }
+ })
+
+ async function fetchDelete(data) {
+ console.log('๋ฌผ๊ฑด์ญ์ APIํธ์ถ!!!!!!!!!', data)
+ //ํ์ถ๊ฐ๋ง๊ณ api๋ฐ์ดํฐ๋ง ๋ณด๋
+ // let newData = data.filter((item) => item.company != null)
+ // console.log('์ญ์ ์ ์ ์ก๋๋ ๋ฐ์ดํ::', newData)
+ // await del({ url: '', data:newData })
+ await get({ url: 'https://www.ag-grid.com/example-assets/space-mission-data.json' })
+ // try {
+ // const res = await del({url:'', data:newData})
+
+ // if(!res || res.length === 0) {
+
+ // } else {
+ fetchData()
+ // }
+ // } catch (error) {
+ // console.error('Data Delete error:', error);
+ // }
+ }
+
+ // ์ญ์ API ์๋ฃ ํ fetchData Apiํธ์ถ
+ async function fetchData() {
+ console.log('๋ฌผ๊ฑด์ญ์ ํ ์กฐํAPIํธ์ถ!!!!!!!!!!!!!', stuffSearchParams)
+ const data = await get({ url: 'https://www.ag-grid.com/example-assets/space-mission-data.json' })
+ setGridProps({ ...gridProps, gridData: data, count: data.length })
+ setGridCount(data.length)
+ //data.length = 10
+ //setGridProps({ ...gridProps, gridData: data, count: data.length-1})
+ //setGridCount(data.length - 1 )
+ }
+
+ if (errCount === 0) {
+ // console.log('errCount::::::::', errCount)
+ fetchDelete(data)
+ // fetchData()
+ } else {
+ alert('๋ฌผ๊ฑด์ ๋ณด๊ฐ ์๋ ํ๋ง ์ ํํด์ฃผ์ธ์')
+ }
+ }
+
+ //ํ์ถ๊ฐ
+ let newCount = 0
+ const addRowItems = () => {
+ // console.log('girdRef::::::', gridRef.current.api)
+ const newItems = [
+ {
+ mission: newCount + 1,
+ successful: true,
+ },
+ ]
+ gridRef.current.api.applyTransaction({
+ add: newItems,
+ addIndex: newCount,
+ })
+ newCount++
+ }
+
+ //ํ์ญ์
+ const removeRowItems = () => {
+ // console.log('selectedRowData::', selectedRowData)
+ let errCount = 0
+ selectedRowData.forEach((cell) => {
+ if (!cell.company) {
+ let newSelectedRowData = selectedRowData.filter((item) => item.company == null)
+ gridRef.current.api.applyTransaction({ remove: newSelectedRowData })
+ } else {
+ if (errCount === 0) {
+ alert('ํ์ถ๊ฐ๋ก ์ถ๊ฐ ํ ํ๋ง ์ญ์ ๋ฉ๋๋ค.')
+ }
+ errCount++
+ }
+ })
+ }
+
+ // ์ง์
์ ๊ทธ๋ฆฌ๋ ๋ฐ์ดํฐ ์กฐํ
+ useEffect(() => {
+ if (stuffSearchParams?.code === 'S') {
+ const params = {
+ schObjectNo: '',
+ schSaleStoreId: '',
+ schAddress: '',
+ schObjectName: '',
+ schSaleStoreName: '',
+ schSpecDateYn: '',
+ schReceiveUser: '',
+ schDispCompanyName: '',
+ schDateType: 'U',
+ schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
+ schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
+ startRow: (curPage - 1) * size + 1,
+ endRow: curPage * size,
+ }
+
+ async function fetchData() {
+ console.log('ํ๋ฉด์ง์
:::::::::::::', params)
+ console.log('ํ์ฌํ์ด์ง::::::', curPage)
+ console.log('ํ์ด์ง๋น ๊ฒ์๋ฌผ์::::::', size)
+
+ //api์ ๋๊ธธ๊ฐ startRow, endRow
+ // let startRow
+ // let endRow
+ // startRow = (curPage - 1) * size + 1
+ // endRow = curPage * size
+ // console.log('startrow::', startRow)
+ // console.log('endRow::', endRow)
+
+ // let curPage
+ // let totalpage
+ // let totalCount
+ // let size
+ // let pageCount
+
+ const apiUrl = `/api/object/v1.0/object?saleStoreId=201TES01&${queryStringFormatter(params)}`
+
+ await get({
+ url: apiUrl,
+ }).then((res) => {
+ if (res.length > 0) {
+ console.log('API๊ฒฐ๊ณผ:::::::', res)
+ setGridProps({ ...gridProps, gridData: res, count: res.length })
+ setGridCount(res.length)
+ }
+ })
+ }
+ fetchData()
+ }
+ }, [])
+
+ useEffect(() => {
+ if (stuffSearchParams?.code === 'E') {
+ console.log('์กฐํ ๋๋ฟ์๋ ::::::::::::::', stuffSearchParams)
+ async function fetchData() {
+ const apiUrl = `/api/object/v1.0/object?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}`
+ await get({ url: apiUrl }).then((res) => {
+ console.log('API๊ฒฐ๊ณผ:::::::', res)
+ setGridProps({ ...gridProps, gridData: res, count: res.length })
+ setGridCount(res.length)
+ })
+ }
+ fetchData()
+ }
+ }, [stuffSearchParams])
+
return (
<>
-
Management Stuff
+
+ ๋ฌผ๊ฑด๋ชฉ๋ก
+
+ ์ ์ฒด : {gridCount} // ์ ํ : {selectedRowDataCount}
+
+
+ {/* */}
+ {/*
+ */}
+
+
+
+
+
>
)
}
diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx
new file mode 100644
index 00000000..ed15d729
--- /dev/null
+++ b/src/components/management/StuffDetail.jsx
@@ -0,0 +1,475 @@
+'use client'
+
+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 Link from 'next/link'
+import { get } from '@/lib/Axios'
+import { queryStringFormatter } from '@/util/common-utils'
+import dayjs from 'dayjs'
+import { useForm } from 'react-hook-form'
+export default function StuffDetail() {
+ const router = useRouter()
+ const searchParams = useSearchParams()
+
+ //form
+ const formInitValue = {
+ // ๋ฌผ๊ฑด๋ฒํธ T...(์์) R...(์ง์ง)
+ dispCompanyName: '', //๋ด๋น์
+ objectStatusId: '0', //๋ฌผ๊ฑด๊ตฌ๋ถ(์ ์ถ:0 ๊ธฐ์ถ : 1)
+ objectName: '', //๋ฌผ๊ฑด๋ช
+ objectNameOmit: '', //๊ฒฝ์นญ์ ํ
+ objectNameKana: '', //๋ฌผ๊ฑด๋ช
ํ๋ฆฌ๊ฐ๋
+ saleStoreId: '', //ํ๋งค์ ID
+ saleStoreName: '', //ํ๋งค์ ๋ช
+ zipNo: '', //์ฐํธ๋ฒํธ
+ prefId: '', //๋๋๋ถํ
+ address: '', //์ฃผ์
+ powerSimArea: '', //๋ฐ์ ๋์๋ฎฌ๋ ์ด์
์ง์ญ
+ windSpeed: '', //๊ธฐ์คํ์
+ snowCover: '', //์์ง์ ์ค๋
+ coldAreaChk: false, //ํ๋ญ์ง๋์ฑ
์ํ
+ surfaceType: '', //๋ฉด์กฐ๋๊ตฌ๋ถ(โ
ขใปโ
ฃ / โ
ก)
+ saltAreaChk: false, //์ผํด์ง์ญ์ฉ์์ดํ
์ฌ์ฉ
+ installHeight: '', //์ค์น๋์ด
+ powerConTerms: '', //๊ณ์ฝ์กฐ๊ฑด
+ remark: '', //๋ฉ๋ชจ
+ tempFlag: 'T', //์์์ ์ฅ(1) ์ ์ฅ(0)
+ }
+ const { register, setValue, getValues, handleSubmit, resetField, control, watch } = useForm({
+ defaultValues: formInitValue,
+ })
+
+ const form = { register, setValue, getValues, handleSubmit, resetField, control, watch }
+
+ const [receiveUser, setReceiveUser] = useState('') //๋ด๋น์
+ const [name2, setName2] = useState('') //๋ฌผ๊ฑด๋ช
+ const [name3, setName3] = useState('') //๋ฌผ๊ฑด๋ช
ํ๋ฆฌ๊ฐ๋
+ const [zipCode, setZipCode] = useState('') //์ฐํธ๋ฒํธ
+ const [name5, setName5] = useState('') //์์ง์ ์ค๋
+ const [gubun, setGubun] = useState('NEW') //์ ์ถ ๊ธฐ์ถ
+ const [sel, setSel] = useState('') //๊ฒฝ์นญ์ ํ
+ const [sel2, setSel2] = useState('') //๋ฐ์ ๋์๋ฎฌ๋ ์ด์
์ง์ญ
+ const [sel3, setSel3] = useState('') //๊ธฐ์คํ์
+ const [sel4, setSel4] = useState('') //์ค์น๋์ด
+
+ const [errors, setErrors] = useState({})
+ const [isFormValid, setIsFormValid] = useState(false) //์์์ ์ฅ, ์ง์ง์ ์ฅ ๋ฒํผ ์ปจํธ๋กค
+ const [testSelOption, setTestSelOption] = useState([]) // ํ
์คํธ์ฉ
+ const [autoSelectValue, setAutoSelectValue] = useState('') //ํ๋งค์ ๋ช
์๋์์ฑ
+ const [buttonValid, setButtonValid] = useState(false) //์ฃผ์๊ฒ์ ํ์ฑํ ์ปจํธ๋กค
+ const [isSelected, setIsSelected] = useState(false) //ํ๋ญ์ง๋์ฒต ์ฒดํฌ๋ฐ์ค
+ const [isSelected2, setIsSelected2] = useState(false) //์ผํด์ง์ญ์ฉ์์ดํ
์ฌ์ฉ ์ฒดํฌ๋ฐ์ค
+ const [gubun2, setGubun2] = useState('1') //๋ฉด์กฐ๋๊ตฌ๋ถ ๋ผ๋์ค
+ const [gubun3, setGubun3] = useState('A') //๊ณ์ฝ์กฐ๊ฑด ๋ผ๋์ค
+ const [memo, setMemo] = useState('') //๋ฉ๋ชจ
+ const objectNo = searchParams.get('objectNo') //url์์ ๋ฌผ๊ฑด๋ฒํธ ๊บผ๋ด์ ๋ฐ๋ก set
+
+ // const [address1, setAddress1] = useState('') //์ฐํธAPI๋ฆฌํด ๋๋๋ถํ๋ช
+ // const [address2, setAddress2] = useState('') //์ฐํธAPI๋ฆฌํด ์๊ตฌ์ ์ด๋ช
+ // const [address3, setAddress3] = useState('') //์ฐํธAPI๋ฆฌํด ๋ง์ ์ง์ญ๋ช
+ // const [prefCode, setPrefCode] = useState(1) //์ฐํธAPI prefcode
+
+ const [editMode, setEditMode] = useState('NEW')
+ const [detailData, setDetailData] = useState({})
+
+ useEffect(() => {
+ // console.log('์์ธํ๋ฉด์ง์
:::::::::', searchParams.get('objectNo'))
+ console.log('๋ฌผ๊ฑด๋ฒํธ::::', objectNo)
+
+ if (objectNo) {
+ // console.log('์์ธ::', objectNo)
+ setEditMode('EDIT')
+ if (objectNo.substring(0, 1) === 'R') {
+ setIsFormValid(true)
+ }
+ //์ผ๋จ ํ๋๋ฒํธ ๋ฌด์กฐ๊ฑด 1๋ก
+ //API ํธ์ถ
+ get({ url: `/api/object/v1.0/object/${objectNo}/1` }).then((res) => {
+ if (res != null) {
+ // console.log('res:::::::', res)
+ setDetailData(res)
+ }
+ })
+ }
+ }, [objectNo])
+
+ useEffect(() => {
+ // validateForm()
+ }, [receiveUser, name2, name3, gubun, sel, autoSelectValue, zipCode, sel2, sel3, name5, sel4])
+
+ // ์ฐํธ๋ฒํธ ์ซ์๋ง ์ฒดํฌ
+ const _zipNo = watch('zipNo')
+ useEffect(() => {
+ console.log('์ค์๊ฐ์ด๋:::::', _zipNo)
+ if (_zipNo !== '' && _zipNo.length === 7 && !_zipNo.match(/\D/g)) {
+ console.log('๋ฒจ๋ฆฌํต๊ณผํ๊ตฐ')
+ setButtonValid(true)
+ } else {
+ setButtonValid(false)
+ }
+ }, [_zipNo])
+
+ // ์์ง์ ์ค๋ ์ซ์๋ง
+ const textTypeHandler2 = (e) => {
+ if (!e.target.value.match(/[^0-9]/g)) {
+ setName5(e.target.value)
+ }
+ }
+ const validateForm = () => {
+ let errors = {}
+
+ if (!receiveUser || receiveUser.trim().length === 0) {
+ errors.receiveUser = '๋ด๋น์ is required.'
+ }
+
+ if (!name2 || name2.trim().length === 0) {
+ errors.name2 = '๋ฌผ๊ฑด๋ช
is required.'
+ }
+
+ if (!name3 || name3.trim().length === 0) {
+ errors.name3 = '๋ฌผ๊ฑด๋ช
ํ๋ฆฌ๊ฐ๋ is required.'
+ }
+
+ if (!sel) {
+ errors.sel = '๊ฒฝ์นญ์ ํ is required'
+ }
+
+ if (!sel2) {
+ errors.sel2 = '๋ฐ์ ๋์๋ฎฌ๋ ์ด์
์ง์ญ is required'
+ }
+
+ if (!sel3) {
+ errors.sel3 = '๊ธฐ์คํ์ is required'
+ }
+
+ if (!sel4) {
+ errors.sel4 = '์ค์น๋์ด is required'
+ }
+
+ if (!autoSelectValue) {
+ errors.autoSelectValue = 'ํ๋งค์ ID์๋์์ฑ is required'
+ }
+
+ if (!zipCode || zipCode.length != 7) {
+ errors.zipCode = '์ฐํธ๋ฒํธ is required.'
+ setButtonValid(true)
+ } else {
+ setButtonValid(false)
+ }
+
+ if (!name5) {
+ errors.name5 = '์์ง์ ์ค๋ is required.'
+ }
+
+ console.log('errors::', errors)
+ setErrors(errors)
+ setIsFormValid(Object.keys(errors).length === 0)
+ }
+
+ // ์ฐํธ๋ฒํธ API
+ const onSearchPostNumber = () => {
+ const params = {
+ zipcode: _zipNo,
+ }
+ get({ url: `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter(params)}` }).then((res) => {
+ console.log('์ฐํธAPI RES::::::::', res)
+ //7830060
+ if (res.status === 200) {
+ if (res.results?.length > 0) {
+ // setAddress1(res.results[0].address1)
+ // setAddress2(res.results[0].address2)
+ // setAddress3(res.results[0].address3)
+ // setPrefCode(res.results[0].prefcode)
+ // prefId: '', //๋๋๋ถํ
+ // address: '', //์ฃผ์
+ form.setValue('prefId', res.results[0].prefcode)
+ form.setValue('address', res.results[0].address2 + res.results[0].address3)
+ } else {
+ alert('๋ฑ๋ก๋ ์ฐํธ๋ฒํธ์์ ์ฃผ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ๋ค์ ์
๋ ฅํด์ฃผ์ธ์.')
+ }
+ } else {
+ alert(res.message)
+ }
+ })
+ }
+
+ const onTempSave = () => {
+ console.log('์์์ ์ฅ::', isFormValid)
+ }
+
+ const onSave = () => {
+ console.log('์ง์ง์ ์ฅisFormValid:::', isFormValid)
+ }
+
+ const moveList = () => {
+ router.push('/management/stuff')
+ }
+
+ const changeAddress2 = (e) => {
+ console.log('e:::::::', e.target.value)
+ }
+
+ //ํ์๊ฐ ๋ค ์
๋ ฅํ์๋
+ const onValid = (data) => {
+ console.log('data::::::', data)
+ const formData = form.getValues()
+ //console.log('formData::::', formData)
+ const _dispCompanyName = watch('dispCompanyName')
+ const _objectStatusId = watch('objectStatusId')
+ const _objectNameOmit = watch('objectNameOmit')
+ const _zipno = watch('zipno')
+ console.log(_dispCompanyName)
+ console.log(_objectStatusId)
+ console.log(_objectNameOmit)
+ console.log(_zipno)
+ }
+
+ //ํ์๊ฐ ์๋ฃ์์๋
+ const onInvalid = (errors) => {
+ console.log('์คํจ', errors)
+ }
+
+ return (
+ <>
+ {(editMode === 'NEW' && (
+
+ )) ||
์์ธ:::::::::::
}
+
+ {/*
+
+ ๋ฌผ๊ฑด๋ฒํธ
+ {objectNo}
+
+
+ ์ฌ์ํ์ ์ผ
+ {detailData?.specDate ? dayjs(detailData.specDate).format('YYYY.MM.DD') : null}
+
+
+ ๊ฐฑ์ ์ผ์
+
+ {detailData?.lastEditDatetime
+ ? dayjs(detailData.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')
+ : detailData?.createDatetime
+ ? dayjs(detailData.createDatetime).format('YYYY.MM.DD HH:mm:ss')
+ : null}
+
+
+
+ ๋ฑ๋ก์ผ
+
+
+
*/}
+ {/*
(*ํ์ ์
๋ ฅํญ๋ชฉ)
+
+
+ setName2(e.target.value)} />
+
+
+
+
+
+ ๋ฌผ๊ฑด๋ช
ํ๋ฆฌ๊ฐ๋
+ setName3(e.target.value)} />
+
+
*/}
+ {/*
+
ํ๋งค์ ๋ช
/ID *
+
+
+ {(option) => {option.name}}
+
+
+
*/}
+ {/*
+ ์ฐํธ๋ฒํธ*
+
+
+ *์ฐํธ๋ฒํธ 7์๋ฆฌ๋ฅผ ์
๋ ฅํ ํ, ์ฃผ์๊ฒ์ ๋ฒํผ์ ํด๋ฆญํด ์ฃผ์ญ์์ค
+
*/}
+ {/*
+ ๋๋๋ถํ / ์ฃผ์*
+
+
*/}
+ {/*
+ ๋ฐ์ ๋์๋ฎฌ๋ ์ด์
์ง์ญ*
+
+
+
+ ๊ธฐ์คํ์*
+
+ m/s์ดํ
+
+
+ ์์ง์ ์ค๋*
+ cm
+
+ ํ๋ญ์ง๋์ฑ
์ํ
+
+
*/}
+ {/*
+ ๋ฉด์กฐ๋๊ตฌ๋ถ*
+ {
+ setGubun2(e.target.value)
+ }}
+ />
+
+ {
+ setGubun2(e.target.value)
+ }}
+ />
+
+
+ ์ผํด์ง์ญ์ฉ์์ดํ
์ฌ์ฉ
+
+
+
+ ์ค์น๋์ด*
+
+ m
+
+
+ ๊ณ์ฝ์กฐ๊ฑด
+ {
+ setGubun3(e.target.value)
+ }}
+ />
+
+ {
+ setGubun3(e.target.value)
+ }}
+ />
+
+
+
+ ๋ฉ๋ชจ
+
+
+ {!isFormValid ? (
+ <>
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+
+
+ */}
+ >
+ )
+}
diff --git a/src/components/management/StuffQGrid.jsx b/src/components/management/StuffQGrid.jsx
new file mode 100644
index 00000000..4fd6c42d
--- /dev/null
+++ b/src/components/management/StuffQGrid.jsx
@@ -0,0 +1,117 @@
+import React from 'react'
+import { useCallback, useEffect, useMemo, useState } from 'react'
+import { AgGridReact } from 'ag-grid-react'
+
+import 'ag-grid-community/styles/ag-grid.css'
+import 'ag-grid-community/styles/ag-theme-quartz.css'
+
+export default function StuffQGrid(props) {
+ const { gridData, gridColumns, isPageable = true, count, gridRef } = props
+ /**
+ * ํ ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ ๋ useState์ ์ฌ์ฉํ์ฌ ๋ ๋๋ง ์ ๋ฐ์ ๊ฑธ์ณ ์ผ๊ด๋ ๋ฐฐ์ด ์ฐธ์กฐ๋ฅผ ์ ์งํ๋ ๊ฒ์ด ์ข์ต๋๋ค
+ */
+ const [rowData, setRowData] = useState(null)
+
+ /**
+ * Column Definitions๋ฅผ ์ค์ ํ ๋๋ useMemo ๋๋ useState๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๋ ๊ฐ์ ์ผ๊ด๋ ์ฐธ์กฐ๋ฅผ ์ ์งํ์ญ์์ค.
+ * ์์ฉ ํ๋ก๊ทธ๋จ์ด Column Definitions๋ฅผ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ์๋ ๋ ๋๋ง ๊ฐ์ ์ผ๊ด๋ ์ฐธ์กฐ๋ฅผ ์ ์งํ๋ ค๋ฉด useMemo ๋๋ useState๋ฅผ ์ฌ์ฉํ์ญ์์ค.
+ */
+ const [colDefs, setColDefs] = useState(
+ gridColumns ?? [
+ { field: 'mission', filter: true },
+ { field: 'company' },
+ { field: 'location' },
+ { field: 'date' },
+ { field: 'price', valueFormatter: (params) => `โฉ ${params.value.toLocaleString()}` },
+ { field: 'successful' },
+ { field: 'rocket' },
+ ],
+ )
+
+ /**
+ * defaultColDef ์์ฑ์ ์ ๊ณตํ ๋ ์ด ์ธ๋ผ์ธ ๋๋ ๊ตฌ์ฑ ์์์ ๋จ์ ๊ฐ์ฒด๋ก ์ ์ํ์ง ๋ง์ญ์์ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ชจ๋ ๋ ๋๋ง์์ ์ ์ธ์คํด์ค๊ฐ ์์ฑ๋ฉ๋๋ค.
+ * ๋์ or useState ๋ฅผ ์ฌ์ฉํ์ฌ useMemo ๋ ๋ ๊ฐ์ ์ผ๊ด๋ ์ฐธ์กฐ๊ฐ ์ ์ง๋๋๋ก ํฉ๋๋ค.
+ */
+ const defaultColDef = useMemo(() => {
+ return {
+ filter: false,
+ flex: 1,
+ sortable: false,
+ suppressMovable: true,
+ resizable: false,
+ suppressSizeToFit: false,
+ headerClass: 'centered', //_test.scss์ ์ถ๊ฐ ํ
์คํธ
+ }
+ }, [])
+
+ /**
+ * ๋จ์ ์ ํ(string, boolean ๋ฐ number)์ ์์ฑ์ ๋ ๋๋ง ๊ฐ์ ๊ฐ์ผ๋ก ๋น๊ต๋๋ฏ๋ก ํํฌ๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๋ค.
+ */
+ const rowBuffer = 100
+
+ /**
+ * ๋ชจ๋ ๋ ๋๋ง์์ ๊ทธ๋ฆฌ๋ ์ํ๋ฅผ ์ฌ์ค์ ํ์ง ์๋๋ก useCallback์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
+ * api๋ฐ์ดํ ํด๋น ์ปฌ๋ผ์ ๋ฐ๋ผ ๋ก์ฐ ์ฒดํฌ๋ฐ์ค ์ฒดํฌ ๊ฐ๋ฅ์ฌ๋ถ ๋ฑ ์ปจํธ๋กค
+ */
+ const isRowSelectable = useCallback(
+ (params) => {
+ return !!params.data
+ },
+ [count],
+ )
+
+ // ์ฒดํฌ๋ฐ์ค ์ฒดํฌ์
+ const onSelectionChanged = useCallback((event) => {
+ props.getSelectedRowdata(event.api.getSelectedRows())
+ }, [])
+
+ //๋๋ธํด๋ฆญ
+ const onCellDoubleClicked = useCallback((event) => {
+ // if (event.column.colId === 'company') {
+ // return
+ // } else {
+ props.getCellDoubleClicked(event)
+ // }
+ }, [])
+
+ //์ปจํ
์ธ ์ ๋ฐ๋ผ ์ปฌ๋ผ๋์ด ์๋์กฐ์
+ const autoSizeStrategy = useMemo(() => {
+ return {
+ type: 'fitCellContents',
+ }
+ }, [])
+
+ const onGridReady = useCallback((event) => {
+ // console.log('event:::', event)
+ // ํค๋ ์ฌ์ด์ฆ ์กฐ์ ์ปฌ๋ผ์ width๊ฐ์ผ๋ก ๊ณ์ฐ
+ event.api.sizeColumnsToFit()
+ }, [])
+
+ // Fetch data & update rowData state
+ useEffect(() => {
+ gridData ? setRowData(gridData) : ''
+ }, [gridData])
+
+ return (
+
+
๋ฌผ๊ฑด ๋ชฉ๋ก์ด ์์ต๋๋ค.'}
+ />
+
+ )
+}
diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx
new file mode 100644
index 00000000..f0d665d0
--- /dev/null
+++ b/src/components/management/StuffSearchCondition.jsx
@@ -0,0 +1,264 @@
+'use client'
+
+import React, { useEffect } from 'react'
+import { useState } from 'react'
+import { Input, RadioGroup, Radio, Button } from '@nextui-org/react'
+import RangeDatePicker from '@/components/common/datepicker/RangeDatePicker'
+import { useRecoilState, useResetRecoilState } from 'recoil'
+import { stuffSearchState } from '@/store/stuffAtom'
+import dayjs from 'dayjs'
+import isLeapYear from 'dayjs/plugin/isLeapYear' // ์ค๋
ํ๋จ ํ๋ฌ๊ทธ์ธ
+dayjs.extend(isLeapYear)
+import Link from 'next/link'
+export default function StuffSearchCondition() {
+ //๋ฌ๋ ฅ props ๊ด๋ จ ๋ ์ง ์
ํ
+ const [dateRange, setDateRange] = useState([dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), dayjs(new Date()).format('YYYY-MM-DD')])
+ const [startRangeDate, endRangeDate] = dateRange
+
+ const rangeDatePickerProps = {
+ startRangeDate, //์์์ผ
+ endRangeDate, //์ข
๋ฃ์ผ
+ setDateRange,
+ }
+
+ //์ฌ๊ธฐ์ ์ ํํ ๊ฒ์์กฐ๊ฑด๋ค์ recoil๋ก ๊ด๋ฆฌ
+ const resetStuffRecoil = useResetRecoilState(stuffSearchState)
+ const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
+ const [objectNo, setObjectNo] = useState('') //๋ฌผ๊ฑด๋ฒํธ
+ const [saleStoreId, setSaleStoreId] = useState('') //ํ๋งค๋๋ฆฌ์ ID
+ 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)
+
+ // ์กฐํ
+ const onSubmit = () => {
+ let diff = dayjs(endRangeDate).diff(startRangeDate, 'day')
+ if (diff > 366) {
+ return alert('์ต๋1๋
์กฐํ ๊ฐ๋ฅํฉ๋๋ค.')
+ }
+ setStuffSearch({
+ schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
+ schSaleStoreId: stuffSearch?.schSaleStoreId ? stuffSearch.schSaleStoreId : saleStoreId,
+ 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,
+ schFromDt: dayjs(startRangeDate).format('YYYY-MM-DD'),
+ schToDt: dayjs(endRangeDate).format('YYYY-MM-DD'),
+ code: 'E',
+ })
+ }
+
+ //์ด๊ธฐํ
+ const resetRecoil = () => {
+ setObjectNo('')
+ setSaleStoreId('')
+ setAddress('')
+ setobjectName('')
+ setSaleStoreName('')
+ setSpecDateYn('')
+ setReceiveUser('')
+ setDispCompanyName('')
+ setDateType('U')
+ setDateRange([dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), dayjs(new Date()).format('YYYY-MM-DD')])
+ resetStuffRecoil()
+ }
+
+ //x๋ก ๋ ์ง ๋น์ ์๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์
ํ
+ useEffect(() => {
+ if (!startRangeDate && !endRangeDate) {
+ setDateRange([dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), dayjs(new Date()).format('YYYY-MM-DD')])
+ }
+ }, [startRangeDate, endRangeDate])
+
+ useEffect(() => {
+ setDateRange([
+ stuffSearch?.schFromDt ? stuffSearch.schFromDt : dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
+ stuffSearch?.schToDt ? stuffSearch.schToDt : dayjs(new Date()).format('YYYY-MM-DD'),
+ ])
+ }, [stuffSearch])
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+ {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', address: 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 })
+ }}
+ />
+
+ )
+ } 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/components/ui/ObjectPlacement.jsx b/src/components/ui/ObjectPlacement.jsx
new file mode 100644
index 00000000..f7a73a5c
--- /dev/null
+++ b/src/components/ui/ObjectPlacement.jsx
@@ -0,0 +1,146 @@
+import React, { useCallback, useEffect, useRef, useState } from 'react'
+import { Button, Input } from '@nextui-org/react'
+import { useRecoilState, useSetRecoilState } from 'recoil'
+import { modalState } from '@/store/modalAtom'
+import { fabric } from 'fabric'
+import { QPolygon } from '@/components/fabric/QPolygon'
+import { modeState, objectPlacementModeState } from '@/store/canvasAtom'
+import { BATCH_TYPE, INPUT_TYPE } from '@/common/common'
+
+const ObjectPlacement = ({ canvas }) => {
+ const [open, setOpen] = useRecoilState(modalState)
+ const [mode, setMode] = useRecoilState(modeState)
+ const [objectPlacementMode, setObjectPlacementModeState] = useRecoilState(objectPlacementModeState)
+ const [width, setWidth] = useState(0)
+ const [height, setHeight] = useState(0)
+ const [areaBoundary, setAreaBoundary] = useState(true)
+
+ // opening or shadow ๊ฐ๊ตฌ / ๊ทธ๋ฆผ์
+ const [batchType, setBatchType] = useState(BATCH_TYPE.OPENING)
+
+ // free or dimension ํ๋ฆฌ / ์น์
+ const [inputType, setInputType] = useState(INPUT_TYPE.FREE)
+
+ const handleSave = () => {
+ setMode(batchType)
+ setOpen(false)
+ }
+
+ return (
+
+
+
+
+
+
+
๊ฐ๊ตฌ ยท ๊ทธ๋ฆผ์ ๋ฐฐ์น
+
+
+
+
+
+
+
+
+
+
+
์ค์
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default ObjectPlacement
diff --git a/src/components/ui/SurfaceShape.jsx b/src/components/ui/SurfaceShape.jsx
index ac30138f..706729a3 100644
--- a/src/components/ui/SurfaceShape.jsx
+++ b/src/components/ui/SurfaceShape.jsx
@@ -13,7 +13,7 @@ import { getIntersectionPoint } from '@/util/canvas-util'
* @constructor
*/
export const SurfaceShapeModal = ({ canvas }) => {
- const [type, setType] = useState(0)
+ const [type, setType] = useState(1)
const setOpen = useSetRecoilState(modalState)
const fontSize = useRecoilValue(fontSizeState)
//์ง๋ถ์ฌ
diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js
index 043a561f..044a5e58 100644
--- a/src/hooks/useCanvas.js
+++ b/src/hooks/useCanvas.js
@@ -4,7 +4,7 @@ import { fabric } from 'fabric'
import { actionHandler, anchorWrapper, polygonPositionHandler } from '@/util/canvas-util'
import { useRecoilState } from 'recoil'
-import { canvasSizeState, fontSizeState } from '@/store/canvasAtom'
+import { canvasSizeState, canvasState, fontSizeState } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
import { QPolygon } from '@/components/fabric/QPolygon'
import { defineQLine } from '@/util/qline-utils'
@@ -14,7 +14,7 @@ import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import { post } from '@/lib/Axios'
export function useCanvas(id) {
- const [canvas, setCanvas] = useState()
+ const [canvas, setCanvas] = useRecoilState(canvasState)
const [isLocked, setIsLocked] = useState(false)
const [history, setHistory] = useState([])
const [backImg, setBackImg] = useState()
@@ -138,12 +138,24 @@ export function useCanvas(id) {
if (canvas) {
if (canvas?._objects.length > 0) {
const poppedObject = canvas?._objects.pop()
+ const group = []
+ group.push(poppedObject)
+
+ if (poppedObject.parent || poppedObject.parentId) {
+ canvas
+ ?.getObjects()
+ .filter((obj) => obj.parent === poppedObject.parent || obj.parentId === poppedObject.parentId || obj === poppedObject.parent)
+ .forEach((obj) => {
+ group.push(obj)
+ canvas?.remove(obj)
+ })
+ }
setHistory((prev) => {
if (prev === undefined) {
- return poppedObject ? [poppedObject] : []
+ return poppedObject ? [group] : []
}
- return poppedObject ? [...prev, poppedObject] : prev
+ return poppedObject ? [...prev, group] : prev
})
canvas?.renderAll()
}
@@ -154,7 +166,13 @@ export function useCanvas(id) {
if (canvas && history) {
if (history.length > 0) {
setIsLocked(true)
- canvas?.add(history[history.length - 1])
+ if (Array.isArray(history[history.length - 1])) {
+ history[history.length - 1].forEach((obj) => {
+ canvas?.add(obj)
+ })
+ } else {
+ canvas?.add(history[history.length - 1])
+ }
const newHistory = history.slice(0, -1)
setHistory(newHistory)
}
@@ -449,7 +467,7 @@ export function useCanvas(id) {
/**
* cad ํ์ผ ์ฌ์ฉ์ ์ด๋ฏธ์ง ๋ก๋ฉ ํจ์
*/
- const handleCadImageLoad = (url) => {
+ const handleBackImageLoadToCanvas = (url) => {
console.log('image load url: ', url)
fabric.Image.fromURL(url, function (img) {
@@ -485,7 +503,7 @@ export function useCanvas(id) {
setCanvasBackgroundWithDots,
addCanvas,
removeMouseLines,
- handleCadImageLoad,
+ handleBackImageLoadToCanvas,
handleCadImageInit,
backImg,
setBackImg,
diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js
index d3d8cee6..d427b548 100644
--- a/src/hooks/useMode.js
+++ b/src/hooks/useMode.js
@@ -14,12 +14,14 @@ import { useRecoilState, useRecoilValue } from 'recoil'
import {
canvasSizeState,
+ canvasState,
compassState,
drewRoofCellsState,
fontSizeState,
guideLineState,
horiGuideLinesState,
modeState,
+ objectPlacementModeState,
roofPolygonArrayState,
roofPolygonPatternArrayState,
roofState,
@@ -34,7 +36,7 @@ import { QPolygon } from '@/components/fabric/QPolygon'
import offsetPolygon from '@/util/qpolygon-utils'
import { isObjectNotEmpty } from '@/util/common-utils'
import * as turf from '@turf/turf'
-import { Mode } from '@/common/common'
+import { INPUT_TYPE, Mode } from '@/common/common'
export function useMode() {
const [mode, setMode] = useRecoilState(modeState)
@@ -42,7 +44,7 @@ export function useMode() {
const historyPoints = useRef([])
const historyLines = useRef([])
const startPoint = useRef()
- const [canvas, setCanvas] = useState(null)
+ const [canvas, setCanvas] = useRecoilState(canvasState)
const [zoom, setZoom] = useState(100)
const [fontSize] = useRecoilState(fontSizeState)
const [sortedArray, setSortedArray] = useRecoilState(sortedPolygonArray)
@@ -74,13 +76,14 @@ export function useMode() {
const [horiGuideLines, setHoriGuideLines] = useRecoilState(horiGuideLinesState)
const [vertGuideLines, setVertGuideLines] = useRecoilState(vertGuideLinesState)
+ const [objectPlacementMode, setObjectPlacementModeState] = useRecoilState(objectPlacementModeState)
+
useEffect(() => {
// if (!canvas) {
// canvas?.setZoom(0.8)
// return
// }
if (!canvas) return
- setCanvas(canvas)
canvas?.off('mouse:out', removeMouseLines)
canvas?.on('mouse:out', removeMouseLines)
canvas?.off('mouse:move')
@@ -104,11 +107,7 @@ export function useMode() {
}, [endPoint])
useEffect(() => {
- canvas?.off('mouse:out', removeMouseLines)
- canvas?.on('mouse:out', removeMouseLines)
changeMode(canvas, mode)
- canvas?.off('mouse:move')
- canvas?.on('mouse:move', drawMouseLines)
}, [mode, horiGuideLines, vertGuideLines])
useEffect(() => {
@@ -423,6 +422,17 @@ export function useMode() {
break
case 'adsorptionPoint':
canvas?.on('mouse:down', mouseEvent.adsorptionPoint)
+ break
+ case 'shadow':
+ canvas?.on('mouse:down', mouseEvent.shadowMode.down)
+ canvas?.on('mouse:move', mouseEvent.shadowMode.move)
+ canvas?.on('mouse:up', mouseEvent.shadowMode.up)
+ break
+ case 'opening':
+ canvas?.on('mouse:down', mouseEvent.openingMode.down)
+ canvas?.on('mouse:move', mouseEvent.openingMode.move)
+ canvas?.on('mouse:up', mouseEvent.openingMode.up)
+
break
case 'default':
canvas?.off('mouse:down')
@@ -587,10 +597,9 @@ export function useMode() {
const mouseAndkeyboardEventClear = () => {
canvas?.off('mouse:down')
- Object.keys(mouseEvent).forEach((key) => {
- canvas?.off('mouse:down', mouseEvent[key])
- document.removeEventListener('contextmenu', mouseEvent[key])
- })
+ canvas?.off('mouse:move')
+ canvas?.off('mouse:up')
+ canvas?.off('mouse:out')
Object.keys(keyboardEvent).forEach((key) => {
document.removeEventListener('keydown', keyboardEvent[key])
@@ -674,8 +683,8 @@ export function useMode() {
const changeMode = (canvas, mode) => {
mouseAndkeyboardEventClear()
+ addCommonMouseEvent()
setMode(mode)
- setCanvas(canvas)
// mode๋ณ ์ด๋ฒคํธ ๋ณ๊ฒฝ
@@ -713,6 +722,12 @@ export function useMode() {
}
}
+ // ๋ชจ๋ ๋ชจ๋์์ ์ฌ์ฉ๋๋ ๊ณตํต ์ด๋ฒคํธ ์ถ๊ฐ
+ const addCommonMouseEvent = () => {
+ canvas?.on('mouse:move', drawMouseLines)
+ canvas?.on('mouse:out', removeMouseLines)
+ }
+
const changeKeyboardEvent = (mode) => {
if (mode === Mode.EDIT) {
switch (mode) {
@@ -992,6 +1007,214 @@ export function useMode() {
canvas.add(circle)
canvas.renderAll()
},
+ //๋ฉด ํ์ ๋ฐฐ์น ๋ชจ๋
+ surfaceShapeMode: (o) => {},
+ // ๊ทธ๋ฆผ์ ๋ชจ๋
+ shadowMode: {
+ rect: null,
+ isDown: false,
+ origX: 0,
+ origY: 0,
+ down: (o) => {
+ if (mode !== Mode.SHADOW) return
+ mouseEvent.shadowMode.isDown = true
+ const pointer = canvas.getPointer(o.e)
+ mouseEvent.shadowMode.origX = pointer.x
+ mouseEvent.shadowMode.origY = pointer.y
+ mouseEvent.shadowMode.rect = new fabric.Rect({
+ fill: 'grey',
+ left: mouseEvent.shadowMode.origX,
+ top: mouseEvent.shadowMode.origY,
+ originX: 'left',
+ originY: 'top',
+ opacity: 0.3,
+ width: 0,
+ height: 0,
+ angle: 0,
+ transparentCorners: false,
+ })
+ canvas.add(mouseEvent.shadowMode.rect)
+ },
+ move: (e) => {
+ if (!mouseEvent.shadowMode.isDown) return
+ const pointer = canvas.getPointer(e.e)
+ if (mouseEvent.shadowMode.origX > pointer.x) {
+ mouseEvent.shadowMode.rect.set({ left: Math.abs(pointer.x) })
+ }
+ if (mouseEvent.shadowMode.origY > pointer.y) {
+ mouseEvent.shadowMode.rect.set({ top: Math.abs(pointer.y) })
+ }
+
+ mouseEvent.shadowMode.rect.set({ width: Math.abs(mouseEvent.shadowMode.origX - pointer.x) })
+ mouseEvent.shadowMode.rect.set({ height: Math.abs(mouseEvent.shadowMode.origY - pointer.y) })
+ },
+ up: (o) => {
+ mouseEvent.shadowMode.isDown = false
+ setMode(Mode.DEFAULT)
+ },
+ },
+ openingMode: {
+ rect: null,
+ isDown: false,
+ origX: 0,
+ origY: 0,
+ down: (o) => {
+ if (mode !== Mode.OPENING) return
+ const roofs = canvas?._objects.filter((obj) => obj.name === 'roof')
+ if (roofs.length === 0) {
+ alert('์ง๋ถ์ ๋จผ์ ๊ทธ๋ ค์ฃผ์ธ์')
+ setMode(Mode.DEFAULT)
+ return
+ }
+ const pointer = canvas.getPointer(o.e)
+ let selectRoof = null
+ roofs.forEach((roof) => {
+ if (roof.inPolygon({ x: pointer.x, y: pointer.y })) {
+ selectRoof = roof
+ }
+ })
+ if (!selectRoof) {
+ alert('์ง๋ถ ๋ด๋ถ์๋ง ์์ฑ ๊ฐ๋ฅํฉ๋๋ค.')
+ return
+ }
+ mouseEvent.openingMode.origX = pointer.x
+ mouseEvent.openingMode.origY = pointer.y
+ if (objectPlacementMode.inputType === INPUT_TYPE.FREE) {
+ mouseEvent.openingMode.isDown = true
+
+ mouseEvent.openingMode.rect = new fabric.Rect({
+ fill: 'white',
+ stroke: 'black',
+ strokeWidth: 1,
+ left: mouseEvent.openingMode.origX,
+ top: mouseEvent.openingMode.origY,
+ originX: 'left',
+ originY: 'top',
+ width: pointer.x - mouseEvent.openingMode.origX,
+ height: pointer.y - mouseEvent.openingMode.origY,
+ })
+ canvas.add(mouseEvent.openingMode.rect)
+ } else if (objectPlacementMode.inputType === INPUT_TYPE.DIMENSION) {
+ mouseEvent.openingMode.rect = new fabric.Rect({
+ fill: 'white',
+ stroke: 'black',
+ strokeWidth: 1,
+ left: mouseEvent.openingMode.origX,
+ top: mouseEvent.openingMode.origY,
+ originX: 'left',
+ originY: 'top',
+ width: Number(objectPlacementMode.width),
+ height: Number(objectPlacementMode.height),
+ })
+ canvas.add(mouseEvent.openingMode.rect)
+ canvas.off('mouse:move')
+ }
+ },
+ move: (e) => {
+ if (!mouseEvent.openingMode.isDown) return
+ const pointer = canvas.getPointer(e.e)
+ if (mouseEvent.openingMode.origX > pointer.x) {
+ mouseEvent.openingMode.rect.set({ left: Math.abs(pointer.x) })
+ }
+ if (mouseEvent.openingMode.origY > pointer.y) {
+ mouseEvent.openingMode.rect.set({ top: Math.abs(pointer.y) })
+ }
+
+ mouseEvent.openingMode.rect.set({ width: Math.abs(mouseEvent.openingMode.origX - pointer.x) })
+ mouseEvent.openingMode.rect.set({ height: Math.abs(mouseEvent.openingMode.origY - pointer.y) })
+ },
+ up: (o) => {
+ mouseEvent.openingMode.isDown = false
+
+ const { areaBoundary } = objectPlacementMode
+
+ //roof์ ๋ด๋ถ์ ์๋์ง ํ์ธ
+ if (!checkInsideRoof(mouseEvent.openingMode.rect)) {
+ setMode(Mode.DEFAULT)
+ }
+
+ // ์์ญ ๊ต์ฐจ์ธ์ง ํ์ธ
+ if (!areaBoundary) {
+ const isCross = checkCrossAreaBoundary(mouseEvent.openingMode.rect)
+ if (isCross) {
+ alert('์์ญ์ด ๊ต์ฐจ๋์์ต๋๋ค.')
+ canvas.remove(mouseEvent.openingMode.rect)
+ }
+ }
+
+ mouseEvent.openingMode.rect.set({ name: 'opening' })
+ setMode(Mode.DEFAULT)
+ },
+ },
+ }
+
+ const checkCrossAreaBoundary = (rect) => {
+ const openings = canvas?._objects.filter((obj) => obj.name === 'opening')
+ if (openings.length === 0) {
+ return false
+ }
+
+ const rectPoints = [
+ { x: rect.left, y: rect.top },
+ { x: rect.left, y: rect.top + rect.height },
+ { x: rect.left + rect.width, y: rect.top + rect.height },
+ { x: rect.left + rect.width, y: rect.top },
+ ]
+
+ const rect1Corners = {
+ minX: Math.min(...rectPoints.map((point) => point.x)),
+ maxX: Math.max(...rectPoints.map((point) => point.x)),
+ minY: Math.min(...rectPoints.map((point) => point.y)),
+ maxY: Math.max(...rectPoints.map((point) => point.y)),
+ }
+ let isCross = true
+ for (let i = 0; i < openings.length; i++) {
+ if (i !== 0 && isCross) {
+ break
+ }
+ const rect2 = openings[i]
+ const rect2Points = [
+ { x: rect2.left, y: rect2.top },
+ { x: rect2.left, y: rect2.top + rect2.height },
+ { x: rect2.left + rect2.width, y: rect2.top + rect2.height },
+ { x: rect2.left + rect2.width, y: rect2.top },
+ ]
+
+ const rect2Corners = {
+ minX: Math.min(...rect2Points.map((point) => point.x)),
+ maxX: Math.max(...rect2Points.map((point) => point.x)),
+ minY: Math.min(...rect2Points.map((point) => point.y)),
+ maxY: Math.max(...rect2Points.map((point) => point.y)),
+ }
+
+ // Check if one rectangle is to the left of the other
+ if (
+ rect1Corners.maxX < rect2Corners.minX ||
+ rect2Corners.maxX < rect1Corners.minX ||
+ rect1Corners.maxY < rect2Corners.minY ||
+ rect2Corners.maxY < rect1Corners.minY
+ ) {
+ isCross = false
+ continue
+ } else {
+ isCross = true
+ break
+ }
+ }
+
+ return isCross
+ }
+
+ const checkInsideRoof = (rect) => {
+ let result = true
+ const roofs = canvas?._objects.filter((obj) => obj.name === 'roof')
+ if (roofs.length === 0) {
+ alert('์ง๋ถ์ ๋จผ์ ๊ทธ๋ ค์ฃผ์ธ์')
+ canvas?.remove(rect)
+ return false
+ }
+
+ return result
}
const getInterSectPointByMouseLine = () => {
@@ -4896,7 +5119,6 @@ export function useMode() {
mode,
setMode,
changeMode,
- setCanvas,
handleClear,
zoomIn,
zoomOut,
diff --git a/src/lib/authActions.js b/src/lib/authActions.js
index 60fac21a..06c02ef0 100644
--- a/src/lib/authActions.js
+++ b/src/lib/authActions.js
@@ -27,6 +27,28 @@ export async function getSession() {
return session
}
+export async function setSession(data) {
+ const session = await getSession()
+
+ session.userId = data.userId
+ session.name = data.name
+ session.saleStoreId = data.saleStoreId
+ session.mail = data.mail
+ session.tel = data.tel
+ session.storeId = data.storeId
+ session.userNm = data.userNm
+ session.userNmKana = data.userNmKana
+ session.category = data.category
+ session.telNo = data.telNo
+ session.fax = data.fax
+ session.email = data.email
+ session.pwdInitYn = data.pwdInitYn
+ session.isLoggedIn = true
+ // console.log('session:', session)
+
+ await session.save()
+}
+
export async function login(formData) {
const session = await getSession()
diff --git a/src/lib/file.js b/src/lib/file.js
new file mode 100644
index 00000000..418fbe96
--- /dev/null
+++ b/src/lib/file.js
@@ -0,0 +1,22 @@
+'use server'
+import path from 'path'
+import multer from 'multer'
+
+export const upload = (files) => {
+ console.log(files)
+ const storage = multer.diskStorage({
+ destination: (req, file, callback) => {
+ const extension = path.extname(file.originalname)
+ const basename = path.basename(file.originalname, extension)
+ callback(null, `/public/upload/${basename}-${Date.now()}${extension}`)
+ },
+ filename: (req, file, callback) => {
+ callback(null, `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`)
+ }
+ })
+ const test = multer({
+ storage: storage
+ }).array(files.name, 5)
+
+ console.log(test)
+}
diff --git a/src/locales/ja.js b/src/locales/ja.js
index 2b7df6bd..5ae1b171 100644
--- a/src/locales/ja.js
+++ b/src/locales/ja.js
@@ -4,4 +4,87 @@ export default {
hello: 'ใใใซใกใฏ',
welcome: 'ใใใซใกใฏ {name}!',
locale: '็พๅจใฎใญใฑใผใซใฏ {locale} ใงใใ',
+ common: {
+ require: 'ํ์',
+ },
+ site: {
+ name: 'Q.CAST III',
+ sub_name: 'ํ์๊ด ๋ฐ์ ์์คํ
๋๋ฉด๊ด๋ฆฌ ์ฌ์ดํธ',
+ },
+ login: {
+ login: 'Login',
+ init_password: {
+ btn: '๋น๋ฐ๋ฒํธ ์ด๊ธฐํ',
+ title: '๋น๋ฐ๋ฒํธ ์ด๊ธฐํ',
+ sub_title: '๋น๋ฐ๋ฒํธ๋ฅผ ์ด๊ธฐํํ ์์ด๋์ ์ด๋ฉ์ผ ์ฃผ์๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์.',
+ },
+ },
+ join: {
+ title: 'Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ ์ ์ฒญ',
+ sub1: {
+ title: 'ํ๋งค๋๋ฆฌ์ ์ ๋ณด',
+ comment: 'โป ๋ฑ๋ก๋๋ ๋ฆฌ์
๋ฌ์ ํ์ฌ ์ด๋ฆ์ ์
๋ ฅํ์ญ์์ค. (2์ฐจ์ ์ ใโโํ๋งค์ฃผ์ํ์ฌ(2์ฐจ์ ๏ผรร์ค๋น์ฃผ์ํ์ฌ)ใ๋ก ๊ธฐ์
ํด ์ฃผ์ธ์.)',
+ storeQcastNm: 'ํ๋งค๋๋ฆฌ์ ๋ช
',
+ storeQcastNm_placeholder: 'ๆ ชๅผไผ็คพใจใใซใฎใขใปใฝใชใฅใผใทใงใณใปใขใณใใปใตใผใใน๏ผ2ๆฌกๅบ๏ผๅฑฑๅฃไฝๆฉ่ฒฉๅฃฒๆ้ไผ็คพ๏ผ',
+ storeQcastNmKana: 'ํ๋งค๋๋ฆฌ์ ๋ช
ํ๋ฆฌ๊ฐ๋',
+ storeQcastNmKana_placeholder: 'ใซใใทใญใฌใคใทใฃใจใใซใฎใขใปใฝใชใฅใผใทใงใณใปใขใณ',
+ postCd: '์ฐํธ๋ฒํธ',
+ postCd_placeholder: '์ซ์ 7์๋ฆฌ',
+ addr: '์ฃผ์',
+ addr_placeholder: '์ ๊ฐ50์์ด๋ด',
+ telNo: '์ ํ๋ฒํธ',
+ telNo_placeholder: '00-0000-0000',
+ fax: 'FAX ๋ฒํธ',
+ fax_placeholder: '00-0000-0000',
+ },
+ sub2: {
+ title: '๋ด๋น์ ์ ๋ณด',
+ userNm: '๋ด๋น์๋ช
',
+ userNmKana: '๋ด๋น์๋ช
ํ๋ฆฌ๊ฐ๋',
+ userId: '์ ์ฒญ ID',
+ email: '์ด๋ฉ์ผ ์ฃผ์',
+ telNo: '์ ํ๋ฒํธ',
+ telNo_placeholder: '00-0000-0000',
+ fax: 'FAX ๋ฒํธ',
+ fax_placeholder: '00-0000-0000',
+ category: '๋ถ์๋ช
',
+ },
+ sub3: {
+ title: '๊ฒฌ์ ์ ์ ์ถ์ฉ ํ์ฌ์ ๋ณด',
+ qtCompNm: 'ํ์ฌ๋ช
',
+ qtPostCd: '์ฐํธ๋ฒํธ',
+ qtPostCd_placeholder: '์ซ์ 7์๋ฆฌ',
+ qtAddr: '์ฃผ์',
+ qtAddr_placeholder: '์ ๊ฐ50์์ด๋ด',
+ qtEmail: '์ด๋ฉ์ผ ์ฃผ์',
+ qtTelNo: '์ ํ๋ฒํธ',
+ qtTelNo_placeholder: '00-0000-0000',
+ qtFax: 'FAX ๋ฒํธ',
+ qtFax_placeholder: '00-0000-0000',
+ },
+ btn: {
+ approval_request: 'ID ์น์ธ์์ฒญ',
+ },
+ complete: {
+ title: 'Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ์ ์ฒญ ์๋ฃ',
+ contents: 'โป ์ ์ฒญํ ID๊ฐ ์น์ธ๋๋ฉด, ๋ด๋น์ ์ ๋ณด์ ์
๋ ฅํ ์ด๋ฉ์ผ ์ฃผ์๋ก ๋ก๊ทธ์ธ ๊ด๋ จ ์๋ด ๋ฉ์ผ์ด ์ ์ก๋ฉ๋๋ค.',
+ email_comment: '๋ด๋น์ ์ด๋ฉ์ผ ์ฃผ์',
+ email: 'test@naver.com',
+ },
+ },
+ stuff: {
+ gridHeader: {
+ lastEditDatetime: '๊ฐฑ์ ์ผ์',
+ objectNo: '๋ฌผ๊ฑด๋ฒํธ',
+ planTotCnt: 'ํ๋ ์',
+ objectName: '๋ฌผ๊ฑด๋ช
',
+ saleStoreId: '๋๋ฆฌ์ ID',
+ saleStoreName: '๋๋ฆฌ์ ๋ช
',
+ address: '๋ฌผ๊ฑด์ฃผ์',
+ dispCompanyName: '๊ฒฌ์ ์ฒ',
+ receiveUser: '๋ด๋น์',
+ specDate: '์ฌ์ํ์ธ',
+ createDatetime: '๋ฑ๋ก์ผ',
+ },
+ },
}
diff --git a/src/locales/ja.json b/src/locales/ja.json
index a1725dfd..75f49389 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -1,3 +1,155 @@
{
- "hi": "ใใใซใกใฏ"
+ "hi": "ใใใซใกใฏ",
+ "common.message.no.data": "No data",
+ "common.message.no.dataDown": "ใใฆใณใญใผใใใใใผใฟใใใใพใใ",
+ "common.message.noData": "่กจ็คบใใใใผใฟใใใใพใใ",
+ "common.message.search": "search success",
+ "common.message.insert": "insert success",
+ "common.message.update": "update success",
+ "common.message.delete": "ๅ้ค",
+ "common.message.restoration": "ๅพฉๅ
",
+ "common.message.cancel": "ใญใฃใณใปใซ",
+ "common.message.send": "ใกใผใซใ้ไฟกใใพใใ.",
+ "common.message.no.delete": "ๅ้คใใใใผใฟใใใใพใใ",
+ "common.message.save": "ไฟๅญ",
+ "common.message.transfer": "่ปข้",
+ "common.message.batch.exec": "batch success",
+ "common.message.not.mov": "็งปๅใงใใพใใ.",
+ "common.message.required.data": "{0} ใฏๅ
ฅๅๅฟ
้ ้
็ฎใจใชใใพใใ",
+ "common.message.save.error": "ใใผใฟใฎไฟๅญไธญใซใจใฉใผใ็บ็ใใพใใใ ใตใคใ็ฎก็่
ใซใๅใๅใใใใ ใใใ",
+ "common.message.transfer.error": "ใใผใฟใฎ่ปข้ไธญใซใจใฉใผใ็บ็ใใพใใใ ใตใคใ็ฎก็่
ใซใๅใๅใใใใ ใใใ",
+ "common.message.delete.error": "ใใผใฟใฎๅ้คไธญใซใจใฉใผใ็บ็ใใพใใใ ใตใคใ็ฎก็่
ใซใๅใๅใใใใ ใใใ",
+ "common.message.batch.error": "ใใใใฎๅฎ่กไธญใซใจใฉใผใ็บ็ใใพใใใ ใตใคใ็ฎก็่
ใซ้ฃ็ตกใใฆใใ ใใใ",
+ "common.message.send.error": "ใใผใฟใฎ้ไฟกไธญใซใจใฉใผใ็บ็ใใพใใใใตใคใ็ฎก็่
ใซใๅใๅใใใใ ใใ",
+ "common.message.communication.error": "ใใใใฏใผใฏใจใฉใผใ็บ็ใใพใใใใตใคใ็ฎก็่
ใซ้ฃ็ตกใใฆใใ ใใใ",
+ "common.message.data.error": "{0} ใฏใใผใฟๅฝขๅผใ็กๅนใงใใ",
+ "common.message.data.setting.error": "{0} ใฏๅ้คใใใใใใใงใซๆงๆใใใฆใใใใผใฟใงใใ",
+ "common.message.parameter.error": "ใใฉใกใผใฟใจใฉใผ",
+ "common.message.product.parameter.error": "ๅญๅจใใชใ่ฃฝๅใใใใพใใ",
+ "common.message.customer.parameter.error": "ๅญๅจใใชใ้กงๅฎขใใใใพใใ",
+ "common.message.file.exists.error": "ใใกใคใซใๆญฃๅธธใซใขใใใญใผใใใใชใใใใซใจใฉใผใ็บ็ใใพใใ",
+ "common.message.file.download.exists": "ใใกใคใซใๅญๅจใใพใใใ",
+ "common.message.file.download.error": "ใกใคใซใฎใใฆใณใญใผใใจใฉใผ",
+ "common.message.file.template.validation01": "ใใฉใซใใใขใใใญใผใใงใใพใใ",
+ "common.message.file.template.validation02": "ใขใใใญใผใใงใใใฎใฏExcelใใกใคใซใฎใฟใงใใ",
+ "common.message.file.template.validation03": "็ป้ฒใงใใชใๆกๅผตๅญใงใ",
+ "common.message.file.template.validation04": "ๅฎน้ใ่ถ
ใใฆใใพใใใขใใใญใผใๅฏ่ฝใชๅฎน้๏ผ{0} MB",
+ "common.message.file.template.validation05": "ใขใใใญใผใใใกใคใซใ้ธๆใใฆไธใใ",
+ "common.message.multi.insert": "ๅ่จ {0} ไปถๆฐ ({1}ๆๅใ {2} ๅคฑๆ {3})",
+ "common.message.error": "ใจใฉใผใ็บ็ใใพใใใใตใคใ็ฎก็่
ใซ้ฃ็ตกใใฆใใ ใใใ",
+ "common.message.data.save": "ไฟๅญใใพใใ๏ผ",
+ "common.message.data.delete": " ๅ้คใใพใใ๏ผ",
+ "common.message.data.exists": "{0} ใฏใใงใซๅญๅจใใใใผใฟใงใใ",
+ "common.message.data.no.exists": "{0} ใฏๅญๅจใใชใใใผใฟใงใใ",
+ "common.message.all": "All",
+ "common.message.tab.close.all": "ใในใฆใฎใฟใใ้ใใพใใ๏ผ",
+ "common.message.transfer.save": "{0}ไปถ่ปข้ใใพใใ?",
+ "common.message.confirm.save": "ไฟๅญใใพใใ๏ผ",
+ "common.message.confirm.confirm": "ๆฟ่ชใใพใใ๏ผ",
+ "common.message.confirm.request": "ๆฟ่ชใชใฏใจในใใใพใใ๏ผ",
+ "common.message.confirm.delete": "ๅ้คใใพใใ๏ผ",
+ "common.message.confirm.close": "้ใใพใใ๏ผ",
+ "common.message.confirm.unclose": "ใฏใญใผใบไธญๆญขใใพใใ๏ผ",
+ "common.message.confirm.cancel": "ใญใฃใณใปใซใใพใใ๏ผ",
+ "common.message.confirm.uncancel": "ใญใฃใณใปใซไธญๆญขใใพใใ?",
+ "common.message.confirm.copy": "ใณใใผใใพใใ๏ผ",
+ "common.message.confirm.createSo": "S/Oไฝๆใใพใใ๏ผ",
+ "common.message.confirm.mark": "ไฟๅญๅฎไบ",
+ "common.message.confirm.mail": "ใกใผใซใ้ไฟกใใพใใ๏ผ",
+ "common.message.confirm.printPriceItem": "ไพกๆ ผใๅฐๅทใใพใใ๏ผ",
+ "common.message.confirm.allAppr ": "Do you want to Batch approve the selected data?",
+ "common.message.confirm.deliveryFee": "้ๆใ็ป้ฒใใพใใ๏ผ",
+ "common.message.success.delete": "ๅ้คๅฎไบ",
+ "common.message.success.close": "้ใใ",
+ "common.message.success.unclose": "ใญใฃใณใปใซใใพใใ",
+ "common.message.validation.date": "็ตไบๆฅใ้ๅงๆฅใใๅใซใใใใจใฏใงใใพใใใ ใใไธๅบฆๅ
ฅๅใใฆใใ ใใใ",
+ "common.message.no.editfield": "ใใฃใผใซใใ็ทจ้ใงใใพใใ",
+ "common.message.success.rmmail": "ใชในใฏ็ฎก็ใใผใ ใซใกใผใซใ้ไฟกใใพใใใ",
+ "common.message.password.validation01": "ใในใฏใผใใฎๅคๆดใไธ่ดใใพใใใ",
+ "common.message.password.validation02": "่ฑ่ชใๆฐๅญใ็นๆฎๆๅญใ็ตใฟๅใใใ8ๆกไปฅไธใๅ
ฅๅใใฆใใ ใใใ",
+ "common.message.password.validation03": "ใในใฏใผใใIDใจๅใใซใใใใจใฏใงใใพใใใ",
+ "common.message.menu.validation01": "ๆณจๆใไฟๅญใใใกใใฅใผใฏใใใพใใ.",
+ "common.message.menu.validation02": "The same sort order exists.",
+ "common.message.menuCode.check01": "็ป้ฒๅฏ่ฝ",
+ "common.message.menuCode.check02": "็ป้ฒใงใใพใใ",
+ "common.message.pleaseSelect": "{0}ใ้ธๆใใฆใใ ใใ",
+ "common.message.pleaseInput": "{0}ใๅ
ฅๅใใฆใใ ใใใ",
+ "common.message.pleaseInputOr": "{0}ใพใใฏ{1}ใๅ
ฅๅใใฆใใ ใใใ",
+ "common.message.approved ": "ๆฟ่ชๆธใฟ",
+ "common.message.errorFieldExist": "ใจใฉใผ้
็ฎใๅญๅจใใพใ",
+ "common.message.storeIdExist ": "ๆขใซๅฉ็จใใใฆใใ่ฒฉๅฃฒๅบIDใงใ",
+ "common.message.userIdExist ": "ใใงใซไฝฟ็จใใฆใใใฆใผใถใผIDใ",
+ "common.message.noExists ": "ๅ้คใใใๆฒ็คบ็ฉใงใ",
+ "common.message.emailReqTo": "ใกใผใซๅฎๅ
ใๅฟ
่ฆใงใ",
+ "common.message.downloadPeriod": "ใใฆใณใญใผใๆค็ดขๆ้ใ{0}ๆฅไปฅๅ
ใซ้ธๆใใฆใใ ใใใ",
+ "common.message.backToSubmit": "่ฒฉๅฃฒๅบใใญใใฏ่งฃ้คๅฎ่กใใพใใ๏ผ",
+ "common.message.backToG3": "Back to G3ๅฆ็ๅฎ่กใใพใใ๏ผ",
+ "common.message.writeToConfirm": "ไฝๆ่งฃ้คใๅฎ่กใใพใใ๏ผ",
+ "common.message.password.init.success": "ใในใฏใผใ [{0}] ใซๅๆๅใใใพใใใ",
+ "common.message.no.edit.save": "ใใฎๆๆธใฏๅคๆดใงใใพใใใ",
+
+ "common.require": "ํ์",
+
+ "site.name": "Q.CAST III",
+ "site.sub_name": "ํ์๊ด ๋ฐ์ ์์คํ
๋๋ฉด๊ด๋ฆฌ ์ฌ์ดํธ",
+
+ "login": "๋ก๊ทธ์ธ",
+ "login.init_password.btn": "๋น๋ฐ๋ฒํธ ์ด๊ธฐํ",
+ "login.init_password.title": "๋น๋ฐ๋ฒํธ ์ด๊ธฐํ",
+ "login.init_password.sub_title": "๋น๋ฐ๋ฒํธ๋ฅผ ์ด๊ธฐํํ ์์ด๋์ ์ด๋ฉ์ผ ์ฃผ์๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์.",
+ "login.init_password.complete_message": "๋น๋ฐ๋ฒํธ๊ฐ ์ด๊ธฐํ ๋์์ต๋๋ค. ์ด๊ธฐํ๋ ๋น๋ฐ๋ฒํธ๋ ์์ด๋์ ๊ฐ์ต๋๋ค.",
+
+ "join.title": "Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ ์ ์ฒญ",
+ "join.sub1.title": "ํ๋งค๋๋ฆฌ์ ์ ๋ณด",
+ "join.sub1.comment": "โป ๋ฑ๋ก๋๋ ๋ฆฌ์
๋ฌ์ ํ์ฌ ์ด๋ฆ์ ์
๋ ฅํ์ญ์์ค. (2์ฐจ์ ์ ใโโํ๋งค์ฃผ์ํ์ฌ(2์ฐจ์ ๏ผรร์ค๋น์ฃผ์ํ์ฌ)ใ๋ก ๊ธฐ์
ํด ์ฃผ์ธ์.)",
+ "join.sub1.storeQcastNm": "ํ๋งค๋๋ฆฌ์ ๋ช
",
+ "join.sub1.storeQcastNm_placeholder": "ๆ ชๅผไผ็คพใจใใซใฎใขใปใฝใชใฅใผใทใงใณใปใขใณใใปใตใผใใน๏ผ2ๆฌกๅบ๏ผๅฑฑๅฃไฝๆฉ่ฒฉๅฃฒๆ้ไผ็คพ๏ผ",
+ "join.sub1.storeQcastNmKana": "ํ๋งค๋๋ฆฌ์ ๋ช
ํ๋ฆฌ๊ฐ๋",
+ "join.sub1.storeQcastNmKana_placeholder": "ใซใใทใญใฌใคใทใฃใจใใซใฎใขใปใฝใชใฅใผใทใงใณใปใขใณ",
+ "join.sub1.postCd": "์ฐํธ๋ฒํธ",
+ "join.sub1.postCd_placeholder": "์ซ์ 7์๋ฆฌ",
+ "join.sub1.addr": "์ฃผ์",
+ "join.sub1.addr_placeholder": "์ ๊ฐ50์์ด๋ด",
+ "join.sub1.telNo": "์ ํ๋ฒํธ",
+ "join.sub1.telNo_placeholder": "00-0000-0000",
+ "join.sub1.fax": "FAX ๋ฒํธ",
+ "join.sub1.fax_placeholder": "00-0000-0000",
+ "join.sub2.title": "๋ด๋น์ ์ ๋ณด",
+ "join.sub2.userNm": "๋ด๋น์๋ช
",
+ "join.sub2.userNmKana": "๋ด๋น์๋ช
ํ๋ฆฌ๊ฐ๋",
+ "join.sub2.userId": "์ ์ฒญ ID",
+ "join.sub2.email": "์ด๋ฉ์ผ ์ฃผ์",
+ "join.sub2.telNo": "์ ํ๋ฒํธ",
+ "join.sub2.telNo_placeholder": "00-0000-0000",
+ "join.sub2.fax": "FAX ๋ฒํธ",
+ "join.sub2.fax_placeholder": "00-0000-0000",
+ "join.sub2.category": "๋ถ์๋ช
",
+ "join.sub3.title": "๊ฒฌ์ ์ ์ ์ถ์ฉ ํ์ฌ์ ๋ณด",
+ "join.sub3.qtCompNm": "ํ์ฌ๋ช
",
+ "join.sub3.qtPostCd": "์ฐํธ๋ฒํธ",
+ "join.sub3.qtPostCd_placeholder": "์ซ์ 7์๋ฆฌ",
+ "join.sub3.qtAddr": "์ฃผ์",
+ "join.sub3.qtAddr_placeholder": "์ ๊ฐ50์์ด๋ด",
+ "join.sub3.qtEmail": "์ด๋ฉ์ผ ์ฃผ์",
+ "join.sub3.qtTelNo": "์ ํ๋ฒํธ",
+ "join.sub3.qtTelNo_placeholder": "00-0000-0000",
+ "join.sub3.qtFax": "FAX ๋ฒํธ",
+ "join.sub3.qtFax_placeholder": "00-0000-0000",
+ "join.btn.approval_request": "ID ์น์ธ์์ฒญ",
+ "join.complete.title": "Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ์ ์ฒญ ์๋ฃ",
+ "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": "๋ฑ๋ก์ผ"
}
diff --git a/src/locales/ko.js b/src/locales/ko.js
index 40e17ba2..c01b913c 100644
--- a/src/locales/ko.js
+++ b/src/locales/ko.js
@@ -4,4 +4,88 @@ export default {
hello: '์๋
',
welcome: '์๋
{name}!',
locale: 'ํ์ฌ ๋ก์ผ์ผ์ {locale}์
๋๋ค.',
+ common: {
+ require: 'ํ์',
+ },
+ site: {
+ name: 'Q.CAST III',
+ sub_name: 'ํ์๊ด ๋ฐ์ ์์คํ
๋๋ฉด๊ด๋ฆฌ ์ฌ์ดํธ',
+ },
+ login: {
+ login: '๋ก๊ทธ์ธ',
+ init_password: {
+ btn: '๋น๋ฐ๋ฒํธ ์ด๊ธฐํ',
+ title: '๋น๋ฐ๋ฒํธ ์ด๊ธฐํ',
+ sub_title: '๋น๋ฐ๋ฒํธ๋ฅผ ์ด๊ธฐํํ ์์ด๋์ ์ด๋ฉ์ผ ์ฃผ์๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์.',
+ complete_message: '๋น๋ฐ๋ฒํธ๊ฐ ์ด๊ธฐํ ๋์์ต๋๋ค. ์ด๊ธฐํ๋ ๋น๋ฐ๋ฒํธ๋ ์์ด๋์ ๊ฐ์ต๋๋ค.',
+ },
+ },
+ join: {
+ title: 'Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ ์ ์ฒญ',
+ sub1: {
+ title: 'ํ๋งค๋๋ฆฌ์ ์ ๋ณด',
+ comment: 'โป ๋ฑ๋ก๋๋ ๋ฆฌ์
๋ฌ์ ํ์ฌ ์ด๋ฆ์ ์
๋ ฅํ์ญ์์ค. (2์ฐจ์ ์ ใโโํ๋งค์ฃผ์ํ์ฌ(2์ฐจ์ ๏ผรร์ค๋น์ฃผ์ํ์ฌ)ใ๋ก ๊ธฐ์
ํด ์ฃผ์ธ์.)',
+ storeQcastNm: 'ํ๋งค๋๋ฆฌ์ ๋ช
',
+ storeQcastNm_placeholder: '์ฃผ์ํ์ฌ ์๋์ง ๊ธฐ์ด ์๋ฃจ์
์ค ์๋น์ค (2์ฐจ์ : ์ผ๋ง๊ตฌ์น ์ฃผ๊ธฐ ํ๋งค ์ ํํ์ฌ)',
+ storeQcastNmKana: 'ํ๋งค๋๋ฆฌ์ ๋ช
ํ๋ฆฌ๊ฐ๋',
+ storeQcastNmKana_placeholder: '์ฃผ์ํ์ฌ ์๋์ง ๊ธฐ์ด ์๋ฃจ์
',
+ postCd: '์ฐํธ๋ฒํธ',
+ postCd_placeholder: '์ซ์ 7์๋ฆฌ',
+ addr: '์ฃผ์',
+ addr_placeholder: '์ ๊ฐ50์์ด๋ด',
+ telNo: '์ ํ๋ฒํธ',
+ telNo_placeholder: '00-0000-0000',
+ fax: 'FAX ๋ฒํธ',
+ fax_placeholder: '00-0000-0000',
+ },
+ sub2: {
+ title: '๋ด๋น์ ์ ๋ณด',
+ userNm: '๋ด๋น์๋ช
',
+ userNmKana: '๋ด๋น์๋ช
ํ๋ฆฌ๊ฐ๋',
+ userId: '์ ์ฒญ ID',
+ email: '์ด๋ฉ์ผ ์ฃผ์',
+ telNo: '์ ํ๋ฒํธ',
+ telNo_placeholder: '00-0000-0000',
+ fax: 'FAX ๋ฒํธ',
+ fax_placeholder: '00-0000-0000',
+ category: '๋ถ์๋ช
',
+ },
+ sub3: {
+ title: '๊ฒฌ์ ์ ์ ์ถ์ฉ ํ์ฌ์ ๋ณด',
+ qtCompNm: 'ํ์ฌ๋ช
',
+ qtPostCd: '์ฐํธ๋ฒํธ',
+ qtPostCd_placeholder: '์ซ์ 7์๋ฆฌ',
+ qtAddr: '์ฃผ์',
+ qtAddr_placeholder: '์ ๊ฐ50์์ด๋ด',
+ qtEmail: '์ด๋ฉ์ผ ์ฃผ์',
+ qtTelNo: '์ ํ๋ฒํธ',
+ qtTelNo_placeholder: '00-0000-0000',
+ qtFax: 'FAX ๋ฒํธ',
+ qtFax_placeholder: '00-0000-0000',
+ },
+ btn: {
+ approval_request: 'ID ์น์ธ์์ฒญ',
+ },
+ complete: {
+ title: 'Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ์ ์ฒญ ์๋ฃ',
+ contents: 'โป ์ ์ฒญํ ID๊ฐ ์น์ธ๋๋ฉด, ๋ด๋น์ ์ ๋ณด์ ์
๋ ฅํ ์ด๋ฉ์ผ ์ฃผ์๋ก ๋ก๊ทธ์ธ ๊ด๋ จ ์๋ด ๋ฉ์ผ์ด ์ ์ก๋ฉ๋๋ค.',
+ email_comment: '๋ด๋น์ ์ด๋ฉ์ผ ์ฃผ์',
+ email: 'test@naver.com',
+ },
+ },
+ stuff: {
+ gridHeader: {
+ lastEditDatetime: '๊ฐฑ์ ์ผ์',
+ objectNo: '๋ฌผ๊ฑด๋ฒํธ',
+ planTotCnt: 'ํ๋ ์',
+ objectName: '๋ฌผ๊ฑด๋ช
',
+ saleStoreId: '๋๋ฆฌ์ ID',
+ saleStoreName: '๋๋ฆฌ์ ๋ช
',
+ address: '๋ฌผ๊ฑด์ฃผ์',
+ dispCompanyName: '๊ฒฌ์ ์ฒ',
+ receiveUser: '๋ด๋น์',
+ specDate: '์ฌ์ํ์ธ',
+ createDatetime: '๋ฑ๋ก์ผ',
+ },
+ },
}
diff --git a/src/locales/ko.json b/src/locales/ko.json
index 282d9722..75ef871f 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -1,3 +1,155 @@
{
- "hi": "์๋
ํ์ธ์"
+ "hi": "์๋
ํ์ธ์",
+ "common.message.no.data": "No data",
+ "common.message.no.dataDown": "No data to download",
+ "common.message.noData": "No data to display",
+ "common.message.search": "search success",
+ "common.message.insert": "insert success",
+ "common.message.update": "update success",
+ "common.message.delete": "Deleted",
+ "common.message.restoration": "Restored",
+ "common.message.cancel": "Canceled",
+ "common.message.send": "The mail has been sent.",
+ "common.message.no.delete": "There is no data to delete.",
+ "common.message.save": "Saved.",
+ "common.message.transfer": "Transfered",
+ "common.message.batch.exec": "batch success",
+ "common.message.not.mov": "Its impossible to move.",
+ "common.message.required.data": "{0} is required input value.",
+ "common.message.save.error": "An error occurred while saving the data. Please contact site administrator.",
+ "common.message.transfer.error": "An error occurred while transfer the data. Please contact site administrator.",
+ "common.message.delete.error": "An error occurred while deleting data. Please contact site administrator.",
+ "common.message.batch.error": "An error occurred while executing the batch. Please contact site administrator.",
+ "common.message.send.error": "Error sending data, please contact your administrator.",
+ "common.message.communication.error": "Network error occurred. \n Please contact site administrator.",
+ "common.message.data.error": "{0} The data format is not valid.",
+ "common.message.data.setting.error": "{0} is data that has been deleted or already configured.",
+ "common.message.parameter.error": "Parameter Error",
+ "common.message.product.parameter.error": "์กด์ฌํ์ง ์๋ ์ ํ์ด ์์ต๋๋ค.",
+ "common.message.customer.parameter.error": "์กด์ฌํ์ง ์๋ ๊ณ ๊ฐ์ด ์์ต๋๋ค.",
+ "common.message.file.exists.error": "Error due to file not uploading normally",
+ "common.message.file.download.exists": "File does not exist.",
+ "common.message.file.download.error": "File download error",
+ "common.message.file.template.validation01": "Unable to upload folder",
+ "common.message.file.template.validation02": "Only Excel files can be uploaded.",
+ "common.message.file.template.validation03": "Non-registerable extension",
+ "common.message.file.template.validation04": "Exceed capacity \n Uploadable capacity : {0} MB",
+ "common.message.file.template.validation05": "์
๋ก๋ ํ์ผ์ ์ ํํด์ฃผ์ธ์.",
+ "common.message.multi.insert": "Total {0} cases ({1} successes, {2} failures {3})",
+ "common.message.error": "Error occurred, please contact site administrator.",
+ "common.message.data.save": "Do you want to save it?",
+ "common.message.data.delete": "Do you want to delete it?",
+ "common.message.data.exists": "{0} is data that already exists.",
+ "common.message.data.no.exists": "{0} is data that does not exist.",
+ "common.message.all": "All",
+ "common.message.tab.close.all": "Close all tabs?",
+ "common.message.transfer.save": "Want to {0} transfer it?",
+ "common.message.confirm.save": "Want to save it?",
+ "common.message.confirm.confirm": "Want to approve?",
+ "common.message.confirm.request": "Would you like to request a Approval?",
+ "common.message.confirm.delete": "Do you want to delete it?",
+ "common.message.confirm.close": "Want to close?",
+ "common.message.confirm.unclose": "Do you want to cancel the close?",
+ "common.message.confirm.cancel": "Want to cancellation?",
+ "common.message.confirm.uncancel": "Do you want to cancel the cancellation?",
+ "common.message.confirm.copy": "Do you want to copy?",
+ "common.message.confirm.createSo": "Create Sales Order?",
+ "common.message.confirm.mark": "Saved.",
+ "common.message.confirm.mail": "Do you want to send mail?",
+ "common.message.confirm.printPriceItem": "Would you like to print item price?",
+ "common.message.confirm.allAppr ": "Do you want to Batch approve the selected data?",
+ "common.message.confirm.deliveryFee": "Do you want to register shipping fee?",
+ "common.message.success.delete": "Deleted.",
+ "common.message.success.close": "Closed.",
+ "common.message.success.unclose": "Cancel Closed.",
+ "common.message.validation.date": "The end date cannot be earlier than the start date. Please enter it again.",
+ "common.message.no.editfield": "Can not edit field",
+ "common.message.success.rmmail": "You have successfully sent mail to the Risk Management team.",
+ "common.message.password.validation01": "Change passwords do not match.",
+ "common.message.password.validation02": "Please enter at least 8 digits combining English, numbers, and special characters.",
+ "common.message.password.validation03": "Password cannot be the same as ID.",
+ "common.message.menu.validation01": "There is no menu to save the order.",
+ "common.message.menu.validation02": "The same sort order exists.",
+ "common.message.menuCode.check01": "Registerable",
+ "common.message.menuCode.check02": "Unable to register",
+ "common.message.pleaseSelect": "Please Select {0}",
+ "common.message.pleaseInput": "Please Input a {0}.",
+ "common.message.pleaseInputOr": "Please Input a {0} or {1}.",
+ "common.message.approved ": "Approved.",
+ "common.message.errorFieldExist": "Error Field Exist",
+ "common.message.storeIdExist ": "์ด๋ฏธ ์ฌ์ฉํ๊ณ ์๋ ํ๋งค์ ID ์
๋๋ค.",
+ "common.message.userIdExist ": "์ด๋ฏธ ์ฌ์ฉํ๊ณ ์๋ ์ฌ์ฉ์ ID ์
๋๋ค.",
+ "common.message.noExists ": "์ญ์ ๋ ๊ฒ์๋ฌผ ์
๋๋ค.",
+ "common.message.emailReqTo": "Email To is required",
+ "common.message.downloadPeriod": "Please select the download search period within {0} days.",
+ "common.message.backToSubmit": "ํ๋งค์ ๋ธ๋ก ํด์ ๋ฅผ ์คํํ์๊ฒ ์ต๋๊น?",
+ "common.message.backToG3": "Back to G3 ์ฒ๋ฆฌ๋ฅผ ์คํํ์๊ฒ ์ต๋๊น?",
+ "common.message.writeToConfirm": "์์ฑ ํด์ ๋ฅผ ์คํํ์๊ฒ ์ต๋๊น?",
+ "common.message.password.init.success": "๋น๋ฐ๋ฒํธ [{0}]๋ก ์ด๊ธฐํ ๋์์ต๋๋ค.",
+ "common.message.no.edit.save": "This document cannot be changed.",
+
+ "common.require": "ํ์",
+
+ "site.name": "Q.CAST III",
+ "site.sub_name": "ํ์๊ด ๋ฐ์ ์์คํ
๋๋ฉด๊ด๋ฆฌ ์ฌ์ดํธ",
+
+ "login": "๋ก๊ทธ์ธ",
+ "login.init_password.btn": "๋น๋ฐ๋ฒํธ ์ด๊ธฐํ",
+ "login.init_password.title": "๋น๋ฐ๋ฒํธ ์ด๊ธฐํ",
+ "login.init_password.sub_title": "๋น๋ฐ๋ฒํธ๋ฅผ ์ด๊ธฐํํ ์์ด๋์ ์ด๋ฉ์ผ ์ฃผ์๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์.",
+ "login.init_password.complete_message": "๋น๋ฐ๋ฒํธ๊ฐ ์ด๊ธฐํ ๋์์ต๋๋ค. ์ด๊ธฐํ๋ ๋น๋ฐ๋ฒํธ๋ ์์ด๋์ ๊ฐ์ต๋๋ค.",
+
+ "join.title": "Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ ์ ์ฒญ",
+ "join.sub1.title": "ํ๋งค๋๋ฆฌ์ ์ ๋ณด",
+ "join.sub1.comment": "โป ๋ฑ๋ก๋๋ ๋ฆฌ์
๋ฌ์ ํ์ฌ ์ด๋ฆ์ ์
๋ ฅํ์ญ์์ค. (2์ฐจ์ ์ ใโโํ๋งค์ฃผ์ํ์ฌ(2์ฐจ์ ๏ผรร์ค๋น์ฃผ์ํ์ฌ)ใ๋ก ๊ธฐ์
ํด ์ฃผ์ธ์.)",
+ "join.sub1.storeQcastNm": "ํ๋งค๋๋ฆฌ์ ๋ช
",
+ "join.sub1.storeQcastNm_placeholder": "์ฃผ์ํ์ฌ ์๋์ง ๊ธฐ์ด ์๋ฃจ์
์ค ์๋น์ค (2์ฐจ์ : ์ผ๋ง๊ตฌ์น ์ฃผ๊ธฐ ํ๋งค ์ ํํ์ฌ)",
+ "join.sub1.storeQcastNmKana": "ํ๋งค๋๋ฆฌ์ ๋ช
ํ๋ฆฌ๊ฐ๋",
+ "join.sub1.storeQcastNmKana_placeholder": "์ฃผ์ํ์ฌ ์๋์ง ๊ธฐ์ด ์๋ฃจ์
",
+ "join.sub1.postCd": "์ฐํธ๋ฒํธ",
+ "join.sub1.postCd_placeholder": "์ซ์ 7์๋ฆฌ",
+ "join.sub1.addr": "์ฃผ์",
+ "join.sub1.addr_placeholder": "์ ๊ฐ50์์ด๋ด",
+ "join.sub1.telNo": "์ ํ๋ฒํธ",
+ "join.sub1.telNo_placeholder": "00-0000-0000",
+ "join.sub1.fax": "FAX ๋ฒํธ",
+ "join.sub1.fax_placeholder": "00-0000-0000",
+ "join.sub2.title": "๋ด๋น์ ์ ๋ณด",
+ "join.sub2.userNm": "๋ด๋น์๋ช
",
+ "join.sub2.userNmKana": "๋ด๋น์๋ช
ํ๋ฆฌ๊ฐ๋",
+ "join.sub2.userId": "์ ์ฒญ ID",
+ "join.sub2.email": "์ด๋ฉ์ผ ์ฃผ์",
+ "join.sub2.telNo": "์ ํ๋ฒํธ",
+ "join.sub2.telNo_placeholder": "00-0000-0000",
+ "join.sub2.fax": "FAX ๋ฒํธ",
+ "join.sub2.fax_placeholder": "00-0000-0000",
+ "join.sub2.category": "๋ถ์๋ช
",
+ "join.sub3.title": "๊ฒฌ์ ์ ์ ์ถ์ฉ ํ์ฌ์ ๋ณด",
+ "join.sub3.qtCompNm": "ํ์ฌ๋ช
",
+ "join.sub3.qtPostCd": "์ฐํธ๋ฒํธ",
+ "join.sub3.qtPostCd_placeholder": "์ซ์ 7์๋ฆฌ",
+ "join.sub3.qtAddr": "์ฃผ์",
+ "join.sub3.qtAddr_placeholder": "์ ๊ฐ50์์ด๋ด",
+ "join.sub3.qtEmail": "์ด๋ฉ์ผ ์ฃผ์",
+ "join.sub3.qtTelNo": "์ ํ๋ฒํธ",
+ "join.sub3.qtTelNo_placeholder": "00-0000-0000",
+ "join.sub3.qtFax": "FAX ๋ฒํธ",
+ "join.sub3.qtFax_placeholder": "00-0000-0000",
+ "join.btn.approval_request": "ID ์น์ธ์์ฒญ",
+ "join.complete.title": "Q.CAST3 ๋ก๊ทธ์ธID ๋ฐํ์ ์ฒญ ์๋ฃ",
+ "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": "๋ฑ๋ก์ผ"
}
diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js
index a675b508..44f29df5 100644
--- a/src/store/canvasAtom.js
+++ b/src/store/canvasAtom.js
@@ -1,5 +1,11 @@
import { atom } from 'recoil'
+export const canvasState = atom({
+ key: 'canvasState',
+ default: null,
+ dangerouslyAllowMutability: true,
+})
+
export const textState = atom({
key: 'textState',
default: 'test text',
@@ -145,8 +151,31 @@ export const cadFileCompleteState = atom({
default: false,
})
+export const useGoogleMapFileState = atom({
+ key: 'useGoogleMapFile',
+ default: false,
+})
+
+// ๊ตฌ๊ธ๋งต ์ ์ฅ ์ด๋ฏธ์ง ํ์ผ ์ด๋ฆ
+export const googleMapFileNameState = atom({
+ key: 'googleMapFileName',
+ default: '',
+})
+
export const globalCompassState = atom({
key: 'globalCompass',
default: 0,
dangerouslyAllowMutability: true,
})
+
+// ๋ฉดํ์ ๋ฐฐ์น ๋ชจ๋
+export const surfacePlacementModeState = atom({
+ key: 'surfacePlacementMode',
+ default: { width: 0, height: 0, areaBoundary: true, inputType: 'free' },
+})
+
+// ์ค๋ธ์ ํธ ๋ฐฐ์น ๋ชจ๋
+export const objectPlacementModeState = atom({
+ key: 'objectPlacementMode',
+ default: { width: 0, height: 0, areaBoundary: false, inputType: 'free', batchType: 'opening' },
+})
diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js
new file mode 100644
index 00000000..0ab99ea1
--- /dev/null
+++ b/src/store/settingAtom.js
@@ -0,0 +1,45 @@
+import { atom } from 'recoil'
+
+export const settingModalFirstOptionsState = atom({
+ key: 'settingModalFirstOptions',
+ default: {
+ option1: [
+ { id: 1, name: 'ๅฒใๅฝใฆ่กจ็คบ', selected: false },
+ { id: 2, name: 'ๅฎๅฏธ่กจ็คบ', selected: false },
+ { id: 3, name: 'ๅณ้ข่กจ็คบ', selected: false },
+ { id: 4, name: 'ๅฏธๆณ่กจ็คบใชใ', selected: false },
+ { id: 5, name: 'ใฐใชใใ่กจ็คบ', selected: false },
+ { id: 6, name: 'ๆถๅฐ่กจ็คบ', selected: false },
+ { id: 7, name: 'ๆๅญ่กจ็คบ', selected: false },
+ { id: 8, name: 'ๅบงๆจ่กจ็คบ', selected: false },
+ { id: 9, name: 'ๆตใๆนๅ่กจ็คบ', selected: false },
+ { id: 10, name: 'ๅณ้ขๅๆฟ่กจ็คบ', selected: false },
+ { id: 11, name: 'รผๅปไธๅฏธๆณ่กจ็คบ', selected: false },
+ ],
+ option2: [
+ { id: 1, name: 'ใใผใใผใฎใฟ', selected: false },
+ { id: 2, name: 'ใฉใคใณใใใ', selected: false },
+ { id: 3, name: 'All painted', selected: false },
+ ],
+ },
+ dangerouslyAllowMutability: true,
+})
+
+export const settingModalSecondOptionsState = atom({
+ key: 'settingModalSecondOptions',
+ default: {
+ option1: [
+ { id: 1, name: 'ๆๅญใใฉใณใใฎๅคๆด' },
+ { id: 2, name: 'ใใญใผๆนๅใใฉใณใใฎๅคๆด' },
+ { id: 3, name: 'ๅฏธๆณใใฉใณใใฎๅคๆด' },
+ { id: 4, name: 'ๅ่ทฏ็ชๅทใใฉใณใใฎๅคๆด' },
+ ],
+ option2: [
+ { id: 1, name: 'ๆฅตๅฐ', selected: false },
+ { id: 2, name: '็', selected: false },
+ { id: 3, name: 'ไธญ', selected: false },
+ { id: 4, name: 'ใใฃใผใณ', selected: false },
+ ],
+ },
+ dangerouslyAllowMutability: true,
+})
diff --git a/src/store/stuffAtom.js b/src/store/stuffAtom.js
new file mode 100644
index 00000000..a122543c
--- /dev/null
+++ b/src/store/stuffAtom.js
@@ -0,0 +1,22 @@
+import { atom } from 'recoil'
+import dayjs from 'dayjs'
+import isLeapYear from 'dayjs/plugin/isLeapYear' // ์ค๋
ํ๋จ ํ๋ฌ๊ทธ์ธ
+dayjs.extend(isLeapYear)
+export const stuffSearchState = atom({
+ key: 'stuffSearchState',
+ default: {
+ schObjectNo: '', //๋ฌผ๊ฑด๋ฒํธ
+ schSaleStoreId: '', //ํ๋งค๋๋ฆฌ์ ID
+ schAddress: '', //๋ฌผ๊ฑด์ฃผ์
+ schObjectName: '', //๋ฌผ๊ฑด๋ช
+ schSaleStoreName: '', //ํ๋งค๋๋ฆฌ์ ๋ช
+ schSpecDateYn: '', //์ฌ์ํ์
('', 'Y', 'N')
+ schReceiveUser: '', //๋ด๋น์
+ schDispCompanyName: '', //๊ฒฌ์ ์ฒ
+ schDateType: 'U', //๊ฐฑ์ ์ผ(U)/๋ฑ๋ก์ผ(R)
+ schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'), //์์์ผ
+ schToDt: dayjs(new Date()).format('YYYY-MM-DD'), //์ข
๋ฃ์ผ
+ code: 'S',
+ },
+ dangerouslyAllowMutability: true,
+})
diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss
new file mode 100644
index 00000000..b9dbe68e
--- /dev/null
+++ b/src/styles/_contents.scss
@@ -0,0 +1,455 @@
+// CanvasPage
+.canvas-wrap {
+ height: calc(100vh - 47px);
+ display: flex;
+ flex-direction: column;
+
+ .canvas-content {
+ flex: 1 1 auto;
+
+ .canvas-layout {
+ height: 100%;
+ }
+ }
+}
+
+// CanvasMenu
+.canvas-menu-wrap {
+ position: relative;
+ display: block;
+ width: 100%;
+ padding-bottom: 0;
+ background-color: #383838;
+ transition: padding .17s ease-in-out;
+
+ .canvas-menu-inner {
+ position: relative;
+ display: flex;
+ align-items: center;
+ padding: 0 40px 0 20px;
+ background-color: #2C2C2C;
+ z-index: 999;
+
+ .canvas-menu-list {
+ display: flex;
+ align-items: center;
+ height: 100%;
+
+ .canvas-menu-item {
+ display: flex;
+ align-items: center;
+ height: 100%;
+
+ button {
+ display: flex;
+ align-items: center;
+ font-size: 12px;
+ height: 100%;
+ color: #fff;
+ font-weight: 600;
+ padding: 15px 20px;
+ opacity: 0.55;
+ transition: all .17s ease-in-out;
+
+ .menu-icon {
+ display: block;
+ width: 16px;
+ height: 16px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: cover;
+ margin-right: 10px;
+
+ &.con00 {
+ background-image: url(/static/images/canvas/menu_icon00.svg);
+ }
+
+ &.con01 {
+ background-image: url(/static/images/canvas/menu_icon01.svg);
+ }
+
+ &.con02 {
+ background-image: url(/static/images/canvas/menu_icon02.svg);
+ }
+
+ &.con03 {
+ background-image: url(/static/images/canvas/menu_icon03.svg);
+ }
+
+ &.con04 {
+ background-image: url(/static/images/canvas/menu_icon04.svg);
+ }
+
+ &.con05 {
+ background-image: url(/static/images/canvas/menu_icon05.svg);
+ }
+
+ &.con06 {
+ background-image: url(/static/images/canvas/menu_icon06.svg);
+ }
+ }
+ }
+
+ &.active {
+ background-color: #383838;
+
+ button {
+ opacity: 1;
+ }
+ }
+ }
+ }
+
+ .canvas-side-btn-wrap {
+ display: flex;
+ align-items: center;
+ margin-left: auto;
+
+ .select-box {
+ width: 124px;
+ margin-right: 5px;
+
+ > div {
+ width: 100%;
+ }
+ }
+
+ .btn-from {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+
+ button {
+ display: block;
+ width: 30px;
+ height: 30px;
+ border-radius: 2px;
+ background-color: #3D3D3D;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 15px 15px;
+ transition: all .17s ease-in-out;
+
+ &.btn01 {
+ background-image: url(../../public/static/images/canvas/side_icon01.svg);
+ }
+
+ &.btn02 {
+ background-image: url(../../public/static/images/canvas/side_icon02.svg);
+ }
+
+ &.btn03 {
+ background-image: url(../../public/static/images/canvas/side_icon03.svg);
+ }
+
+ &.btn04 {
+ background-image: url(../../public/static/images/canvas/side_icon04.svg);
+ }
+
+ &.btn05 {
+ background-image: url(../../public/static/images/canvas/side_icon05.svg);
+ }
+
+ &.btn06 {
+ background-image: url(../../public/static/images/canvas/side_icon06.svg);
+ }
+
+ &.btn07 {
+ background-image: url(../../public/static/images/canvas/side_icon07.svg);
+ }
+
+ &.btn08 {
+ background-image: url(../../public/static/images/canvas/side_icon08.svg);
+ }
+
+ &.btn09 {
+ background-image: url(../../public/static/images/canvas/side_icon09.svg);
+ }
+
+ &:hover {
+ background-color: #1083E3;
+ }
+
+ &.active {
+ background-color: #1083E3;
+ }
+ }
+ }
+
+ .vertical-horizontal {
+ display: flex;
+ min-width: 170px;
+ height: 28px;
+ margin: 0 5px;
+ border-radius: 2px;
+ background: #373737;
+ line-height: 28px;
+ overflow: hidden;
+
+ span {
+ padding: 0 10px;
+ font-size: 13px;
+ color: #fff;
+ }
+
+ button {
+ margin-left: auto;
+ height: 100%;
+ background-color: #4B4B4B;
+ font-size: 13px;
+ font-weight: 400;
+ color: #fff;
+ padding: 0 7.5px;
+ }
+ }
+
+ .size-control {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ background-color: #3D3D3D;
+ border-radius: 2px;
+ width: 100px;
+ height: 30px;
+ margin: 0 5px;
+
+ span {
+ font-size: 13px;
+ color: #fff;
+ }
+
+ .control-btn {
+ display: block;
+ width: 12px;
+ height: 12px;
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-position: center;
+
+ &.minus {
+ background-image: url(../../public/static/images/canvas/minus.svg);
+ }
+
+ &.plus {
+ background-image: url(../../public/static/images/canvas/plus.svg);
+ }
+ }
+ }
+ }
+ }
+
+ .canvas-depth2-wrap {
+ position: absolute;
+ top: -100%;
+ left: 0;
+ background-color: #383838;
+ width: 100%;
+ height: 50px;
+ transition: all .17s ease-in-out;
+
+ .canvas-depth2-inner {
+ display: flex;
+ align-items: center;
+ padding: 0 40px;
+ height: 100%;
+
+ .canvas-depth2-list {
+ display: flex;
+ align-items: center;
+ height: 100%;
+
+ .canvas-depth2-item {
+ display: flex;
+ align-items: center;
+ margin-right: 26px;
+ height: 100%;
+
+ button {
+ position: relative;
+ opacity: 0.55;
+ color: #fff;
+ font-size: 12px;
+ font-weight: normal;
+ height: 100%;
+ padding-right: 12px;
+ }
+
+ &.active {
+ button {
+ opacity: 1;
+ font-weight: 600;
+
+ &:after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ width: 5px;
+ height: 8px;
+ background: url(../../public/static/images/canvas/depth2-arr.svg) no-repeat center;
+ }
+ }
+ }
+ }
+ }
+
+ .canvas-depth2-btn-list {
+ display: flex;
+ align-items: center;
+ margin-left: auto;
+ height: 100%;
+
+ .depth2-btn-box {
+ display: flex;
+ align-items: center;
+ margin-right: 34px;
+ height: 100%;
+ transition: all .17s ease-in-out;
+
+ button {
+ position: relative;
+ font-size: 12px;
+ font-weight: 400;
+ height: 100%;
+ color: #fff;
+ padding-right: 12px;
+
+ &:after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ width: 5px;
+ height: 8px;
+ background: url(../../public/static/images/canvas/depth2-arr.svg) no-repeat center;
+ }
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ &.mouse {
+ opacity: 0.55;
+ }
+ }
+ }
+ }
+
+ &.active {
+ top: 47px;
+ }
+ }
+
+ &.active {
+ padding-bottom: 50px;
+ }
+}
+
+// canvas-layout
+.canvas-layout {
+ .canvas-page-list {
+ display: flex;
+ background-color: #1C1C1C;
+ border-top: 1px solid #000;
+ width: 100%;
+
+ .canvas-plane-wrap {
+ display: flex;
+ align-items: center;
+ max-width: calc(100% - 45px);
+
+ .canvas-page-box {
+ display: flex;
+ align-items: center;
+ background-color: #1c1c1c;
+ padding: 9.6px 20px;
+ border-right: 1px solid #000;
+ min-width: 0;
+ transition: all .17s ease-in-out;
+
+ span {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ font-size: 12px;
+ font-family: 'Pretendard', sans-serif;
+ color: #AAA;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
+
+ .close {
+ flex: none;
+ display: block;
+ width: 7px;
+ height: 8px;
+ margin-left: 15px;
+ background: url(../../public/static/images/canvas/plan_close_gray.svg) no-repeat center;
+ background-size: cover;
+ }
+
+ &.on {
+ background-color: #fff;
+
+ span {
+ font-weight: 600;
+ color: #101010;
+ }
+
+ .close {
+ background: url(../../public/static/images/canvas/plan_close_black.svg) no-repeat center;
+ }
+
+ &:hover {
+ background-color: #fff;
+ }
+ }
+
+ &:hover {
+ background-color: #000;
+ }
+ }
+ }
+
+ .plane-add {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 45px;
+ padding: 13.5px 0;
+ background-color: #1C1C1C;
+ border-right: 1px solid #000;
+ transition: all .17s ease-in-out;
+
+ span {
+ display: block;
+ width: 9px;
+ height: 9px;
+ background: url(../../public/static/images/canvas/plane_add.svg) no-repeat center;
+ background-size: cover;
+ }
+
+ &:hover {
+ background-color: #000;
+ }
+ }
+ }
+}
+
+.canvas-frame {
+ position: relative;
+ height: calc(100% - 36.5px);
+
+ canvas {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+}
\ No newline at end of file
diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss
new file mode 100644
index 00000000..b1d16e89
--- /dev/null
+++ b/src/styles/_fonts.scss
@@ -0,0 +1,199 @@
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-ExtraBold.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-ExtraBold.woff') format('woff');
+ font-weight: bold;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-Bold.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-Bold.woff') format('woff');
+ font-weight: bold;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-Black.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-Black.woff') format('woff');
+ font-weight: 900;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-ExtraLight.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-ExtraLight.woff') format('woff');
+ font-weight: 200;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-Light.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-Light.woff') format('woff');
+ font-weight: 300;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-Medium.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-Medium.woff') format('woff');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-Regular.woff') format('woff');
+ font-weight: normal;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-SemiBold.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-SemiBold.woff') format('woff');
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Noto Sans JP';
+ src: url('/fonts/NotoSansJP-Thin.woff2') format('woff2'),
+ url('/fonts/NotoSansJP-Thin.woff') format('woff');
+ font-weight: 100;
+ font-style: normal;
+ font-display: swap;
+}
+
+// pretendard
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Bold.woff2') format('woff2'),
+ url('/fonts/Pretendard-Bold.woff') format('woff');
+ font-weight: bold;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-ExtraBold.woff2') format('woff2'),
+ url('/fonts/Pretendard-ExtraBold.woff') format('woff');
+ font-weight: bold;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-ExtraBold.woff2') format('woff2'),
+ url('/fonts/Pretendard-ExtraBold.woff') format('woff');
+ font-weight: bold;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-ExtraLight.woff2') format('woff2'),
+ url('/fonts/Pretendard-ExtraLight.woff') format('woff');
+ font-weight: 200;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-ExtraLight.woff2') format('woff2'),
+ url('/fonts/Pretendard-ExtraLight.woff') format('woff');
+ font-weight: 200;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Light.woff2') format('woff2'),
+ url('/fonts/Pretendard-Light.woff') format('woff');
+ font-weight: 300;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Light.woff2') format('woff2'),
+ url('/fonts/Pretendard-Light.woff') format('woff');
+ font-weight: 300;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Medium.woff2') format('woff2'),
+ url('/fonts/Pretendard-Medium.woff') format('woff');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Medium.woff2') format('woff2'),
+ url('/fonts/Pretendard-Medium.woff') format('woff');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Regular.woff2') format('woff2'),
+ url('/fonts/Pretendard-Regular.woff') format('woff');
+ font-weight: normal;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Black.woff2') format('woff2'),
+ url('/fonts/Pretendard-Black.woff') format('woff');
+ font-weight: 900;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Black.woff2') format('woff2'),
+ url('/fonts/Pretendard-Black.woff') format('woff');
+ font-weight: 900;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Bold.woff2') format('woff2'),
+ url('/fonts/Pretendard-Bold.woff') format('woff');
+ font-weight: bold;
+ font-style: normal;
+ font-display: swap;
+}
+
diff --git a/src/styles/_inputcommon.scss b/src/styles/_inputcommon.scss
new file mode 100644
index 00000000..97e5cc53
--- /dev/null
+++ b/src/styles/_inputcommon.scss
@@ -0,0 +1,35 @@
+.input-content{
+ max-width: 1600px;
+ margin: 0 auto;
+ padding-bottom: 100px;
+ .input-wrap{
+ padding: 50px 50px 0;
+ h1{
+ margin-bottom: 20px;
+ }
+ .form-btn{
+ button{
+ margin-right: 10px;
+ }
+ }
+ .form-select{
+ width: 168px;
+ > div{
+ width: 100%;
+ }
+ }
+ .form-datepicker{
+ div{
+ margin-bottom: 10px;
+ }
+ }
+ .form-Arrow-btn,
+ .form-Check-btn{
+ padding: 10px;
+ background-color: #272727;
+ > button{
+ margin-bottom: 10px;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/styles/_layout.scss b/src/styles/_layout.scss
new file mode 100644
index 00000000..e33d75ea
--- /dev/null
+++ b/src/styles/_layout.scss
@@ -0,0 +1,216 @@
+.wrap{
+ display: flex;
+ flex-direction: column;
+ min-width: 1600px;
+ min-height: 100vh;
+ overflow-x: hidden;
+}
+.content{
+ flex: 1 1 auto;
+ padding-top: 46px;
+}
+
+// header
+// nav item ๊ณตํต
+@mixin navitem(){
+ position: relative;
+ display: flex;
+ align-items: center;
+ font-size: 14px;
+ color: #fff;
+ font-weight: 500;
+ height: 100%;
+ padding-right: 12px;
+ transition: color .17s ease-in-out;
+}
+header{
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ min-width: 1600px;
+ height: 46px;
+ background-color: #1C1C1C;
+ border-bottom: 1px solid #000;
+ z-index: 9999;
+ .header-inner{
+ display: flex;
+ align-items: center;
+ height: 100%;
+ padding: 0 40px;
+ .header-right{
+ display: flex;
+ height: 100%;
+ align-items: center;
+ .logo{
+ a{
+ display: block;
+ width: 232px;
+ height: 30px;
+ background: url(/static/images/common/Logo.svg)no-repeat center;
+ background-size: contain;
+ }
+ }
+ nav{
+ margin-left: 50px;
+ height: 100%;
+ .nav-list{
+ display: flex;
+ align-items: center;
+ height: 100%;
+ .nav-item{
+ position: relative;
+ margin-right: 62px;
+ height: 100%;
+ a{
+ @include navitem;
+ }
+ button{
+ @include navitem;
+ &:after{
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ width: 6px;
+ height: 10px;
+ background: url(/static/images/common/nav-arr.svg)no-repeat center;
+ transition: all .17s ease-in-out;
+ }
+ }
+ &:last-child{
+ margin-right: 0;
+ }
+ .nav-depth2{
+ position: absolute;
+ top: calc(100% - 2px);
+ left: 50%;
+ transform: translateX(-50%);
+ min-width: 100px;
+ background-color: #1C1C1C;
+ border: 1px solid #464646;
+ padding: 24px;
+ opacity: 0;
+ visibility: hidden;
+ transition: all .17s ease-in-out;
+ .nav-depth2-item{
+ margin-bottom: 10px;
+ transition: all .17s ease-in-out;
+ a{
+ font-size: 13px;
+ font-weight: normal;
+ white-space: nowrap;
+ }
+ &:last-child{
+ margin-bottom: 0;
+ }
+ &.mouse{
+ opacity: 0.55;
+ }
+ }
+ &::before{
+ content: '';
+ position: absolute;
+ top: -5px;
+ left: 50%;
+ transform: translateX(-50%) rotate(45deg);
+ width: 8px;
+ height: 8px;
+ background-color: #1c1c1c;
+ border-top: 1px solid #464646;
+ border-left: 1px solid #464646;
+ }
+ }
+ &.mouse{
+ > a{
+ color: rgba(255, 255, 255, 0.30);
+ }
+ > button{
+ color: rgba(255, 255, 255, 0.30);
+ &:after{
+ opacity: 0.3;
+ }
+ }
+ }
+ &:hover{
+ .nav-depth2{
+ opacity: 1;
+ visibility: visible;
+ }
+ > button{
+ &:after{
+ transform: translateY(-50%) rotate(90deg);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ .header-left{
+ margin-left: auto;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ .profile-box{
+ position: relative;
+ padding-left: 30px;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ margin-right: 20px;
+ cursor: pointer;
+ .profile{
+ font-size: 13px;
+ font-weight: normal;
+ color: #fff;
+ }
+ &::after{
+ content: '';
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ left: 0;
+ width: 24px;
+ height: 24px;
+ background: url(/static/images/common/profile_icon.svg)no-repeat center;
+ background-size: cover;
+ }
+ }
+ .sign-out-box{
+ position: relative;
+ padding-left: 30px;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ margin-right: 20px;
+ cursor: pointer;
+ .sign-out{
+ font-size: 13px;
+ font-weight: normal;
+ color: #fff;
+ }
+ &::after{
+ content: '';
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ left: 0;
+ width: 24px;
+ height: 24px;
+ background: url(../../public/static/images/common/signout_icon.svg)no-repeat center;
+ background-size: cover;
+ }
+ }
+ .select-box{
+ min-width: 165px;
+ margin-right: 8px;
+ >div{
+ width: 100%;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss
new file mode 100644
index 00000000..05b0e4a9
--- /dev/null
+++ b/src/styles/_modal.scss
@@ -0,0 +1,91 @@
+@keyframes mountpop{
+ from{opacity: 0; scale: 0.95;}
+ to{opacity: 1; scale: 1;}
+}
+@keyframes unmountpop{
+ from{opacity: 1; scale: 1;}
+ to{opacity: 0; scale: 0.95;}
+}
+
+.modal-pop-wrap{
+ position: fixed;
+ top: 200px;
+ right: 100px;
+ width: 100%;
+ min-width: 380px;
+ max-width: fit-content;
+ height: -webkit-fit-content;
+ height: -moz-fit-content;
+ height: fit-content;
+ border: 1px solid #000;
+ border-radius: 4px;
+ background-color: #272727;
+ z-index: 9999999;
+ &.sm{
+ max-width: 450px;
+ }
+ &.mount{
+ animation: mountpop .17s ease-in-out forwards;
+ }
+ &.unmount{
+ animation: unmountpop .17s ease-in-out forwards;
+ }
+}
+.modal-head{
+ display: flex;
+ align-items: center;
+ padding: 10px 24px;
+ background-color: #000;
+ cursor: pointer;
+ h1.title{
+ font-size: 13px;
+ color: #fff;
+ font-weight: 700;
+ }
+ .modal-close{
+ margin-left: auto;
+ color: #fff;
+ text-indent: -999999999px;
+ width: 10px;
+ height: 10px;
+ background: url(../../public/static/images/canvas/modal_close.svg)no-repeat center;
+ }
+}
+.modal-body{
+ padding: 15px;
+ .modal-btn-wrap{
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ button{
+ flex: 1;
+ }
+ }
+ .modal-check-btn-wrap{
+ margin-top: 15px;
+ .check-wrap-title{
+ font-size: 12px;
+ color: #fff;
+ font-weight: 600;
+ &.light{
+ font-weight: 400;
+ }
+ }
+ .flex-check-box{
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ margin-top: 15px;
+ &.for2{
+ button{
+ width: calc(50% - 5px);
+ }
+ }
+ &.for-line{
+ button{
+ flex: 1;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss
new file mode 100644
index 00000000..7dc13a69
--- /dev/null
+++ b/src/styles/_reset.scss
@@ -0,0 +1,431 @@
+* {
+ -webkit-text-size-adjust: none;
+ -moz-text-size-adjust: none;
+ -ms-text-size-adjust: none;
+ text-size-adjust: none;
+ box-sizing: content-box
+}
+
+*, ::after, ::before {
+ box-sizing: border-box;
+}
+
+html, body {
+ width: 100%;
+ height: 100%;
+ font-size: 16px;
+}
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font: inherit;
+ vertical-align: baseline;
+ font-family: 'Noto Sans JP', sans-serif;
+}
+
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+
+body {
+ line-height: 1.4;
+}
+
+body:first-of-type caption {
+ display: none;
+}
+
+ol, ul {
+ list-style: none;
+}
+
+blockquote, q {
+ quotes: none;
+}
+
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+table {
+ border-collapse: separate;
+ border-spacing: 0;
+ border: 0 none;
+}
+
+caption, th, td {
+ text-align: left;
+ font-weight: normal;
+ border: 0;
+}
+
+a {
+ cursor: pointer;
+ color: #000;
+}
+
+a, a:hover, a:active {
+ text-decoration: none;
+ -webkit-tap-highlight-color: transparent;
+}
+
+/*form_style*/
+input, select, textarea, button, a, label {
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+button, input[type=text], input[type=button] {
+ -webkit-appearance: none;
+ -webkit-border-radius: 0;
+ -webkit-appearance: none;
+ appearance: none;
+ border-radius: 0
+}
+
+input[type=checkbox], input[type=radio] {
+ box-sizing: border-box;
+ padding: 0;
+}
+
+input, select, button {
+ border: 0 none;
+ outline: none;
+ margin: 0;
+}
+
+select {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+select::-ms-expand {
+ display: none;
+}
+
+::-webkit-input-placeholder {
+ line-height: 1;
+ font-weight: 300;
+ font-size: 0.938rem;
+ letter-spacing: -0.6px;
+ color: #8b8b8b;
+}
+
+.log-box ::-webkit-input-placeholder {
+ color: #8b8b8b;
+}
+
+button {
+ background: transparent;
+ font-family: 'Noto Sans JP', sans-serif;
+ border: none;
+ padding: 0;
+ margin: 0;
+ line-height: 1.4;
+ color: inherit;
+ outline: none;
+ cursor: pointer;
+}
+
+
+// button
+.btn-frame {
+ display: inline-block;
+ padding: 0 10px;
+ height: 34px;
+ line-height: 34px;
+ border-radius: 2px;
+ color: #fff;
+ font-size: 12px;
+ font-weight: 400;
+ border: 1px solid #000;
+ text-align: center;
+ font-family: 'Pretendard', sans-serif;
+ transition: all .17s ease-in-out;
+ cursor: pointer;
+
+ &.block {
+ width: 100%;
+ }
+
+ &.small {
+ font-family: 'Noto Sans JP', sans-serif;
+ height: 30px;
+ line-height: 30px;
+ font-size: 13px;
+ }
+
+ &.deepgray {
+ background-color: #2C2C2C;
+ border: 1px solid #484848;
+ }
+
+ &.gray {
+ background-color: #3C3C3C;
+ border: 1px solid #545454;
+ }
+
+ &.dark {
+ background-color: #1C1C1C;
+ border: 1px solid #484848;
+ }
+
+ &.modal {
+ background-color: #272727;
+ border: 1px solid #484848;
+ color: #aaa;
+
+ &:hover {
+ background-color: #1083E3;
+ border: 1px solid #1083E3;
+ color: #fff;
+ font-weight: 500;
+ }
+ }
+
+ &.act {
+ background-color: #1083E3;
+ border: 1px solid #1083E3;
+ color: #fff;
+ font-weight: 500;
+ }
+
+ &.block {
+ display: block;
+ width: 100%;
+ }
+}
+
+// select
+.sort-select {
+ position: relative;
+ display: inline-block;
+ min-width: 100px;
+ height: 30px;
+ line-height: 30px;
+ padding: 0 10px;
+ background-color: #373737;
+ border: 1px solid #3F3F3F;
+ border-radius: 2px;
+ border-top-left-radius: 2px;
+ color: #fff;
+ cursor: pointer;
+
+ p {
+ font-size: 13px;
+ color: #fff;
+ height: 100%;
+ }
+
+ .select-item-wrap {
+ position: absolute;
+ top: 100%;
+ left: -1px;
+ clip-path: inset(0 0 100% 0);
+ width: calc(100% + 2px);
+ padding: 8px 0;
+ background-color: #373737;
+ border: 1px solid #3F3F3F;
+ border-radius: 2px;
+ transition: all 0.17s ease-in-out;
+ visibility: hidden;
+
+ .select-item {
+ display: flex;
+ align-items: center;
+ padding: 8px 20px;
+ line-height: 1.4;
+ transition: all .17s ease-in-out;
+
+ button {
+ font-size: 12px;
+ color: #fff;
+ line-height: 1.4;
+ }
+
+ &:hover {
+ background-color: #2C2C2C;
+ }
+ }
+ }
+
+ &::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 7px;
+ transform: translateY(-50%);
+ width: 10px;
+ height: 6px;
+ background: url(/static/images/common/select-arr.svg) no-repeat center;
+ background-size: cover;
+ transition: all .17s ease-in-out;
+ }
+
+ &.active {
+ .select-item-wrap {
+ clip-path: inset(0 0 0 0);
+ visibility: visible;
+ }
+
+ &:after {
+ transform: translateY(-50%) rotate(-180deg);
+ }
+ }
+}
+
+// input
+input[type=text] {
+ &.input-origin {
+ display: inline-block;
+ height: 30px;
+ line-height: 30px;
+ border-radius: 2px;
+ background-color: #313131;
+ color: #fff;
+ font-size: 12px;
+ font-weight: 500;
+ font-family: 'Pretendard', sans-serif;
+ padding: 0 10px;
+
+ &::placeholder {
+ font-size: 12px;
+ }
+ }
+}
+
+// date-picker
+.single-date {
+ input {
+ border-radius: 2px;
+ color: #fff;
+ font-size: 12px;
+ font-family: 'Pretendard', sans-serif;
+ background-color: #313131;
+ }
+}
+
+.range-date {
+ input {
+ border-radius: 2px;
+ color: #fff;
+ font-size: 12px;
+ font-family: 'Pretendard', sans-serif;
+ background-color: #313131;
+ }
+
+ .react-datepicker__input-container {
+ button {
+ &:after {
+ display: none;
+ }
+ }
+ }
+}
+
+// check-btn
+.check-btn {
+ display: flex;
+ align-items: center;
+ height: 30px;
+ background-color: #3A3A3A;
+ border-radius: 3px;
+ transition: all .17s ease-in-out;
+
+ .check-area {
+ flex: none;
+ width: 30px;
+ height: 100%;
+ border-right: 1px solid #272727;
+ background: url(../../public/static/images/canvas/check-grey.svg) no-repeat center;
+ background-size: 11px 9px;
+ }
+
+ .title-area {
+ padding: 0 10px;
+ font-size: 12px;
+ color: #898989;
+ font-weight: 400;
+ }
+
+ &.block {
+ width: 100%;
+ }
+
+ &:hover,
+ &.act {
+ background-color: #fff;
+
+ .check-area {
+ border-right: 1px solid #101010;
+ background: url(../../public/static/images/canvas/check-black.svg) no-repeat center;
+ }
+
+ .title-area {
+ color: #101010;
+ font-weight: 600;
+ }
+ }
+}
+
+// arr-btn
+.arr-btn {
+ display: block;
+ height: 30px;
+ border-radius: 3px;
+ background-color: #3A3A3A;
+ padding: 0 11px;
+ text-align: left;
+ transition: all .17s ease-in-out;
+
+ span {
+ position: relative;
+ font-size: 12px;
+ color: #898989;
+ font-weight: 400;
+ padding-right: 15px;
+
+ &:after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ width: 5px;
+ height: 8px;
+ background: url(../../public/static/images/canvas/arr_btn_ico.svg) no-repeat center;
+ }
+ }
+
+ &:hover,
+ &.act {
+ background-color: #fff;
+
+ span {
+ color: #101010;
+ font-weight: 500;
+
+ &:after {
+ background: url(../../public/static/images/canvas/arr_btn_ico_black.svg) no-repeat center;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/styles/_test.scss b/src/styles/_test.scss
index 55440362..9e542bbd 100644
--- a/src/styles/_test.scss
+++ b/src/styles/_test.scss
@@ -41,7 +41,7 @@
.grid-item {
width: 100%;
height: 100%;
- border: 1px solid black; /* ๊ทธ๋ฆฌ๋ ์ธ๊ฐ์ */
+ border: 1px solid black; /* ๊ทธ๋ฆฌ๋ ์ธ๊ฐ์ */
text-align: center; /* ๊ทธ๋ฆฌ๋ ๋ด ๊ฐ์ด๋ฐ ์ ๋ ฌ */
}
@@ -79,3 +79,9 @@
background-color: white;
color: black;
}
+
+.centered {
+ .ag-header-cell-label {
+ justify-content: center !important;
+ }
+}
diff --git a/src/styles/common.scss b/src/styles/common.scss
new file mode 100644
index 00000000..8152784c
--- /dev/null
+++ b/src/styles/common.scss
@@ -0,0 +1,2 @@
+@import 'fonts.scss';
+@import 'reset.scss';
\ No newline at end of file
diff --git a/src/styles/style.scss b/src/styles/style.scss
index 862bf204..67e19244 100644
--- a/src/styles/style.scss
+++ b/src/styles/style.scss
@@ -1,18 +1,3 @@
-@import '_test.scss';
-@import 'react-toastify/dist/ReactToastify.css';
-
-body {
- padding: 0;
- margin: 0;
- font-family: -apple-system, RoomNo, sans-serif;
-}
-
-.font-test {
- font-family: 'RoomNo';
-}
-
-@font-face {
- font-family: 'RoomNo';
- font-weight: 200;
- src: url('/fonts/Room No.703.ttf') format('truetype');
-}
+@import '_layout.scss';
+@import '_contents.scss';
+@import '_modal.scss';
\ No newline at end of file
diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js
index 2cae1ce9..29785c25 100644
--- a/src/util/qpolygon-utils.js
+++ b/src/util/qpolygon-utils.js
@@ -2781,6 +2781,12 @@ export const drawDirectionArrow = (polygon) => {
if (!direction) {
return
}
+
+ polygon.canvas
+ .getObjects()
+ .filter((obj) => obj.name === 'directionText' && obj.parent === polygon.arrow)
+ .forEach((obj) => polygon.canvas.remove(obj))
+
let arrow = null
let points = []
@@ -2788,13 +2794,13 @@ export const drawDirectionArrow = (polygon) => {
polygon.canvas.remove(polygon.arrow)
}
- let centerPoint = polygon.getCenterPoint()
+ let centerPoint = { x: polygon.width / 2 + polygon.left, y: polygon.height / 2 + polygon.top }
let stickeyPoint
- const polygonMaxX = Math.max(...polygon.points.map((point) => point.x))
- const polygonMinX = Math.min(...polygon.points.map((point) => point.x))
- const polygonMaxY = Math.max(...polygon.points.map((point) => point.y))
- const polygonMinY = Math.min(...polygon.points.map((point) => point.y))
+ const polygonMaxX = Math.max(...polygon.getCurrentPoints().map((point) => point.x))
+ const polygonMinX = Math.min(...polygon.getCurrentPoints().map((point) => point.x))
+ const polygonMaxY = Math.max(...polygon.getCurrentPoints().map((point) => point.y))
+ const polygonMinY = Math.min(...polygon.getCurrentPoints().map((point) => point.y))
switch (direction) {
case 'north':
@@ -2867,6 +2873,7 @@ export const drawDirectionArrow = (polygon) => {
polygon.arrow = arrow
polygon.canvas.add(arrow)
polygon.canvas.renderAll()
+ drawDirectionStringToArrow(polygon.canvas, 0)
}
/**
@@ -2874,7 +2881,7 @@ export const drawDirectionArrow = (polygon) => {
* @param canvas
* @param compass
*/
-export const drawDirectionStringToArrow = (canvas, compass, fontSize) => {
+export const drawDirectionStringToArrow = (canvas, compass = 0) => {
const arrows = canvas?.getObjects().filter((obj) => obj.name === 'arrow')
if (arrows.length === 0) {
@@ -3067,8 +3074,10 @@ const addTextByArrows = (arrows, txt, canvas) => {
originX: 'center',
originY: 'center',
name: 'directionText',
+ selectable: false,
left: arrow.stickeyPoint.x,
top: arrow.stickeyPoint.y,
+ parent: arrow,
})
canvas.add(text)
})
diff --git a/yarn.lock b/yarn.lock
index 1a73ec7a..62434324 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4107,7 +4107,7 @@ buffer@^6.0.3:
busboy@1.6.0:
version "1.6.0"
- resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz"
+ resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
dependencies:
streamsearch "^1.1.0"
@@ -4161,7 +4161,7 @@ client-only@0.0.1, client-only@^0.0.1:
resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz"
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
-clsx@^1.2.1:
+clsx@^1.1.1, clsx@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
@@ -5515,6 +5515,24 @@ react-dom@^18:
loose-envify "^1.1.0"
scheduler "^0.23.2"
+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"
+ integrity sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==
+
+react-draggable@^4.4.6:
+ version "4.4.6"
+ resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.6.tgz#63343ee945770881ca1256a5b6fa5c9f5983fe1e"
+ integrity sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==
+ dependencies:
+ clsx "^1.1.1"
+ prop-types "^15.8.1"
+
+react-icons@^5.3.0:
+ version "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:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"