Merge branch 'dev' into feature/test-jy

This commit is contained in:
Jaeyoung Lee 2024-09-11 16:42:53 +09:00
commit 1908432913
39 changed files with 754 additions and 248 deletions

View File

@ -2,6 +2,7 @@ NEXT_PUBLIC_TEST="테스트변수입니다. development"
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080" NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
# NEXT_PUBLIC_API_SERVER_PATH="http://localhost:8080" # NEXT_PUBLIC_API_SERVER_PATH="http://localhost:8080"
# NEXT_PUBLIC_API_SERVER_PATH="http://172.30.1.60:8080"
DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;password=Qwertqaz12345;trustServerCertificate=true" DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;password=Qwertqaz12345;trustServerCertificate=true"

Binary file not shown.

View File

@ -0,0 +1,3 @@
<svg width="5" height="8" viewBox="0 0 5 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 6.5L3.5 4L1 1.5" stroke="white" stroke-width="1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 164 B

View File

@ -0,0 +1,4 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 8.875L7 1.375M7 8.875C6.47483 8.875 5.49365 7.37927 5.125 7M7 8.875C7.52517 8.875 8.50635 7.37927 8.875 7" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13 10.375C13 12.2365 12.6115 12.625 10.75 12.625H3.25C1.3885 12.625 1 12.2365 1 10.375" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 448 B

View File

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="elements">
<path id="Icon" d="M3.625 12.25V8.875C3.625 8.46079 3.96079 8.125 4.375 8.125H9.625C10.0392 8.125 10.375 8.46079 10.375 8.875V12.625M8.875 4L4.375 4C3.96079 4 3.625 3.66421 3.625 3.25L3.625 1M12.6234 3.62342L10.3766 1.37658C10.1355 1.13546 9.80844 1 9.46745 1H2.28571C1.57563 1 1 1.57563 1 2.28571V11.7143C1 12.4244 1.57563 13 2.28571 13H11.7143C12.4244 13 13 12.4244 13 11.7143V4.53255C13 4.19156 12.8645 3.86454 12.6234 3.62342Z" stroke="white" stroke-linecap="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 598 B

View File

@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="elements">
<path id="Vector" d="M11.8055 1V2.87932C11.8055 3.05563 11.5851 3.13545 11.4722 3C10.3736 1.7725 8.777 1 7 1C3.68629 1 1 3.68629 1 7C1 10.3137 3.68629 13 7 13C10.3137 13 13 10.3137 13 7" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 377 B

View File

@ -0,0 +1,6 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="elements">
<path id="Rectangle 1705" d="M9.99992 5.2C9.99853 3.42574 9.97165 2.50673 9.45523 1.87746C9.3555 1.75593 9.24407 1.64451 9.12254 1.54478C8.45873 1 7.47249 1 5.5 1C3.52751 1 2.54127 1 1.87746 1.54477C1.75593 1.6445 1.64451 1.75593 1.54478 1.87746C1 2.54127 1 3.52751 1 5.5C1 7.47249 1 8.45873 1.54477 9.12254C1.6445 9.24406 1.75593 9.35549 1.87746 9.45522C2.50672 9.97165 3.42574 9.99852 5.2 9.99992" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector" d="M8.20019 4.69995C7.92405 4.69995 7.70019 4.92381 7.70019 5.19995C7.70019 5.47609 7.92405 5.69995 8.20019 5.69995V4.69995ZM10.0002 5.69995C10.2763 5.69995 10.5002 5.47609 10.5002 5.19995C10.5002 4.92381 10.2763 4.69995 10.0002 4.69995V5.69995ZM5.7002 8.19995C5.7002 7.92381 5.47634 7.69995 5.2002 7.69995C4.92405 7.69995 4.7002 7.92381 4.7002 8.19995H5.7002ZM4.7002 9.99995C4.7002 10.2761 4.92405 10.5 5.2002 10.5C5.47634 10.5 5.7002 10.2761 5.7002 9.99995H4.7002ZM6.74147 5.69571C7.01527 5.6598 7.20812 5.40874 7.17222 5.13494C7.13631 4.86114 6.88525 4.66829 6.61145 4.7042L6.74147 5.69571ZM5.65369 5.57581L5.33604 5.18967L5.33604 5.18967L5.65369 5.57581ZM4.70999 6.30149C4.65561 6.57222 4.831 6.83578 5.10173 6.89016C5.37247 6.94454 5.63602 6.76915 5.6904 6.49841L4.70999 6.30149ZM12.51 6.49841C12.5644 6.76915 12.8279 6.94454 13.0987 6.89016C13.3694 6.83578 13.5448 6.57222 13.4904 6.30149L12.51 6.49841ZM12.5467 5.57581L12.2291 5.96194L12.2291 5.96194L12.5467 5.57581ZM11.5889 4.7042C11.3151 4.66829 11.0641 4.86114 11.0282 5.13494C10.9923 5.40874 11.1851 5.6598 11.4589 5.69571L11.5889 4.7042ZM11.4589 12.5042C11.1851 12.5401 10.9923 12.7912 11.0282 13.065C11.0641 13.3388 11.3151 13.5316 11.5889 13.4957L11.4589 12.5042ZM12.5467 12.6241L12.8644 13.0102L12.5467 12.6241ZM13.4904 11.8984C13.5448 11.6277 13.3694 11.3641 13.0987 11.3097C12.8279 11.2554 12.5644 11.4308 12.51 11.7015L13.4904 11.8984ZM5.6904 11.7015C5.63603 11.4308 5.37247 11.2554 5.10173 11.3097C4.831 11.3641 4.65561 11.6277 4.70999 11.8984L5.6904 11.7015ZM5.65369 12.6241L5.97133 12.238L5.97133 12.238L5.65369 12.6241ZM6.61145 13.4957C6.88525 13.5316 7.13631 13.3388 7.17222 13.065C7.20812 12.7912 7.01527 12.5401 6.74147 12.5042L6.61145 13.4957ZM8.2002 12.5C7.92405 12.5 7.7002 12.7238 7.7002 13C7.7002 13.2761 7.92405 13.5 8.2002 13.5V12.5ZM10.0002 13.5C10.2763 13.5 10.5002 13.2761 10.5002 13C10.5002 12.7238 10.2763 12.5 10.0002 12.5V13.5ZM13.5002 8.19995C13.5002 7.92381 13.2763 7.69995 13.0002 7.69995C12.7241 7.69995 12.5002 7.92381 12.5002 8.19995H13.5002ZM12.5002 9.99995C12.5002 10.2761 12.7241 10.5 13.0002 10.5C13.2763 10.5 13.5002 10.2761 13.5002 9.99995H12.5002ZM8.20019 5.69995H10.0002V4.69995H8.20019V5.69995ZM4.7002 8.19995V9.99995H5.7002V8.19995H4.7002ZM6.61145 4.7042C6.11761 4.76895 5.68947 4.89892 5.33604 5.18967L5.97133 5.96194C6.12045 5.83927 6.33772 5.74865 6.74147 5.69571L6.61145 4.7042ZM5.6904 6.49841C5.7466 6.21864 5.83549 6.07369 5.97133 5.96194L5.33604 5.18967C4.97719 5.48487 4.79851 5.86077 4.70999 6.30149L5.6904 6.49841ZM13.4904 6.30149C13.4019 5.86077 13.2232 5.48487 12.8644 5.18967L12.2291 5.96194C12.3649 6.07369 12.4538 6.21864 12.51 6.49841L13.4904 6.30149ZM11.4589 5.69571C11.8627 5.74865 12.0799 5.83927 12.2291 5.96194L12.8644 5.18967C12.5109 4.89892 12.0828 4.76895 11.5889 4.7042L11.4589 5.69571ZM11.5889 13.4957C12.0828 13.4309 12.5109 13.301 12.8644 13.0102L12.2291 12.238C12.0799 12.3606 11.8627 12.4513 11.4589 12.5042L11.5889 13.4957ZM12.51 11.7015C12.4538 11.9813 12.3649 12.1262 12.2291 12.238L12.8644 13.0102C13.2232 12.715 13.4019 12.3391 13.4904 11.8984L12.51 11.7015ZM4.70999 11.8984C4.79851 12.3391 4.97719 12.715 5.33604 13.0102L5.97133 12.238C5.83548 12.1262 5.7466 11.9813 5.6904 11.7015L4.70999 11.8984ZM6.74147 12.5042C6.33771 12.4512 6.12045 12.3606 5.97133 12.238L5.33604 13.0102C5.68947 13.301 6.11761 13.4309 6.61145 13.4957L6.74147 12.5042ZM8.2002 13.5H10.0002V12.5H8.2002V13.5ZM12.5002 8.19995V9.99995H13.5002V8.19995H12.5002Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

View File

@ -1,13 +1,34 @@
'use client' 'use client'
import { useCurrentLocale } from '@/locales/client' import { useEffect } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
import { LocaleProvider } from './LocaleProvider' import { LocaleProvider } from './LocaleProvider'
import { useCurrentLocale } from '@/locales/client'
import ServerError from './error' import ServerError from './error'
import { ErrorBoundary } from 'next/dist/client/components/error-boundary' import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
import '@/styles/common.scss' import '@/styles/common.scss'
import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json'
export default function LocaleLayout({ children }) { export default function LocaleLayout({ children }) {
const locale = useCurrentLocale() const locale = useCurrentLocale()
const globalLocale = useRecoilValue(globalLocaleStore)
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
useEffect(() => {
console.log(globalLocale)
console.log(sessionStorage.getItem('hi'))
console.log(Object.keys(appMessageState).length)
// if (Object.keys(appMessageState).length === 0) {
if (globalLocale === 'ko') {
setAppMessageState(KO)
} else {
setAppMessageState(JA)
}
// }
}, [globalLocale])
return ( return (
<> <>

View File

@ -1,3 +1,24 @@
export const STEP = {
INITIAL_CANVAS_SETTING: 'initialCanvasSetting', // 배치면 초기설정
ROOF_COVERING: {
EXTERIOR_WALL_LINE: 'exteriorWallLine', // 외벽선 그리기
ROOF_SHAPE_SETTINGS: 'roofShapeSettings', // 지붕형상 설정
ROOF_SHAPE_EDITING: 'roofShapeEditing', // 지붕형상 편집
HELP_LINE_DRAWING: 'helpLineDrawing', // 보조선 그리기
}, // 지붕덮개
BATCH_CANVAS: {
BATCH_DRAWING: 'batchDrawing', // 배치면 그리기
SURFACE_SHAPE_BATCH: 'surfaceShapeBatch', // 면형상 배치
OBJECT_BATCH: 'objectBatch', // 오브젝트 배치
}, // 배치면
MODULE_CIRCUIT_SETTING: {
BASIC_SETTING: 'basicSetting', // 기본설정
CIRCUIT_TRESTLE_SETTING: 'circuitTrestleSetting', // 회로가대설정
}, // 모듈회로구성
ESTIMATE: 'estimate', // todo 견적서
POWER_GENERATION_SIMULATION: 'powerGenerationSimulation', // todo 발전 시뮬레이션
}
export const Mode = { export const Mode = {
DRAW_LINE: 'drawLine', // 기준선 긋기모드` DRAW_LINE: 'drawLine', // 기준선 긋기모드`
EDIT: 'edit', EDIT: 'edit',

View File

@ -9,8 +9,7 @@ import { useAxios } from '@/hooks/useAxios'
import { get, post } from '@/lib/Axios' import { get, post } from '@/lib/Axios'
export default function InitSettingsModal(props) { export default function InitSettingsModal(props) {
const [objectNo, setObjectNo] = useState('test123240909002') // const [objectNo, setObjectNo] = useState('test123240909003') //
const [lastRoofSeq, setLastRoofSeq] = useState(0) // roofSeq
const [open, setOpen] = useRecoilState(modalState) const [open, setOpen] = useRecoilState(modalState)
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
const [roofMaterials, setRoofMaterials] = useState([]) const [roofMaterials, setRoofMaterials] = useState([])
@ -18,7 +17,7 @@ export default function InitSettingsModal(props) {
roofDrawingSet: '1', roofDrawingSet: '1',
roofSizeSet: '1', roofSizeSet: '1',
roofAngleSet: 'slope', roofAngleSet: 'slope',
roofs: [], roofs: [{ roofSeq: '1', roofType: '3', roofWidth: '200', roofHeight: '200', roofGap: '0', roofLayout: 'parallel' }],
}) })
const modelProps = { const modelProps = {
@ -49,7 +48,8 @@ export default function InitSettingsModal(props) {
}) })
const roofsArray = res.some((item) => !item.roofSeq) const roofsArray = res.some((item) => !item.roofSeq)
? null // roofsArray null . ? // roofsArray
[{ roofSeq: '1', roofType: '3', roofWidth: '200', roofHeight: '200', roofGap: '0', roofLayout: 'parallel' }]
: res.map((item) => ({ : res.map((item) => ({
roofSeq: String(item.roofSeq), roofSeq: String(item.roofSeq),
roofType: String(item.roofType), roofType: String(item.roofType),
@ -69,14 +69,6 @@ export default function InitSettingsModal(props) {
// //
setBasicSettings({ ...patternData }) setBasicSettings({ ...patternData })
// roofSeq
if (roofsArray == null) {
//roofs() lastRoofSeq 1
setLastRoofSeq(1)
} else {
setLastRoofSeq(roofsArray.length + 1)
}
}) })
if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) {
@ -90,41 +82,8 @@ export default function InitSettingsModal(props) {
setBasicSettings(newBasicSetting) setBasicSettings(newBasicSetting)
} }
//
const addRoofSetting = () => {
if (basicSetting.roofs != null && basicSetting.roofs.length === 4) {
alert('지붕재는 최대 4종까지 선택할 수 있습니다.')
return
}
//roofs null
if (basicSetting.roofs == null) {
basicSetting.roofs = []
}
//
const newRoofSettings = {
//roofSeq: basicSetting.roofs.length + 1,
roofSeq: lastRoofSeq, // roofSeq 1
roofType: '3',
roofWidth: '200',
roofHeight: '200',
roofGap: '0',
roofLayout: 'parallel',
}
setBasicSettings((prevState) => ({
...prevState,
roofs: [...prevState.roofs, newRoofSettings],
}))
setLastRoofSeq(newRoofSettings.roofSeq + 1) // roofSeq
}
// //
const handleRoofSettings = (id, event) => { const handleRoofSettings = (id, event) => {
console.log(id)
// roofs // roofs
const updatedRoofs = [...basicSetting.roofs] const updatedRoofs = [...basicSetting.roofs]
@ -144,13 +103,6 @@ export default function InitSettingsModal(props) {
roofs: updatedRoofs, roofs: updatedRoofs,
})) }))
} }
// const roof = basicSetting.roofs.map((roof, i) => (id === roof.roofSeq ? { ...roof, [event.target.name]: event.target.value } : roof))
// setBasicSettings((prevState) => ({
// ...prevState,
// roofs: [...roof],
// }))
} }
// //
@ -176,17 +128,6 @@ export default function InitSettingsModal(props) {
//await handleSelect() //await handleSelect()
} }
// id targetId
const onRemove = async (targetId) => {
console.log(targetId)
setBasicSettings((prevState) => ({
...prevState,
roofs: prevState.roofs.filter((roof) => roof.roofSeq !== targetId),
}))
// setBasicSettings({ ...newRoofSettings }) // setData()
}
return ( return (
<> <>
<div className="container mx-auto mt-10 p-6 bg-white shadow-lg rounded-lg"> <div className="container mx-auto mt-10 p-6 bg-white shadow-lg rounded-lg">
@ -236,15 +177,7 @@ export default function InitSettingsModal(props) {
</RadioGroup> </RadioGroup>
</div> </div>
</div> </div>
<RadioGroup label="지붕재 추가(단위 : mm)" />
<div className="flex space-x-4">지붕재 추가(단위 : mm)</div>
<div className="flex items-center mb-4">
<button className="px-3 py-1 bg-blue-500 text-white rounded mr-3" onClick={addRoofSetting}>
Add
</button>
<span className="text-sm text-gray-500"> 지붕재는 최대 4종까지 선택할 있습니다.</span>
</div>
{/* Roofs Array Rendering */} {/* Roofs Array Rendering */}
{basicSetting.roofs && {basicSetting.roofs &&
basicSetting.roofs.map((roof, index) => { basicSetting.roofs.map((roof, index) => {
@ -257,7 +190,7 @@ export default function InitSettingsModal(props) {
name="roofType" name="roofType"
onChange={(e) => handleRoofSettings(roof.roofSeq, e)} onChange={(e) => handleRoofSettings(roof.roofSeq, e)}
items={roofMaterials} items={roofMaterials}
defaultSelectedKeys={roof.roofType ? roof.roofType : ''} defaultSelectedKeys={roof.roofType ? [roof.roofType] : []}
selectedKeys={roof.roofType} selectedKeys={roof.roofType}
value={roof.roofType} value={roof.roofType}
> >
@ -309,16 +242,6 @@ export default function InitSettingsModal(props) {
<Radio value="cascade">계단식</Radio> <Radio value="cascade">계단식</Radio>
</RadioGroup> </RadioGroup>
</div> </div>
<div className="flex space-x-4">
<Button
size="sm"
onClick={() => {
onRemove(roof.roofSeq)
}}
>
삭제
</Button>
</div>
</div> </div>
) )
})} })}

View File

@ -119,7 +119,7 @@ export default function Playground() {
<div className="test"> <div className="test">
<p className="text-white">Sass 테스트입니다.</p> <p className="text-white">Sass 테스트입니다.</p>
</div> </div>
<div>{getMessage('hi')}</div> <div dangerouslySetInnerHTML={{ __html: getMessage('welcome', ['<span style="color: red">test</span>']) }}></div>
<div> <div>
<h1>React ColorPicker</h1> <h1>React ColorPicker</h1>
<ColorPicker color={color} setColor={setColor} /> <ColorPicker color={color} setColor={setColor} />

View File

@ -5,39 +5,73 @@ import { setSession } from '@/lib/authActions'
import { redirect } from 'next/navigation' import { redirect } from 'next/navigation'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { Button } from '@nextui-org/react' import { Button, Switch } from '@nextui-org/react'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { globalLocaleStore } from '@/store/localeAtom'
import { modalContent, modalState } from '@/store/modalAtom' import { modalContent, modalState } from '@/store/modalAtom'
import { useState } from 'react'
export default function Login(props) { export default function Login(props) {
const { currentLocale } = props const { currentLocale } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [globalLocaleState, setGlbalLocaleState] = useRecoilState(globalLocaleStore)
const [isSelected, setIsSelected] = useState(globalLocaleState === 'ko' ? true : false)
const handleSelected = () => {
if (isSelected) {
setGlbalLocaleState('ja')
} else {
setGlbalLocaleState('ko')
}
setIsSelected(!isSelected)
}
// login process // login process
const loginProcess = async (formData) => { const loginProcess = async (formData) => {
const param = { const param = {
langCd: currentLocale, // langCd: currentLocale
langCd: globalLocaleState,
lastEditUser: formData.get('id'), lastEditUser: formData.get('id'),
loginId: formData.get('id'), loginId: formData.get('id'),
pwd: formData.get('password'), pwd: formData.get('password'),
} }
await post({ url: '/api/login/v1.0/login', data: param }).then((res) => { // await post({ url: '/api/login/v1.0/login', data: param }).then((res) => {
if (res) { // if (res) {
if (res.result.resultCode == 'S') { // if (res.result.resultCode == 'S') {
// console.log('res.data', res.data) // // console.log('res.data', res.data)
// // //
// if (res.data.pwdInitYn != 'Y') { // // if (res.data.pwdInitYn != 'Y') {
// alert(' ') // // alert(' ')
// // } else {
// setSession(res.data)
// redirect('/')
// // }
// } else { // } else {
setSession(res.data) // alert(res.result.resultMsg)
redirect('/')
// } // }
} else { // }
alert(res.result.resultMsg) // })
}
} //
setSession({
userId: 'NEW016610',
saleStoreId: null,
name: null,
mail: null,
tel: null,
storeId: 'TEMP02',
userNm: 'ㅇㅇ6610',
userNmKana: '신규사용자 16610',
category: '인상6610',
telNo: '336610',
fax: null,
email: 't10t@naver.com',
pwdInitYn: 'N',
}) })
redirect('/')
//
} }
// //
@ -174,6 +208,12 @@ export default function Login(props) {
{getMessage('login.init_password.btn')} {getMessage('login.init_password.btn')}
</Button> </Button>
</p> </p>
<div className="flex align-center mt-2">
<Switch isSelected={isSelected} onValueChange={handleSelected}>
{isSelected ? 'Current Locale: KO' : 'Current Locale: JA'}
</Switch>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -14,7 +14,7 @@ export default function QContextMenu(props) {
if (activeObject) { if (activeObject) {
if (activeObject.initOptions) { if (activeObject.initOptions) {
// //
if (activeObject.initOptions.name.indexOf('guide') > -1) { if (activeObject.initOptions?.name?.indexOf('guide') > -1) {
contextType = 'surface' // contextType = 'surface' //
} }
} }

View File

@ -1,7 +1,15 @@
export default function CanvasFrame () { import { useCanvas } from '@/hooks/useCanvas'
return( import { useRef } from 'react'
<div className="canvas-frame"> import { useEvent } from '@/hooks/useEvent'
<canvas></canvas>
export default function CanvasFrame() {
const canvasRef = useRef(null)
useCanvas('canvas')
useEvent()
return (
<div className="canvas-frame" style={{ display: 'flex', justifyContent: 'center' }}>
<canvas ref={canvasRef} id={'canvas'}></canvas>
</div> </div>
) )
} }

View File

@ -1,11 +1,16 @@
'use client' 'use client'
import { useState } from 'react' import { useState } from 'react'
import MenuDepth01 from './MenuDepth01' import MenuDepth01 from './MenuDepth01'
import { useRecoilState } from 'recoil'
import { modalState } from '@/store/modalAtom'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { useMessage } from '@/hooks/useMessage'
export default function CanvasMenu({ setModalOpen }) { export default function CanvasMenu() {
const [modalOption, setModalOption] = useRecoilState(modalState) //modal state
const [menuNumber, setMenuNumber] = useState(null) const [menuNumber, setMenuNumber] = useState(null)
const [vertical, setVertical] = useState(true) const [vertical, setVertical] = useState(true)
const { getMessage } = useMessage()
const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }]
const onClickNav = (number) => { const onClickNav = (number) => {
setMenuNumber(number) setMenuNumber(number)
@ -14,60 +19,69 @@ export default function CanvasMenu({ setModalOpen }) {
} }
} }
return ( return (
<div className={`canvas-menu-wrap ${menuNumber !== null ? 'active' : ''}`}> <div className={`canvas-menu-wrap ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
<div className="canvas-menu-inner"> <div className="canvas-menu-inner">
<ul className="canvas-menu-list"> <ul className="canvas-menu-list">
<li className={`canvas-menu-item ${menuNumber === 0 ? 'active' : ''}`} onClick={() => onClickNav(0)}> <li className={`canvas-menu-item ${menuNumber === 0 ? 'active' : ''}`} onClick={() => onClickNav(0)}>
<button> <button>
<span className="menu-icon con00"></span>配置面 初期設定 <span className="menu-icon con00"></span>
{getMessage('plan.menu.plan.drawing')}
</button> </button>
</li> </li>
<li className={`canvas-menu-item ${menuNumber === 1 ? 'active' : ''}`} onClick={() => onClickNav(1)}> <li className={`canvas-menu-item ${menuNumber === 1 ? 'active' : ''}`} onClick={() => onClickNav(1)}>
<button> <button>
<span className="menu-icon con01"></span>配置面 初期設定 <span className="menu-icon con01"></span>
{getMessage('plan.menu.placement.surface.initial.setting')}
</button> </button>
</li> </li>
<li className={`canvas-menu-item ${menuNumber === 2 ? 'active' : ''}`} onClick={() => onClickNav(2)}> <li className={`canvas-menu-item ${menuNumber === 2 ? 'active' : ''}`} onClick={() => onClickNav(2)}>
<button> <button>
<span className="menu-icon con02"></span>配置面 初期設定 <span className="menu-icon con02"></span>
{getMessage('plan.menu.root.cover')}
</button> </button>
</li> </li>
<li className={`canvas-menu-item ${menuNumber === 3 ? 'active' : ''}`} onClick={() => onClickNav(3)}> <li className={`canvas-menu-item ${menuNumber === 3 ? 'active' : ''}`} onClick={() => onClickNav(3)}>
<button> <button>
<span className="menu-icon con03"></span>配置面 <span className="menu-icon con03"></span>
{getMessage('plan.menu.placement.surface')}
</button> </button>
</li> </li>
<li className={`canvas-menu-item ${menuNumber === 4 ? 'active' : ''}`} onClick={() => onClickNav(4)}> <li className={`canvas-menu-item ${menuNumber === 4 ? 'active' : ''}`} onClick={() => onClickNav(4)}>
<button> <button>
<span className="menu-icon con04"></span>モジュール回路構成 <span className="menu-icon con04"></span>
{getMessage('plan.menu.module.circuit.setting')}
</button> </button>
</li> </li>
<li className={`canvas-menu-item ${menuNumber === 5 ? 'active' : ''}`} onClick={() => onClickNav(5)}> <li className={`canvas-menu-item ${menuNumber === 5 ? 'active' : ''}`} onClick={() => onClickNav(5)}>
<button> <button>
<span className="menu-icon con06"></span>見積 <span className="menu-icon con06"></span>
{getMessage('plan.menu.estimate')}
</button> </button>
</li> </li>
<li className={`canvas-menu-item ${menuNumber === 6 ? 'active' : ''}`} onClick={() => onClickNav(6)}> <li className={`canvas-menu-item ${menuNumber === 6 ? 'active' : ''}`} onClick={() => onClickNav(6)}>
<button> <button>
<span className="menu-icon con05"></span>発展シミュレーション <span className="menu-icon con05"></span>
{getMessage('plan.menu.simulation')}
</button> </button>
</li> </li>
</ul> </ul>
<div className="canvas-side-btn-wrap"> <div className="canvas-side-btn-wrap">
{menuNumber !== 6 && menuNumber !== 5 && (
<>
<div className="btn-from"> <div className="btn-from">
<button className="btn01 "></button> <button className="btn01"></button>
<button className="btn02 active"></button> <button className="btn02 active"></button>
<button className="btn03"></button> <button className="btn03 "></button>
</div> </div>
<div className="vertical-horizontal"> <div className={`vertical-horizontal ${vertical ? 'on' : ''}`}>
<span>垂直水平モード</span> <span>{getMessage('plan.mode.vertical.horizontal')}</span>
<button onClick={() => setVertical(!vertical)}>{vertical ? 'ON' : 'OFF'}</button> <button onClick={() => setVertical(!vertical)}>{vertical ? 'ON' : 'OFF'}</button>
</div> </div>
<div className="select-box"> <div className="select-box">
<QSelectBox title={'瓦53A'} option={SelectOption} /> <QSelectBox title={'瓦53A'} option={SelectOption} />
</div> </div>
<div className="btn-from"> <div className="btn-from">
<button className="btn04" onClick={() => setModalOpen('option')}></button> <button className="btn04" onClick={() => setModalOption({ ...modalOption, option: true })}></button>
<button className="btn05"></button> <button className="btn05"></button>
<button className="btn06"></button> <button className="btn06"></button>
</div> </div>
@ -81,16 +95,51 @@ export default function CanvasMenu({ setModalOpen }) {
<button className="btn08"></button> <button className="btn08"></button>
<button className="btn09"></button> <button className="btn09"></button>
</div> </div>
</>
)}
{menuNumber === 5 && (
<>
<div className="ico-btn-from">
<button className="btn-frame gray ico-flx act">
<span className="ico ico01"></span>
<span>{getMessage('plan.menu.estimate.roof.alloc')}</span>
</button>
<button className="btn-frame gray ico-flx">
<span className="ico ico02"></span>
<span>{getMessage('plan.menu.estimate.save')}</span>
</button>
<button className="btn-frame gray ico-flx">
<span className="ico ico03"></span>
<span>{getMessage('plan.menu.estimate.reset')}</span>
</button>
<button className="btn-frame gray ico-flx">
<span className="ico ico04"></span>
<span>{getMessage('plan.menu.estimate.copy')}</span>
</button>
</div>
</>
)}
{menuNumber === 6 && (
<>
<div className="ico-btn-from">
<button className="btn-frame gray ico-flx">
<span className="ico ico01"></span>
<span>{getMessage('plan.menu.simulation.excel')}</span>
</button>
<button className="btn-frame gray ico-flx">
<span className="ico ico01"></span>
<span>{getMessage('plan.menu.simulation.pdf')}</span>
</button>
</div>
</>
)}
</div> </div>
</div> </div>
<div className={`canvas-depth2-wrap ${menuNumber !== null ? 'active' : ''}`}> <div className={`canvas-depth2-wrap ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
{menuNumber === 0 && <MenuDepth01 />}
{menuNumber === 1 && <MenuDepth01 />}
{menuNumber === 2 && <MenuDepth01 />} {menuNumber === 2 && <MenuDepth01 />}
{menuNumber === 3 && <MenuDepth01 />} {menuNumber === 3 && <MenuDepth01 />}
{menuNumber === 4 && <MenuDepth01 />} {menuNumber === 4 && <MenuDepth01 />}
{menuNumber === 5 && <MenuDepth01 />}
{menuNumber === 6 && <MenuDepth01 />}
</div> </div>
</div> </div>
) )

View File

@ -1,9 +1,10 @@
'use client' 'use client'
import CanvasMenu from '@/components/floor-plan/CanvasMenu' import CanvasMenu from '@/components/floor-plan/CanvasMenu'
import CanvasLayout from '@/components/floor-plan/CanvasLayout'
import SettingModal01 from '@/components/floor-plan/modal/settoing01/SettingModal01' import SettingModal01 from '@/components/floor-plan/modal/settoing01/SettingModal01'
import { useState } from 'react' import { useState } from 'react'
import CanvasLayout from '@/components/floor-plan/CanvasLayout'
import '@/styles/contents.scss'
export default function FloorPlan() { export default function FloorPlan() {
const [modalOpen, setModalOpen] = useState('option') const [modalOpen, setModalOpen] = useState('option')

View File

@ -1,8 +1,10 @@
'use client' 'use client'
import { ToggleonMouse } from '@/components/header/Header' import { ToggleonMouse } from '@/components/header/Header'
import { useMessage } from '@/hooks/useMessage'
export default function MenuDepth01() { export default function MenuDepth01() {
const { getMessage } = useMessage()
return ( return (
<div className="canvas-depth2-inner"> <div className="canvas-depth2-inner">
<ul className="canvas-depth2-list"> <ul className="canvas-depth2-list">
@ -30,7 +32,7 @@ export default function MenuDepth01() {
</ul> </ul>
<ul className="canvas-depth2-btn-list"> <ul className="canvas-depth2-btn-list">
<li className="depth2-btn-box" onMouseEnter={(e) => ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}> <li className="depth2-btn-box" onMouseEnter={(e) => ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}>
<button>屋根面の割り当て</button> <button>{getMessage('plan.menu.estimate.roof.alloc')}</button>
</li> </li>
<li className="depth2-btn-box" onMouseEnter={(e) => ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}> <li className="depth2-btn-box" onMouseEnter={(e) => ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}>
<button>屋根材の設定と変更</button> <button>屋根材の設定と変更</button>

View File

@ -1,9 +1,11 @@
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { settingModalFirstOptionsState } from '@/store/settingAtom' import { settingModalFirstOptionsState } from '@/store/settingAtom'
import { useMessage } from '@/hooks/useMessage'
export default function FirstOption() { export default function FirstOption() {
const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalFirstOptionsState) const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalFirstOptionsState)
const { option1, option2 } = settingsModalOptions const { option1, option2 } = settingsModalOptions
const { getMessage } = useMessage()
const onClickOption = (option) => { const onClickOption = (option) => {
option.selected = !option.selected option.selected = !option.selected
@ -13,23 +15,23 @@ export default function FirstOption() {
return ( return (
<> <>
<div className="modal-check-btn-wrap"> <div className="modal-check-btn-wrap">
<h3 className="check-wrap-title light">図面に表示する項目をクリックすると適用されます</h3> <h3 className="check-wrap-title light">{getMessage('modal.canvas.setting.first.option.info')}</h3>
<div className="flex-check-box for2"> <div className="flex-check-box for2">
{settingsModalOptions?.option1?.map((item) => ( {settingsModalOptions?.option1?.map((item) => (
<button key={item.id} className={`check-btn ${item.selected ? 'act' : ''}`} onClick={(e) => onClickOption(item)}> <button key={item.id} className={`check-btn ${item.selected ? 'act' : ''}`} onClick={(e) => onClickOption(item)}>
<span className="check-area"></span> <span className="check-area"></span>
<span className="title-area">{item.name}</span> <span className="title-area">{getMessage(item.name)}</span>
</button> </button>
))} ))}
</div> </div>
</div> </div>
<div className="modal-check-btn-wrap"> <div className="modal-check-btn-wrap">
<h3 className="check-wrap-title">画面表示</h3> <h3 className="check-wrap-title">{getMessage('modal.canvas.setting.first.option.display')}</h3>
<div className="flex-check-box for-line"> <div className="flex-check-box for-line">
{settingsModalOptions?.option2?.map((item) => ( {settingsModalOptions?.option2?.map((item) => (
<button key={item.id} className={`check-btn ${item.selected ? 'act' : ''}`} onClick={(e) => onClickOption(item)}> <button key={item.id} className={`check-btn ${item.selected ? 'act' : ''}`} onClick={(e) => onClickOption(item)}>
<span className="check-area"></span> <span className="check-area"></span>
<span className="title-area">{item.name}</span> <span className="title-area">{getMessage(item.name)}</span>
</button> </button>
))} ))}
</div> </div>

View File

@ -4,6 +4,7 @@ import { useState } from 'react'
import FirstOption from './FirstOption' import FirstOption from './FirstOption'
import WithDraggable from '@/components/common/draggable/withDraggable' import WithDraggable from '@/components/common/draggable/withDraggable'
import SecondOption from '@/components/floor-plan/modal/settoing01/SecondOption' import SecondOption from '@/components/floor-plan/modal/settoing01/SecondOption'
import { useMessage } from '@/hooks/useMessage'
export default function SettingModal01({ modalOpen, setModalOpen }) { export default function SettingModal01({ modalOpen, setModalOpen }) {
const [buttonAct, setButtonAct] = useState(1) const [buttonAct, setButtonAct] = useState(1)
@ -15,12 +16,13 @@ export default function SettingModal01({ modalOpen, setModalOpen }) {
setClose(false) setClose(false)
}, 180) }, 180)
} }
const { getMessage } = useMessage()
return ( return (
<WithDraggable isShow={true}> <WithDraggable isShow={true}>
<div className={`modal-pop-wrap sm ${modalOpen === 'option' && close === false ? 'mount' : ''}${close ? 'unmount' : ''} `}> <div className={`modal-pop-wrap sm ${modalOpen === 'option' && close === false ? 'mount' : ''}${close ? 'unmount' : ''} `}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">Canvas設定</h1> <h1 className="title">{getMessage('modal.canvas.setting')}</h1>
<button className="modal-close" onClick={HandleClickClose}> <button className="modal-close" onClick={HandleClickClose}>
닫기 닫기
</button> </button>
@ -28,11 +30,11 @@ export default function SettingModal01({ modalOpen, setModalOpen }) {
<div className="modal-body"> <div className="modal-body">
<div className="modal-btn-wrap"> <div className="modal-btn-wrap">
<button className={`btn-frame modal ${buttonAct === 1 ? 'act' : ''}`} onClick={() => setButtonAct(1)}> <button className={`btn-frame modal ${buttonAct === 1 ? 'act' : ''}`} onClick={() => setButtonAct(1)}>
ディスプレイ設定 {getMessage('modal.canvas.setting.display')}
</button> </button>
<button className={`btn-frame modal ${buttonAct === 2 ? 'act' : ''}`} onClick={() => setButtonAct(2)}> <button className={`btn-frame modal ${buttonAct === 2 ? 'act' : ''}`} onClick={() => setButtonAct(2)}>
フォントと図面サイズの設定 {getMessage('modal.canvas.setting.font.plan')}
</button> </button>
</div> </div>
{buttonAct === 1 && <FirstOption />} {buttonAct === 1 && <FirstOption />}

View File

@ -2,6 +2,7 @@
import Link from 'next/link' import Link from 'next/link'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { usePathname } from 'next/navigation' import { usePathname } from 'next/navigation'
import { useMessage } from '@/hooks/useMessage'
export const ToggleonMouse = (e, act, target) => { export const ToggleonMouse = (e, act, target) => {
const listWrap = e.target.closest(target) const listWrap = e.target.closest(target)
@ -19,6 +20,7 @@ export const ToggleonMouse = (e, act, target) => {
} }
export default function Header() { export default function Header() {
const { getMessage } = useMessage()
const pathName = usePathname() const pathName = usePathname()
if (pathName.includes('login') || pathName.includes('join')) { if (pathName.includes('login') || pathName.includes('join')) {
return null return null
@ -39,28 +41,28 @@ export default function Header() {
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')}
> >
<Link href={'#'}>ホームへ</Link> <Link href={'#'}>{getMessage('header.menus.home')}</Link>
</li> </li>
<li <li
className="nav-item" className="nav-item"
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')}
> >
<button>物品及び図面管理</button> <button>{getMessage('header.menus.management')}</button>
<ul className="nav-depth2"> <ul className="nav-depth2">
<li <li
className="nav-depth2-item" className="nav-depth2-item"
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
> >
<Link href={'#'}>新規物件登録</Link> <Link href={'#'}>{getMessage('header.menus.management.stuff')}</Link>
</li> </li>
<li <li
className="nav-depth2-item" className="nav-depth2-item"
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
> >
<Link href={'#'}>モノ/図面管理</Link> <Link href={'#'}>{getMessage('header.menus.management.plan')}</Link>
</li> </li>
</ul> </ul>
</li> </li>
@ -69,28 +71,28 @@ export default function Header() {
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')}
> >
<button>コミュニティ</button> <button>{getMessage('header.menus.community')}</button>
<ul className="nav-depth2"> <ul className="nav-depth2">
<li <li
className="nav-depth2-item" className="nav-depth2-item"
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
> >
<Link href={'#'}>お知らせ</Link> <Link href={'#'}>{getMessage('header.menus.community.notice')}</Link>
</li> </li>
<li <li
className="nav-depth2-item" className="nav-depth2-item"
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
> >
<Link href={'#'}>FAQ</Link> <Link href={'#'}>{getMessage('header.menus.community.faq')}</Link>
</li> </li>
<li <li
className="nav-depth2-item" className="nav-depth2-item"
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
> >
<Link href={'#'}>素材のダウンロード</Link> <Link href={'#'}>{getMessage('header.menus.community.archive')}</Link>
</li> </li>
</ul> </ul>
</li> </li>
@ -102,13 +104,13 @@ export default function Header() {
<button className="profile">Kim Ji Young</button> <button className="profile">Kim Ji Young</button>
</div> </div>
<div className="sign-out-box"> <div className="sign-out-box">
<button className="sign-out">ログアウト</button> <button className="sign-out">{getMessage('header.logout')}</button>
</div> </div>
<div className="select-box"> <div className="select-box">
<QSelectBox title={'Q.ORDER'} option={SelectOption} /> <QSelectBox title={'Q.ORDER'} option={SelectOption} />
</div> </div>
<div className="btn-wrap"> <div className="btn-wrap">
<button className="btn-frame small dark">移動</button> <button className="btn-frame small dark">{getMessage('header.go')}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -8,7 +8,7 @@ import { useMessage } from '@/hooks/useMessage'
import StuffQGrid from './StuffQGrid' import StuffQGrid from './StuffQGrid'
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { stuffSearchState } from '@/store/stuffAtom' import { stuffSearchState } from '@/store/stuffAtom'
import { queryStringFormatter } from '@/util/common-utils' import { queryStringFormatter, isEmptyArray } from '@/util/common-utils'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import isLeapYear from 'dayjs/plugin/isLeapYear' // import isLeapYear from 'dayjs/plugin/isLeapYear' //
dayjs.extend(isLeapYear) dayjs.extend(isLeapYear)
@ -288,13 +288,13 @@ export default function Stuff() {
// let size // let size
// let pageCount // let pageCount
const apiUrl = `/api/object/v1.0/object?saleStoreId=201TES01&${queryStringFormatter(params)}` const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}`
await get({ await get({
url: apiUrl, url: apiUrl,
}).then((res) => { }).then((res) => {
if (res.length > 0) { if (!isEmptyArray(res)) {
console.log('API결과:::::::', res) console.log('화면진입API결과::', res)
setGridProps({ ...gridProps, gridData: res, count: res.length }) setGridProps({ ...gridProps, gridData: res, count: res.length })
setGridCount(res.length) setGridCount(res.length)
} }
@ -308,11 +308,13 @@ export default function Stuff() {
if (stuffSearchParams?.code === 'E') { if (stuffSearchParams?.code === 'E') {
console.log('조회 눌럿을때 ::::::::::::::', stuffSearchParams) console.log('조회 눌럿을때 ::::::::::::::', stuffSearchParams)
async function fetchData() { async function fetchData() {
const apiUrl = `/api/object/v1.0/object?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}` const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}`
await get({ url: apiUrl }).then((res) => { await get({ url: apiUrl }).then((res) => {
console.log('API결과:::::::', res) console.log('API결과:::::::', res)
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res.length }) setGridProps({ ...gridProps, gridData: res, count: res.length })
setGridCount(res.length) setGridCount(res.length)
}
}) })
} }
fetchData() fetchData()

View File

@ -5,7 +5,7 @@ import { useRouter, useSearchParams } from 'next/navigation'
import { Input, RadioGroup, Radio, Button, Autocomplete, AutocompleteItem, Select, SelectItem, Checkbox, Textarea, button } from '@nextui-org/react' import { Input, RadioGroup, Radio, Button, Autocomplete, AutocompleteItem, Select, SelectItem, Checkbox, Textarea, button } from '@nextui-org/react'
import Link from 'next/link' import Link from 'next/link'
import { get } from '@/lib/Axios' import { get } from '@/lib/Axios'
import { queryStringFormatter } from '@/util/common-utils' import { queryStringFormatter, isEmptyArray } from '@/util/common-utils'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { useForm } from 'react-hook-form' import { useForm } from 'react-hook-form'
export default function StuffDetail() { export default function StuffDetail() {
@ -29,10 +29,10 @@ export default function StuffDetail() {
windSpeed: '', // windSpeed: '', //
snowCover: '', // snowCover: '', //
coldAreaChk: false, // coldAreaChk: false, //
surfaceType: '', //( / ) surfaceType: 'Ⅲ・Ⅳ', //( / )
saltAreaChk: false, // saltAreaChk: false, //
installHeight: '', // installHeight: '', //
powerConTerms: '', // powerConTerms: '0', //( / )
remark: '', // remark: '', //
tempFlag: 'T', //(1) (0) tempFlag: 'T', //(1) (0)
} }
@ -42,6 +42,9 @@ export default function StuffDetail() {
const form = { register, setValue, getValues, handleSubmit, resetField, control, watch } const form = { register, setValue, getValues, handleSubmit, resetField, control, watch }
const [prefCodeList, setPrefCodeList] = useState([]) //
const [prefValue, setPrefValue] = useState('')
const [receiveUser, setReceiveUser] = useState('') // const [receiveUser, setReceiveUser] = useState('') //
const [name2, setName2] = useState('') // const [name2, setName2] = useState('') //
const [name3, setName3] = useState('') // const [name3, setName3] = useState('') //
@ -74,18 +77,21 @@ export default function StuffDetail() {
const [detailData, setDetailData] = useState({}) const [detailData, setDetailData] = useState({})
useEffect(() => { useEffect(() => {
get({ url: '/api/object/prefecture/list' }).then((res) => {
if (!isEmptyArray(res)) {
console.log('도도부현API 결과:::', res)
setPrefCodeList(res)
}
})
// console.log(':::::::::', searchParams.get('objectNo')) // console.log(':::::::::', searchParams.get('objectNo'))
console.log('물건번호::::', objectNo) // console.log('::::', objectNo)
if (objectNo) { if (objectNo) {
// console.log('::', objectNo)
setEditMode('EDIT') setEditMode('EDIT')
if (objectNo.substring(0, 1) === 'R') { if (objectNo.substring(0, 1) === 'R') {
setIsFormValid(true) setIsFormValid(true)
} }
// 1 get({ url: `/api/object/${objectNo}/detail` }).then((res) => {
//API
get({ url: `/api/object/v1.0/object/${objectNo}/1` }).then((res) => {
if (res != null) { if (res != null) {
// console.log('res:::::::', res) // console.log('res:::::::', res)
setDetailData(res) setDetailData(res)
@ -101,9 +107,7 @@ export default function StuffDetail() {
// //
const _zipNo = watch('zipNo') const _zipNo = watch('zipNo')
useEffect(() => { useEffect(() => {
console.log('실시간이니:::::', _zipNo)
if (_zipNo !== '' && _zipNo.length === 7 && !_zipNo.match(/\D/g)) { if (_zipNo !== '' && _zipNo.length === 7 && !_zipNo.match(/\D/g)) {
console.log('벨리통과했군')
setButtonValid(true) setButtonValid(true)
} else { } else {
setButtonValid(false) setButtonValid(false)
@ -167,26 +171,29 @@ export default function StuffDetail() {
setIsFormValid(Object.keys(errors).length === 0) setIsFormValid(Object.keys(errors).length === 0)
} }
// API // API
const onSearchPostNumber = () => { const onSearchPostNumber = () => {
const params = { const params = {
zipcode: _zipNo, zipcode: _zipNo,
} }
get({ url: `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter(params)}` }).then((res) => { get({ url: `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter(params)}` }).then((res) => {
console.log('우편API RES::::::::', res)
//7830060 //7830060
if (res.status === 200) { if (res.status === 200) {
if (res.results?.length > 0) { console.log('res.results::', res.results)
// setAddress1(res.results[0].address1) if (res.results != null) {
// setAddress2(res.results[0].address2) console.log('res.results::', res.results)
// setAddress3(res.results[0].address3)
// setPrefCode(res.results[0].prefcode)
// prefId: '', // // prefId: '', //
// address: '', // // address: '', //
console.log('prefcode::', res.results[0].prefcode)
console.log('address::', res.results[0].address2 + res.results[0].address3)
setPrefValue(res.results[0].prefcode)
form.setValue('prefId', res.results[0].prefcode) form.setValue('prefId', res.results[0].prefcode)
form.setValue('address', res.results[0].address2 + res.results[0].address3) form.setValue('address', res.results[0].address2 + res.results[0].address3)
} else { } else {
alert('등록된 우편번호에서 주소를 찾을 수 없습니다. 다시 입력해주세요.') alert('등록된 우편번호에서 주소를 찾을 수 없습니다. 다시 입력해주세요.')
form.setValue('prefId', '')
form.setValue('address', '')
setPrefValue('')
} }
} else { } else {
alert(res.message) alert(res.message)
@ -218,11 +225,18 @@ export default function StuffDetail() {
const _dispCompanyName = watch('dispCompanyName') const _dispCompanyName = watch('dispCompanyName')
const _objectStatusId = watch('objectStatusId') const _objectStatusId = watch('objectStatusId')
const _objectNameOmit = watch('objectNameOmit') const _objectNameOmit = watch('objectNameOmit')
const _zipno = watch('zipno') const _zipNo = watch('zipNo')
const _prefId = watch('prefId')
const _address = watch('address')
const _coldAreaChk = watch('coldAreaChk')
console.log(_dispCompanyName) console.log(_dispCompanyName)
console.log(_objectStatusId) console.log(_objectStatusId)
console.log(_objectNameOmit) console.log(_objectNameOmit)
console.log(_zipno) console.log(_zipNo)
console.log(_prefId)
console.log('prefValue::', prefValue)
console.log(_address)
console.log('_coldAreaChk::', _coldAreaChk)
} }
// //
@ -285,11 +299,87 @@ export default function StuffDetail() {
</div> </div>
<div className="form-input"> <div className="form-input">
<label>도도부현 / 주소</label> <label>도도부현 / 주소</label>
<div className="flex w-full flex-wrap items-end md:flex-nowrap mb-6 md:mb-0 gap-4">
{prefCodeList?.length > 0 && (
<Select className="max-w-xs" selectedKeys={prefValue} isDisabled {...form.register('prefId', { required: true })}>
{prefCodeList.map((row) => {
return <SelectItem key={row.prefId}>{row.prefName}</SelectItem>
})}
</Select>
)}
</div>
<input type="text" className="input-origin" value={form.watch('address')} {...form.register('address')} /> <input type="text" className="input-origin" value={form.watch('address')} {...form.register('address')} />
</div> </div>
<div className="form-input">
<label>발전량시뮬레이션지역</label>
</div> </div>
<button type="submit">저장!!!!!!!!!</button> <div className="form-input">
<label>기준풍속</label>
</div>
<div className="form-input">
<label>수직적설량</label>
<input
type="text"
className="input-origin"
maxLength={3}
{...form.register('snowCover', {
required: true,
pattern: { value: /^[0-9]*$/g, message: '정수만 입력' },
})}
/>{' '}
cm
<Checkbox
onValueChange={(e) => {
form.setValue('coldAreaChk', e)
}}
{...form.register('coldAreaChk')}
>
한랭지대책시행
</Checkbox>
</div>
<div className="form-input">
<label>면조도구분</label>
<input type="radio" name="surfaceType" value="Ⅲ・Ⅳ" id="surfaceType0" {...form.register('surfaceType')} />
<label htmlFor="surfaceType0"></label>
<input type="radio" name="surfaceType" value="Ⅱ" id="surfaceType1" {...form.register('surfaceType')} />
<label htmlFor="surfaceType1"></label>
<Checkbox
{...form.register('saltAreaChk')}
onValueChange={(e) => {
form.setValue('saltAreaChk', e)
}}
>
염해지역용아이템사용
</Checkbox>
</div>
<div className="form-input">
<label>설치높이 installHeight</label>
</div>
<div className="form-input">
<label>계약조건</label>
<input type="radio" name="powerConTerms" value="0" id="powerConTerms0" {...form.register('powerConTerms')} />
<label htmlFor="powerConTerms0">잉여</label>
<input type="radio" name="powerConTerms" value="1" id="powerConTerms1" {...form.register('powerConTerms')} />
<label htmlFor="powerConTerms1">전량</label>
</div>
<div className="form-input">
<label>메모</label>
<Textarea
disableAutosize
classNames={{
base: 'max-w-xs',
input: 'resize-y min-h-[40px]',
}}
{...form.register('remark')}
onValueChange={(e) => {
// console.log('e::::', e)
form.setValue('remark', e)
}}
/>
</div>
</div>
<button type="submit">신규화면임시저장!!!!!!!!!</button>
</form> </form>
)) || <div>상세:::::::::::</div>} )) || <div>상세:::::::::::</div>}

85
src/hooks/useEvent.js Normal file
View File

@ -0,0 +1,85 @@
import { useEffect, useRef } from 'react'
import { useRecoilValue } from 'recoil'
import { canvasState, stepState } from '@/store/canvasAtom'
export function useEvent() {
const canvas = useRecoilValue(canvasState)
const step = useRecoilValue(stepState)
const keyboardEventListeners = useRef([])
useEffect(() => {
if (!canvas) {
return
}
Object.keys(canvas.__eventListeners).forEach((key) => {
if (key.indexOf('mouse') > -1) {
canvas.off(key)
}
})
removeAllKeyboardEventListeners()
addEvent(step)
}, [step])
const addEvent = (step) => {
//default Event 추가
canvas?.on('mouse:move', defaultMouseMoveEvent)
addKeyboardEventListener('keydown', document, defaultKeyboardEvent)
if (step === 1) {
canvas?.on('mouse:down', (e) => {
canvas?.add(new fabric.Rect({ width: 100, height: 100, fill: 'red', left: e.pointer.x, top: e.pointer.y }))
})
addKeyboardEventListener('keydown', document, (e) => {
if (e.key === 'Escape') {
console.log(1111)
}
})
} else if (step === 2) {
canvas?.on('mouse:down', (e) => {
canvas?.add(new fabric.Circle({ radius: 50, fill: 'blue', left: e.pointer.x, top: e.pointer.y }))
})
addKeyboardEventListener('keydown', document, (e) => {
if (e.key === 'Escape') {
console.log(2222)
}
})
} else {
canvas?.on('mouse:down', (e) => {
canvas?.add(new fabric.Triangle({ width: 100, height: 100, fill: 'green', left: e.pointer.x, top: e.pointer.y }))
})
addKeyboardEventListener('keydown', document, (e) => {
if (e.key === 'Escape') {
console.log(333)
}
})
}
}
const defaultMouseMoveEvent = (e) => {
console.log('defaultMouseMoveEvent')
}
const defaultKeyboardEvent = (e) => {
if (e.key === 'Escape') {
console.log('defaultKeyboardEvent')
}
}
/**
* document 키보드 이벤트 임의로 직접 등록한 이벤트의 경우 remove가 안되기 때문에 함수를 통해서만 등록해야 .
* @param eventType
* @param element
* @param handler
*/
function addKeyboardEventListener(eventType, element, handler) {
element.addEventListener(eventType, handler)
keyboardEventListeners.current.push({ eventType, element, handler })
}
function removeAllKeyboardEventListeners() {
keyboardEventListeners.current.forEach(({ eventType, element, handler }) => {
element.removeEventListener(eventType, handler)
})
keyboardEventListeners.current.length = 0 // 배열 초기화
}
}

View File

@ -1,25 +1,27 @@
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { globalLocaleState } from '@/store/localeAtom' import { appMessageStore } from '@/store/localeAtom'
import KO from '@/locales/ko.json' // import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json' // import JA from '@/locales/ja.json'
const SESSION_STORAGE_MESSAGE_KEY = 'QCAST_MESSAGE_STORAGE' const SESSION_STORAGE_MESSAGE_KEY = 'QCAST_MESSAGE_STORAGE'
export const useMessage = () => { export const useMessage = () => {
const globalLocale = useRecoilValue(globalLocaleState) // const globalLocale = useRecoilValue(globalLocaleState)
const appMessageState = useRecoilValue(appMessageStore)
const getMessage = (key, args = []) => { const getMessage = (key, args = []) => {
if (sessionStorage.getItem(SESSION_STORAGE_MESSAGE_KEY) === null) { // if (sessionStorage.getItem(SESSION_STORAGE_MESSAGE_KEY) === null) {
if (globalLocale === 'ko') { // if (globalLocale === 'ko') {
setSessionMessage(JSON.stringify(KO)) // setSessionMessage(JSON.stringify(KO))
} else { // } else {
setSessionMessage(JSON.stringify(JA)) // setSessionMessage(JSON.stringify(JA))
} // }
} // }
const sessionMessage = getSessionMessage() // const sessionMessage = getSessionMessage()
const message = sessionMessage[key] || key // const message = sessionMessage[key] || key
const message = appMessageState[key] || key
return args.reduce((acc, arg, i) => { return args.reduce((acc, arg, i) => {
return acc.replaceAll(`{${i}}`, arg) return acc.replaceAll(`{${i}}`, arg)

View File

@ -1,5 +1,70 @@
{ {
"hi": "こんにちは", "hi": "こんにちは",
"welcome": "환영합니다. {0}님",
"header.menus.home": "ホームへv",
"header.menus.management": "物品及び図面管理",
"header.menus.management.stuff": "新規物件登録",
"header.menus.management.plan": "モノ/図面管理",
"header.menus.community": "コミュニティ",
"header.menus.community.notice": "お知らせ",
"header.menus.community.faq": "FAQ",
"header.menus.community.archive": "素材のダウンロード",
"header.logout": "ログアウト",
"header.go": "移動",
"header.online.warranty.system": "オンライン保証シ",
"header.stem": "ステム",
"plan.menu.plan.drawing": "도면작성",
"plan.menu.placement.surface.initial.setting": "配置面 初期設定",
"plan.menu.root.cover": "지붕덮개",
"plan.menu.root.cover.outline.drawing": "외벽선 그리기",
"modal.cover.outline.drawing": "외벽선 그리기",
"modal.cover.outline": "외벽선",
"modal.cover.outline.right.angle": "직각",
"modal.cover.outline2": "이구배",
"modal.cover.outline.angle": "각도",
"modal.cover.outline.diagonal": "대각선",
"modal.cover.outline.setting": "설정",
"modal.cover.outline.length": "길이",
"modal.cover.outline.arrow": "방향(화살표)",
"modal.cover.outline.fix": "외벽선 확정",
"plan.menu.root.cover.roof.setting": "屋根形状設定",
"plan.menu.root.cover.roof.edit": "지붕형상 편집",
"plan.menu.root.cover.sub.line": "補助線を描",
"plan.menu.placement.surface": "配置面",
"plan.menu.placement.surface.drawing": "배치면 그리기",
"plan.menu.placement.surface.surface": "면형상 배치",
"plan.menu.placement.surface.object": "오브젝트 배치",
"plan.menu.module.circuit.setting": "モジュール回路構成",
"plan.menu.module.circuit.setting.default": "기본 설정",
"plan.menu.module.circuit.setting.circuit.trestle.setting": "회로 및 가대 설정",
"plan.menu.estimate": "見積",
"plan.menu.estimate.roof.alloc": "屋根面の割り当て",
"plan.menu.estimate.save": "保存",
"plan.menu.estimate.reset": "初期化",
"plan.menu.estimate.copy": "コピー",
"plan.menu.simulation": "発展シミュレーション",
"plan.menu.simulation.excel": "Excel",
"plan.menu.simulation.pdf": "PDF",
"plan.mode.vertical.horizontal": "垂直水平モード",
"modal.canvas.setting": "Canvas設定",
"modal.canvas.setting.display": "ディスプレイ設定",
"modal.canvas.setting.font.plan": " フォントと図面サイズの設定",
"modal.canvas.setting.first.option.info": "※図面に表示する項目をクリックすると適用されます。",
"modal.canvas.setting.first.option.alloc": "할당표시",
"modal.canvas.setting.first.option.outline": "외벽선표시",
"modal.canvas.setting.first.option.plan": "도면표시",
"modal.canvas.setting.first.option.roof.line": "지붕선표시",
"modal.canvas.setting.first.option.grid": "그리드표시",
"modal.canvas.setting.first.option.circuit.num": "회로 번호 표시",
"modal.canvas.setting.first.option.word": "문자 표시",
"modal.canvas.setting.first.option.trestle": "가대 표시",
"modal.canvas.setting.first.option.flow": "흐름방향 표시",
"modal.canvas.setting.first.option.total": "집계표 표시",
"modal.canvas.setting.first.option.corridor.dimension": "복도치수 표시",
"modal.canvas.setting.first.option.display": "画面表示",
"modal.canvas.setting.first.option.border": "ボーダーのみ",
"modal.canvas.setting.first.option.line": "ラインハッチ",
"modal.canvas.setting.first.option.all": "All painted",
"common.message.no.data": "No data", "common.message.no.data": "No data",
"common.message.no.dataDown": "ダウンロードするデータがありません", "common.message.no.dataDown": "ダウンロードするデータがありません",
"common.message.noData": "表示するデータがありません", "common.message.noData": "表示するデータがありません",
@ -87,18 +152,14 @@
"common.message.writeToConfirm": "作成解除を実行しますか?", "common.message.writeToConfirm": "作成解除を実行しますか?",
"common.message.password.init.success": "パスワード [{0}] に初期化されました。", "common.message.password.init.success": "パスワード [{0}] に初期化されました。",
"common.message.no.edit.save": "この文書は変更できません。", "common.message.no.edit.save": "この文書は変更できません。",
"common.require": "필수", "common.require": "필수",
"site.name": "Q.CAST III", "site.name": "Q.CAST III",
"site.sub_name": "태양광 발전 시스템 도면관리 사이트", "site.sub_name": "태양광 발전 시스템 도면관리 사이트",
"login": "로그인", "login": "로그인",
"login.init_password.btn": "비밀번호 초기화", "login.init_password.btn": "비밀번호 초기화 ja",
"login.init_password.title": "비밀번호 초기화", "login.init_password.title": "비밀번호 초기화",
"login.init_password.sub_title": "비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.", "login.init_password.sub_title": "비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.",
"login.init_password.complete_message": "비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.", "login.init_password.complete_message": "비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.",
"join.title": "Q.CAST3 로그인ID 발행 신청", "join.title": "Q.CAST3 로그인ID 발행 신청",
"join.sub1.title": "판매대리점 정보", "join.sub1.title": "판매대리점 정보",
"join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점××설비주식회사)」로 기입해 주세요.)", "join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점××설비주식회사)」로 기입해 주세요.)",
@ -140,7 +201,6 @@
"join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.", "join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.",
"join.complete.email_comment": "담당자 이메일 주소", "join.complete.email_comment": "담당자 이메일 주소",
"join.complete.email": "test@naver.com", "join.complete.email": "test@naver.com",
"stuff.gridHeader.lastEditDatetime": "갱신일시", "stuff.gridHeader.lastEditDatetime": "갱신일시",
"stuff.gridHeader.objectNo": "물건번호", "stuff.gridHeader.objectNo": "물건번호",
"stuff.gridHeader.planTotCnt": "플랜 수", "stuff.gridHeader.planTotCnt": "플랜 수",

View File

@ -1,5 +1,70 @@
{ {
"hi": "안녕하세요", "hi": "안녕하세요",
"welcome": "환영합니다. {0}님",
"header.menus.home": "Home",
"header.menus.management": "물건 및 도면 관리",
"header.menus.management.stuff": "신규 물건 등록",
"header.menus.management.plan": "사물/도면 관리",
"header.menus.community": "커뮤니티",
"header.menus.community.notice": "공지",
"header.menus.community.faq": "FAQ",
"header.menus.community.archive": "자료 다운로드",
"header.logout": "로그아웃",
"header.go": "이동",
"header.online.warranty.system": "온라인 보증 시스템",
"header.stem": "Stem",
"plan.menu.plan.drawing": "도면작성",
"plan.menu.placement.surface.initial.setting": "배치면 초기 설정",
"plan.menu.root.cover": "지붕덮개",
"plan.menu.root.cover.outline.drawing": "외벽선 그리기",
"modal.cover.outline.drawing": "외벽선 그리기",
"modal.cover.outline": "외벽선",
"modal.cover.outline.right.angle": "직각",
"modal.cover.outline2": "이구배",
"modal.cover.outline.angle": "각도",
"modal.cover.outline.diagonal": "대각선",
"modal.cover.outline.setting": "설정",
"modal.cover.outline.length": "길이",
"modal.cover.outline.arrow": "방향(화살표)",
"modal.cover.outline.fix": "외벽선 확정",
"plan.menu.root.cover.roof.setting": "지붕형상 설정",
"plan.menu.root.cover.roof.edit": "지붕형상 편집",
"plan.menu.root.cover.sub.line": "보조선 그리기",
"plan.menu.placement.surface": "배치면",
"plan.menu.placement.surface.drawing": "배치면 그리기",
"plan.menu.placement.surface.surface": "면형상 배치",
"plan.menu.placement.surface.object": "오브젝트 배치",
"plan.menu.module.circuit.setting": "모듈,회로 구성",
"plan.menu.module.circuit.setting.default": "기본 설정",
"plan.menu.module.circuit.setting.circuit.trestle.setting": "회로 및 가대 설정",
"plan.menu.estimate": "견적서",
"plan.menu.estimate.roof.alloc": "지붕면 할당",
"plan.menu.estimate.save": "저장",
"plan.menu.estimate.reset": "초기화",
"plan.menu.estimate.copy": "복사",
"plan.menu.simulation": "발전 시뮬레이션",
"plan.menu.simulation.excel": "Excel",
"plan.menu.simulation.pdf": "PDF",
"plan.mode.vertical.horizontal": "수직 수평 모드",
"modal.canvas.setting": "Canvas 설정",
"modal.canvas.setting.display": "디스플레이 설정",
"modal.canvas.setting.font.plan": "글꼴 및 도면 크기 설정",
"modal.canvas.setting.first.option.info": "※도면에 표시하는 항목을 클릭하면 적용됩니다.",
"modal.canvas.setting.first.option.alloc": "할당표시",
"modal.canvas.setting.first.option.outline": "외벽선표시",
"modal.canvas.setting.first.option.plan": "도면표시",
"modal.canvas.setting.first.option.roof.line": "지붕선표시",
"modal.canvas.setting.first.option.grid": "그리드표시",
"modal.canvas.setting.first.option.circuit.num": "회로 번호 표시",
"modal.canvas.setting.first.option.word": "문자 표시",
"modal.canvas.setting.first.option.trestle": "가대 표시",
"modal.canvas.setting.first.option.flow": "흐름방향 표시",
"modal.canvas.setting.first.option.total": "집계표 표시",
"modal.canvas.setting.first.option.corridor.dimension": "복도치수 표시",
"modal.canvas.setting.first.option.display": "화면 표시",
"modal.canvas.setting.first.option.border": "테두리만",
"modal.canvas.setting.first.option.line": "라인해치",
"modal.canvas.setting.first.option.all": "All painted",
"common.message.no.data": "No data", "common.message.no.data": "No data",
"common.message.no.dataDown": "No data to download", "common.message.no.dataDown": "No data to download",
"common.message.noData": "No data to display", "common.message.noData": "No data to display",
@ -87,18 +152,14 @@
"common.message.writeToConfirm": "작성 해제를 실행하시겠습니까?", "common.message.writeToConfirm": "작성 해제를 실행하시겠습니까?",
"common.message.password.init.success": "비밀번호 [{0}]로 초기화 되었습니다.", "common.message.password.init.success": "비밀번호 [{0}]로 초기화 되었습니다.",
"common.message.no.edit.save": "This document cannot be changed.", "common.message.no.edit.save": "This document cannot be changed.",
"common.require": "필수", "common.require": "필수",
"site.name": "Q.CAST III", "site.name": "Q.CAST III",
"site.sub_name": "태양광 발전 시스템 도면관리 사이트", "site.sub_name": "태양광 발전 시스템 도면관리 사이트",
"login": "로그인", "login": "로그인",
"login.init_password.btn": "비밀번호 초기화", "login.init_password.btn": "비밀번호 초기화",
"login.init_password.title": "비밀번호 초기화", "login.init_password.title": "비밀번호 초기화",
"login.init_password.sub_title": "비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.", "login.init_password.sub_title": "비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.",
"login.init_password.complete_message": "비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.", "login.init_password.complete_message": "비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.",
"join.title": "Q.CAST3 로그인ID 발행 신청", "join.title": "Q.CAST3 로그인ID 발행 신청",
"join.sub1.title": "판매대리점 정보", "join.sub1.title": "판매대리점 정보",
"join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점××설비주식회사)」로 기입해 주세요.)", "join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점××설비주식회사)」로 기입해 주세요.)",
@ -140,7 +201,6 @@
"join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.", "join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.",
"join.complete.email_comment": "담당자 이메일 주소", "join.complete.email_comment": "담당자 이메일 주소",
"join.complete.email": "test@naver.com", "join.complete.email": "test@naver.com",
"stuff.gridHeader.lastEditDatetime": "갱신일시", "stuff.gridHeader.lastEditDatetime": "갱신일시",
"stuff.gridHeader.objectNo": "물건번호", "stuff.gridHeader.objectNo": "물건번호",
"stuff.gridHeader.planTotCnt": "플랜 수", "stuff.gridHeader.planTotCnt": "플랜 수",

View File

@ -29,8 +29,8 @@ export const fontSizeState = atom({
export const canvasSizeState = atom({ export const canvasSizeState = atom({
key: 'canvasSize', key: 'canvasSize',
default: { default: {
vertical: 1500, vertical: 1000,
horizontal: 1500, horizontal: 1600,
}, },
}) })
@ -179,3 +179,8 @@ export const objectPlacementModeState = atom({
key: 'objectPlacementMode', key: 'objectPlacementMode',
default: { width: 0, height: 0, areaBoundary: false, inputType: 'free', batchType: 'opening' }, default: { width: 0, height: 0, areaBoundary: false, inputType: 'free', batchType: 'opening' },
}) })
export const stepState = atom({
key: 'step',
default: 0,
})

View File

@ -1,6 +1,11 @@
import { atom } from 'recoil' import { atom } from 'recoil'
export const globalLocaleState = atom({ export const globalLocaleStore = atom({
key: 'globalLocaleState', key: 'globalLocaleState',
default: 'ko', default: 'ko',
}) })
export const appMessageStore = atom({
key: 'appMessageState',
default: {},
})

View File

@ -4,22 +4,22 @@ export const settingModalFirstOptionsState = atom({
key: 'settingModalFirstOptions', key: 'settingModalFirstOptions',
default: { default: {
option1: [ option1: [
{ id: 1, name: '割り当て表示', selected: false }, { id: 1, name: 'modal.canvas.setting.first.option.alloc', selected: false },
{ id: 2, name: '実寸表示', selected: false }, { id: 2, name: 'modal.canvas.setting.first.option.outline', selected: false },
{ id: 3, name: '図面表示', selected: false }, { id: 3, name: 'modal.canvas.setting.first.option.plan', selected: false },
{ id: 4, name: '寸法表示なし', selected: false }, { id: 4, name: 'modal.canvas.setting.first.option.roof.line', selected: false },
{ id: 5, name: 'グリッド表示', selected: false }, { id: 5, name: 'modal.canvas.setting.first.option.grid', selected: false },
{ id: 6, name: '架台表示', selected: false }, { id: 6, name: 'modal.canvas.setting.first.option.circuit.num', selected: false },
{ id: 7, name: '文字表示', selected: false }, { id: 7, name: 'modal.canvas.setting.first.option.word', selected: false },
{ id: 8, name: '座標表示', selected: false }, { id: 8, name: 'modal.canvas.setting.first.option.trestle', selected: false },
{ id: 9, name: '流れ方向表示', selected: false }, { id: 9, name: 'modal.canvas.setting.first.option.flow', selected: false },
{ id: 10, name: '図面切替表示', selected: false }, { id: 10, name: 'modal.canvas.setting.first.option.total', selected: false },
{ id: 11, name: 'ü廊下寸法表示', selected: false }, { id: 11, name: 'modal.canvas.setting.first.option.corridor.dimension', selected: false },
], ],
option2: [ option2: [
{ id: 1, name: 'ボーダーのみ', selected: false }, { id: 1, name: 'modal.canvas.setting.first.option.border', selected: false },
{ id: 2, name: 'ラインハッチ', selected: false }, { id: 2, name: 'modal.canvas.setting.first.option.line', selected: false },
{ id: 3, name: 'All painted', selected: false }, { id: 3, name: 'modal.canvas.setting.first.option.all', selected: false },
], ],
}, },
dangerouslyAllowMutability: true, dangerouslyAllowMutability: true,

View File

@ -131,7 +131,7 @@
transition: all .17s ease-in-out; transition: all .17s ease-in-out;
&.btn01 { &.btn01 {
background-image: url(../../public/static/images/canvas/side_icon01.svg); background-image: url(../../public/static/images/canvas/side_icon03.svg);
} }
&.btn02 { &.btn02 {
@ -139,7 +139,7 @@
} }
&.btn03 { &.btn03 {
background-image: url(../../public/static/images/canvas/side_icon03.svg); background-image: url(../../public/static/images/canvas/side_icon01.svg);
} }
&.btn04 { &.btn04 {
@ -176,6 +176,39 @@
} }
} }
.ico-btn-from {
display: flex;
align-items: center;
gap: 5px;
button {
.ico {
display: block;
width: 14px;
height: 14px;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
&.ico01 {
background-image: url(../../public/static/images/canvas/ico-flx01.svg);
}
&.ico02 {
background-image: url(../../public/static/images/canvas/ico-flx02.svg);
}
&.ico03 {
background-image: url(../../public/static/images/canvas/ico-flx03.svg);
}
&.ico04 {
background-image: url(../../public/static/images/canvas/ico-flx04.svg);
}
}
}
}
.vertical-horizontal { .vertical-horizontal {
display: flex; display: flex;
min-width: 170px; min-width: 170px;
@ -200,6 +233,13 @@
font-weight: 400; font-weight: 400;
color: #fff; color: #fff;
padding: 0 7.5px; padding: 0 7.5px;
transition: all .17s ease-in-out;
}
&.on {
button {
background-color: #1083E3;
}
} }
} }

View File

@ -149,7 +149,7 @@ button {
// button // button
.btn-frame { .btn-frame {
display: inline-block; display: inline-block;
padding: 0 10px; padding: 0 9px;
height: 34px; height: 34px;
line-height: 34px; line-height: 34px;
border-radius: 2px; border-radius: 2px;
@ -201,6 +201,7 @@ button {
} }
} }
&:hover,
&.act { &.act {
background-color: #1083E3; background-color: #1083E3;
border: 1px solid #1083E3; border: 1px solid #1083E3;
@ -212,6 +213,20 @@ button {
display: block; display: block;
width: 100%; width: 100%;
} }
&.ico-flx {
display: flex;
align-items: center;
.ico {
margin-right: 10px;
}
&:hover,
&.act {
font-weight: 400;
}
}
} }
// select // select
@ -293,6 +308,16 @@ button {
} }
// input // input
.form-input {
label {
display: block;
color: #aaa;
font-size: 12px;
font-weight: 500;
margin-bottom: 10px;
}
}
input[type=text] { input[type=text] {
&.input-origin { &.input-origin {
display: inline-block; display: inline-block;
@ -305,9 +330,15 @@ input[type=text] {
font-weight: 500; font-weight: 500;
font-family: 'Pretendard', sans-serif; font-family: 'Pretendard', sans-serif;
padding: 0 10px; padding: 0 10px;
letter-spacing: 0px;
&::placeholder { &::placeholder {
font-size: 12px; font-size: 12px;
letter-spacing: 0px;
}
&.block {
width: 100%;
} }
} }
} }
@ -428,4 +459,24 @@ input[type=text] {
} }
} }
} }
&.dark {
text-align: center;
background-color: #272727;
border: 1px solid #484848;
span {
color: #Fff;
&:after {
background: url(../../public/static/images/canvas/arr_btn_ico_white.svg) no-repeat center;
}
}
&:hover,
&.act {
background-color: #1083E3;
border: 1px solid #1083E3;
}
}
} }

View File

@ -1,2 +1,3 @@
@import 'fonts.scss'; @import 'fonts.scss';
@import 'reset.scss'; @import 'reset.scss';
@import '_layout.scss';

2
src/styles/contents.scss Normal file
View File

@ -0,0 +1,2 @@
@import '_contents.scss';
@import '_modal.scss';

View File

@ -10,6 +10,14 @@ export const isObjectNotEmpty = (obj) => {
return Object.keys(obj).length > 0 return Object.keys(obj).length > 0
} }
export const isNotEmptyArray = (array) => {
return Array.isArray(array) && array.length
}
export const isEmptyArray = (array) => {
return !isNotEmptyArray(array)
}
/** /**
* ex) const params = {page:10, searchDvsnCd: 20} * ex) const params = {page:10, searchDvsnCd: 20}
* @param {*} params * @param {*} params

View File

@ -5515,11 +5515,6 @@ react-dom@^18:
loose-envify "^1.1.0" loose-envify "^1.1.0"
scheduler "^0.23.2" 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: react-draggable@^4.4.6:
version "4.4.6" version "4.4.6"
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.6.tgz#63343ee945770881ca1256a5b6fa5c9f5983fe1e" resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.6.tgz#63343ee945770881ca1256a5b6fa5c9f5983fe1e"
@ -5528,6 +5523,11 @@ react-draggable@^4.4.6:
clsx "^1.1.1" clsx "^1.1.1"
prop-types "^15.8.1" prop-types "^15.8.1"
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-icons@^5.3.0: react-icons@^5.3.0:
version "5.3.0" version "5.3.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c"