Merge branch 'dev' of https://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into dev
This commit is contained in:
commit
8bf1d27c3c
@ -22,6 +22,7 @@
|
|||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"next-international": "^1.2.4",
|
"next-international": "^1.2.4",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
|
"react-colorful": "^5.6.1",
|
||||||
"react-datepicker": "^7.3.0",
|
"react-datepicker": "^7.3.0",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-responsive-modal": "^6.4.2",
|
"react-responsive-modal": "^6.4.2",
|
||||||
@ -35,6 +36,7 @@
|
|||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prisma": "^5.18.0",
|
"prisma": "^5.18.0",
|
||||||
|
"react-color-palette": "^7.2.2",
|
||||||
"sass": "^1.77.8",
|
"sass": "^1.77.8",
|
||||||
"tailwindcss": "^3.4.1"
|
"tailwindcss": "^3.4.1"
|
||||||
}
|
}
|
||||||
|
|||||||
23
public/drawTemplates/153302.svg
Normal file
23
public/drawTemplates/153302.svg
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="600" height="300" viewBox="0 0 1280 875"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.15, written by Peter Selinger 2001-2017
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,875.000000) scale(0.100000,-0.100000)" fill="purple" stroke="#000000" stroke-width="10">
|
||||||
|
|
||||||
|
<path d="M3403 7423 c-257 -762 -623 -1817 -636 -1829 -11 -11 -1264 -358
|
||||||
|
-1817 -504 -405 -106 -540 -144 -539 -150 0 -3 30 -28 67 -55 117 -88 1826
|
||||||
|
-1407 1841 -1421 12 -11 11 -104 -8 -646 -24 -697 -58 -1634 -64 -1770 -3 -49
|
||||||
|
-3 -88 -1 -88 5 0 949 674 1528 1092 l479 346 61 -23 c34 -13 279 -104 546
|
||||||
|
-203 267 -100 754 -282 1083 -405 328 -123 597 -219 597 -215 0 5 -54 189
|
||||||
|
-119 411 -66 221 -192 652 -280 957 -88 305 -187 643 -219 751 l-58 195 304
|
||||||
|
385 c168 211 503 636 745 944 242 308 447 568 455 578 8 9 12 20 8 24 -4 4
|
||||||
|
-220 11 -479 15 -413 6 -1036 22 -1745 44 l-213 7 -427 636 c-235 350 -541
|
||||||
|
808 -682 1018 -140 210 -258 383 -261 383 -3 0 -78 -215 -166 -477z"/>
|
||||||
|
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
4
public/drawTemplates/shape21.svg
Normal file
4
public/drawTemplates/shape21.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg height="280" width="600" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<polygon points="120,15 42,202 400,202 400,99 150,99 " style="fill:lime;stroke:purple;stroke-width:3" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 179 B |
@ -4,8 +4,10 @@ import { useRecoilState, useRecoilValue } from 'recoil'
|
|||||||
import { modalContent, modalState } from '@/store/modalAtom'
|
import { modalContent, modalState } from '@/store/modalAtom'
|
||||||
import { guideLineState, horiGuideLinesState, vertGuideLinesState } from '@/store/canvasAtom'
|
import { guideLineState, horiGuideLinesState, vertGuideLinesState } from '@/store/canvasAtom'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
|
import { ColorPicker, useColor } from 'react-color-palette'
|
||||||
|
import 'react-color-palette/css'
|
||||||
|
|
||||||
export default function SettingsModal(props) {
|
export default function GridSettingsModal(props) {
|
||||||
const { canvasProps } = props
|
const { canvasProps } = props
|
||||||
const [isCustomGridSetting, setIsCustomGridSetting] = useState(true)
|
const [isCustomGridSetting, setIsCustomGridSetting] = useState(true)
|
||||||
const [gridCheckedValue, setGridCheckValue] = useState([])
|
const [gridCheckedValue, setGridCheckValue] = useState([])
|
||||||
@ -21,6 +23,15 @@ export default function SettingsModal(props) {
|
|||||||
|
|
||||||
const gridSettingArray = []
|
const gridSettingArray = []
|
||||||
|
|
||||||
|
const [guideColor, setGuideColor] = useColor('rgb(200, 15, 15)')
|
||||||
|
const [colorPickerShow, setColorPickerShow] = useState(false)
|
||||||
|
|
||||||
|
const boxStyle = {
|
||||||
|
width: '50px',
|
||||||
|
height: '30px',
|
||||||
|
border: '1px solid black',
|
||||||
|
backgroundColor: guideColor.hex,
|
||||||
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
moduleLength.current.value = 90
|
moduleLength.current.value = 90
|
||||||
customModuleHoriLength.current.value = 90
|
customModuleHoriLength.current.value = 90
|
||||||
@ -56,7 +67,7 @@ export default function SettingsModal(props) {
|
|||||||
const horizontalLine = new fabric.Line(
|
const horizontalLine = new fabric.Line(
|
||||||
[0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2],
|
[0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2],
|
||||||
{
|
{
|
||||||
stroke: 'gray',
|
stroke: guideColor.hex,
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
lockMovementX: true,
|
lockMovementX: true,
|
||||||
@ -65,6 +76,8 @@ export default function SettingsModal(props) {
|
|||||||
lockScalingX: true,
|
lockScalingX: true,
|
||||||
lockScalingY: true,
|
lockScalingY: true,
|
||||||
name: 'guideLine',
|
name: 'guideLine',
|
||||||
|
strokeDashArray: [5, 2],
|
||||||
|
opacity: 0.3,
|
||||||
direction: 'horizontal',
|
direction: 'horizontal',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -76,7 +89,7 @@ export default function SettingsModal(props) {
|
|||||||
const verticalLine = new fabric.Line(
|
const verticalLine = new fabric.Line(
|
||||||
[i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height],
|
[i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height],
|
||||||
{
|
{
|
||||||
stroke: 'gray',
|
stroke: guideColor.hex,
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
lockMovementX: true,
|
lockMovementX: true,
|
||||||
@ -85,6 +98,8 @@ export default function SettingsModal(props) {
|
|||||||
lockScalingX: true,
|
lockScalingX: true,
|
||||||
lockScalingY: true,
|
lockScalingY: true,
|
||||||
name: 'guideLine',
|
name: 'guideLine',
|
||||||
|
strokeDashArray: [5, 2],
|
||||||
|
opacity: 0.3,
|
||||||
direction: 'vertical',
|
direction: 'vertical',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -118,7 +133,9 @@ export default function SettingsModal(props) {
|
|||||||
if (gridCheckedValue.includes('dot')) {
|
if (gridCheckedValue.includes('dot')) {
|
||||||
const circle = new fabric.Circle({
|
const circle = new fabric.Circle({
|
||||||
radius: 2,
|
radius: 2,
|
||||||
fill: 'red',
|
fill: 'white',
|
||||||
|
stroke: guideColor.hex,
|
||||||
|
strokeWidth: 0.7,
|
||||||
originX: 'center',
|
originX: 'center',
|
||||||
originY: 'center',
|
originY: 'center',
|
||||||
selectable: false,
|
selectable: false,
|
||||||
@ -216,10 +233,18 @@ export default function SettingsModal(props) {
|
|||||||
<Radio value="custom">임의간격</Radio>
|
<Radio value="custom">임의간격</Radio>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full flex-wrap md:flex-nowrap gap-4"></div>
|
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
||||||
<Checkbox value="linked" isDisabled={isCustomGridSetting}>
|
가이드컬러 <div style={boxStyle} onClick={() => setColorPickerShow(!colorPickerShow)}></div>
|
||||||
종횡연동
|
</div>
|
||||||
</Checkbox>
|
{colorPickerShow && (
|
||||||
|
<ColorPicker color={guideColor} onChange={setGuideColor} hideInput={['hsv', 'rgb', 'hex']} height={100} hideAlpha={true} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
||||||
|
<Checkbox value="linked" isDisabled={isCustomGridSetting}>
|
||||||
|
종횡연동
|
||||||
|
</Checkbox>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
||||||
<Input type="number" label="가로간격" ref={customModuleHoriLength} min={0} isDisabled={isCustomGridSetting} />
|
<Input type="number" label="가로간격" ref={customModuleHoriLength} min={0} isDisabled={isCustomGridSetting} />
|
||||||
@ -229,6 +254,7 @@ export default function SettingsModal(props) {
|
|||||||
<Input type="number" label="세로간격" ref={customModuleVertLength} min={0} isDisabled={isCustomGridSetting} />
|
<Input type="number" label="세로간격" ref={customModuleVertLength} min={0} isDisabled={isCustomGridSetting} />
|
||||||
mm
|
mm
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex gap-4 items-center">
|
<div className="flex gap-4 items-center">
|
||||||
<Button size="sm">초기화</Button>
|
<Button size="sm">초기화</Button>
|
||||||
<Button size="sm" color="secondary" onClick={drawGridSettings} isDisabled={gridCheckedValue.length === 0}>
|
<Button size="sm" color="secondary" onClick={drawGridSettings} isDisabled={gridCheckedValue.length === 0}>
|
||||||
189
src/components/InitSettingsModal.jsx
Normal file
189
src/components/InitSettingsModal.jsx
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import { useEffect, useState, memo, useCallback } from 'react'
|
||||||
|
import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input, Select, SelectItem } from '@nextui-org/react'
|
||||||
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
|
import { modalContent, modalState } from '@/store/modalAtom'
|
||||||
|
import { canvasSettingState } from '@/store/canvasAtom'
|
||||||
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
|
||||||
|
export default function InitSettingsModal(props) {
|
||||||
|
const [open, setOpen] = useRecoilState(modalState)
|
||||||
|
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
|
||||||
|
const [roofMaterials, setRoofMaterials] = useState([])
|
||||||
|
const [basicSetting, setBasicSettings] = useState({
|
||||||
|
type: '1',
|
||||||
|
inputType: '1',
|
||||||
|
angleType: 'slope',
|
||||||
|
roofs: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
const { get, post } = useAxios()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
get({ url: '/api/roof-material/roof-material-infos' }).then((res) => {
|
||||||
|
//TODO: error handling
|
||||||
|
if (!res) return
|
||||||
|
|
||||||
|
setRoofMaterials(res)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) {
|
||||||
|
setBasicSettings({ ...canvasSetting })
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//기본 설정값 변경 함수
|
||||||
|
const handleBasicSetting = (event) => {
|
||||||
|
const newBasicSetting = { ...basicSetting, [event.target.name]: event.target.value }
|
||||||
|
setBasicSettings(newBasicSetting)
|
||||||
|
}
|
||||||
|
|
||||||
|
//배열 추가 함수
|
||||||
|
const addRoofSetting = () => {
|
||||||
|
if (basicSetting.roofs.length === 4) {
|
||||||
|
alert('지붕재는 최대 4종까지 선택할 수 있습니다.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//기본값
|
||||||
|
const newRoofSettings = {
|
||||||
|
id: basicSetting.roofs.length + 1,
|
||||||
|
roofId: '3',
|
||||||
|
width: '200',
|
||||||
|
height: '200',
|
||||||
|
gap: '0',
|
||||||
|
layout: 'parallel',
|
||||||
|
}
|
||||||
|
|
||||||
|
setBasicSettings((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
roofs: [...prevState.roofs, newRoofSettings],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
//배열 값 변경 함수
|
||||||
|
const handleRoofSettings = (id, event) => {
|
||||||
|
const roof = basicSetting.roofs.map((roof, i) => (id === roof.id ? { ...roof, [event.target.name]: event.target.value } : roof))
|
||||||
|
setBasicSettings((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
roofs: [...roof],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitCanvasConfig = () => {
|
||||||
|
post({ url: '/api/canvas-config', data: basicSetting }).then((res) => {
|
||||||
|
if (!res) {
|
||||||
|
setCanvasSetting({ ...basicSetting })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="container mx-auto mt-10 p-6 bg-white shadow-lg rounded-lg">
|
||||||
|
<div className="text-lg font-semibold mb-4">배치면 초기설정</div>
|
||||||
|
|
||||||
|
<div className="mb-6">
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<RadioGroup label="도면 작성방법" name="type" orientation="horizontal" value={basicSetting.type} onChange={handleBasicSetting}>
|
||||||
|
<Radio value="1">치수 입력에 의한 물건작성</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-6">
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<RadioGroup label="치수 입력방법" name="inputType" orientation="horizontal" value={basicSetting.inputType} onChange={handleBasicSetting}>
|
||||||
|
<Radio value="1">복사도 입력</Radio>
|
||||||
|
<Radio value="2">실측값 입력</Radio>
|
||||||
|
<Radio value="3">육지붕</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-6">
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<RadioGroup label="지붕각도 설정" name="angleType" orientation="horizontal" value={basicSetting.angleType} onChange={handleBasicSetting}>
|
||||||
|
<Radio value="slope">경사</Radio>
|
||||||
|
<Radio value="angle">각도</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</div>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
{basicSetting.roofs &&
|
||||||
|
basicSetting.roofs.map((roof, index) => {
|
||||||
|
return <RoofSelectBox roofMaterials={roofMaterials} roof={roof} key={index} onChange={handleRoofSettings} />
|
||||||
|
})}
|
||||||
|
|
||||||
|
<div className="flex gap-4 items-right">
|
||||||
|
<Button size="sm" color="secondary" onClick={submitCanvasConfig}>
|
||||||
|
저장
|
||||||
|
</Button>
|
||||||
|
<Button size="sm" onClick={() => setOpen(!open)}>
|
||||||
|
취소
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const RoofSelectBox = (props) => {
|
||||||
|
return (
|
||||||
|
<div className="mb-4 flex flex-wrap items-center space-x-4" style={{ border: '1px solid black' }}>
|
||||||
|
<Select
|
||||||
|
aria-label="roofMaterial"
|
||||||
|
className={'w-52'}
|
||||||
|
name="roofId"
|
||||||
|
onChange={(e) => props.onChange(props.roof.id, e)}
|
||||||
|
items={props.roofMaterials}
|
||||||
|
defaultSelectedKeys={props.roof.roofId ? props.roof.roofId : ''}
|
||||||
|
selectedKeys={props.roof.roofId}
|
||||||
|
value={props.roof.roofId}
|
||||||
|
>
|
||||||
|
{(roofMaterial) => (
|
||||||
|
<SelectItem key={roofMaterial.id} value={roofMaterial.id}>
|
||||||
|
{roofMaterial.name}
|
||||||
|
</SelectItem>
|
||||||
|
)}
|
||||||
|
</Select>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
name="width"
|
||||||
|
placeholder="너비"
|
||||||
|
value={props.roof.width}
|
||||||
|
className="w-24"
|
||||||
|
onChange={(e) => props.onChange(props.roof.id, e)}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
name="height"
|
||||||
|
placeholder="높이"
|
||||||
|
value={props.roof.height}
|
||||||
|
className="w-24"
|
||||||
|
onChange={(e) => props.onChange(props.roof.id, e)}
|
||||||
|
/>
|
||||||
|
mm
|
||||||
|
<Input type="text" name="gap" placeholder="간격" value={props.roof.gap} className="w-24" onChange={(e) => props.onChange(props.roof.id, e)} />
|
||||||
|
mm
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<RadioGroup
|
||||||
|
orientation="horizontal"
|
||||||
|
name="layout"
|
||||||
|
value={props.roof.layout}
|
||||||
|
defaultValue="parallel"
|
||||||
|
onChange={(e) => props.onChange(props.roof.id, e)}
|
||||||
|
>
|
||||||
|
<Radio value="parallel">병렬식</Radio>
|
||||||
|
<Radio value="cascade">계단식</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { useState } from 'react'
|
||||||
import { Button, Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from '@nextui-org/react'
|
import { Button, Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from '@nextui-org/react'
|
||||||
|
import ColorPicker from './common/color-picker/ColorPicker'
|
||||||
|
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
@ -15,6 +17,8 @@ export default function Playground() {
|
|||||||
const testVar = process.env.NEXT_PUBLIC_TEST
|
const testVar = process.env.NEXT_PUBLIC_TEST
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|
||||||
|
const [color, setColor] = useState('#ff0000')
|
||||||
|
|
||||||
const handleUsers = async () => {
|
const handleUsers = async () => {
|
||||||
// const users = await get('/api/user/find-all')
|
// const users = await get('/api/user/find-all')
|
||||||
const params = {
|
const params = {
|
||||||
@ -61,6 +65,10 @@ export default function Playground() {
|
|||||||
<p className="text-white">Sass 테스트입니다.</p>
|
<p className="text-white">Sass 테스트입니다.</p>
|
||||||
</div>
|
</div>
|
||||||
<div>{getMessage('hi')}</div>
|
<div>{getMessage('hi')}</div>
|
||||||
|
<div>
|
||||||
|
<h1>React ColorPicker</h1>
|
||||||
|
<ColorPicker color={color} setColor={setColor} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -26,13 +26,15 @@ import { QPolygon } from '@/components/fabric/QPolygon'
|
|||||||
import ThumbnailList from './ui/ThumbnailLIst'
|
import ThumbnailList from './ui/ThumbnailLIst'
|
||||||
import QContextMenu from './common/context-menu/QContextMenu'
|
import QContextMenu from './common/context-menu/QContextMenu'
|
||||||
import { modalContent, modalState } from '@/store/modalAtom'
|
import { modalContent, modalState } from '@/store/modalAtom'
|
||||||
import SettingsModal from './SettingsModal'
|
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu'
|
import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu'
|
||||||
import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu'
|
import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu'
|
||||||
import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu'
|
import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu'
|
||||||
import { degreesToRadians, radiansToDegrees } from '@turf/turf'
|
import { degreesToRadians, radiansToDegrees } from '@turf/turf'
|
||||||
|
|
||||||
|
import InitSettingsModal from './InitSettingsModal'
|
||||||
|
import GridSettingsModal from './GridSettingsModal'
|
||||||
|
|
||||||
export default function Roof2(props) {
|
export default function Roof2(props) {
|
||||||
const { name, userId, email, isLoggedIn } = props
|
const { name, userId, email, isLoggedIn } = props
|
||||||
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
|
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
|
||||||
@ -105,6 +107,8 @@ export default function Roof2(props) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
get({ url: `/api/canvas-management/canvas-statuses/by-object/test123240822001` }).then((res) => {
|
get({ url: `/api/canvas-management/canvas-statuses/by-object/test123240822001` }).then((res) => {
|
||||||
|
console.log(res)
|
||||||
|
|
||||||
const arrangeData = res.map((item) => {
|
const arrangeData = res.map((item) => {
|
||||||
console.log(item.canvasStatus.replace(/##/g, '"').replace(/\\/g, ''))
|
console.log(item.canvasStatus.replace(/##/g, '"').replace(/\\/g, ''))
|
||||||
const test = item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '')
|
const test = item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '')
|
||||||
@ -1822,7 +1826,24 @@ export default function Roof2(props) {
|
|||||||
<Button
|
<Button
|
||||||
className="m-1 p-2"
|
className="m-1 p-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setContent(<SettingsModal canvasProps={canvas} />)
|
svgLoad()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
svg로딩
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="m-1 p-2"
|
||||||
|
onClick={() => {
|
||||||
|
setContent(<InitSettingsModal canvasProps={canvas} />)
|
||||||
|
setOpen(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
배치면 초기설정
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="m-1 p-2"
|
||||||
|
onClick={() => {
|
||||||
|
setContent(<GridSettingsModal canvasProps={canvas} />)
|
||||||
setOpen(true)
|
setOpen(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
11
src/components/common/color-picker/ColorPicker.jsx
Normal file
11
src/components/common/color-picker/ColorPicker.jsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { HexColorPicker } from 'react-colorful'
|
||||||
|
|
||||||
|
export default function ColorPicker(props) {
|
||||||
|
const { color, setColor } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<HexColorPicker color={color} onChange={setColor} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -19,7 +19,7 @@ function ThumbnailList(props) {
|
|||||||
<div className="flex justify-center m-4 w-full">
|
<div className="flex justify-center m-4 w-full">
|
||||||
{thumbnails.length > 0 &&
|
{thumbnails.length > 0 &&
|
||||||
thumbnails.map((thumbnail, index) => (
|
thumbnails.map((thumbnail, index) => (
|
||||||
<Card isFooterBlurred radius="lg" className="border-none m-2">
|
<Card isFooterBlurred radius="lg" key={index} className="border-none m-2">
|
||||||
<Image
|
<Image
|
||||||
alt="Woman listing to music"
|
alt="Woman listing to music"
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
|
|||||||
@ -105,5 +105,10 @@ export const horiGuideLinesState = atom({
|
|||||||
export const vertGuideLinesState = atom({
|
export const vertGuideLinesState = atom({
|
||||||
key: 'vertGuideLines',
|
key: 'vertGuideLines',
|
||||||
default: [],
|
default: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
export const canvasSettingState = atom({
|
||||||
|
key: 'canvasSetting',
|
||||||
|
default: {},
|
||||||
dangerouslyAllowMutability: true,
|
dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -5470,6 +5470,11 @@ rbush@^3.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
quickselect "^2.0.0"
|
quickselect "^2.0.0"
|
||||||
|
|
||||||
|
react-colorful@^5.6.1:
|
||||||
|
version "5.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b"
|
||||||
|
integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==
|
||||||
|
|
||||||
react-datepicker@^7.3.0:
|
react-datepicker@^7.3.0:
|
||||||
version "7.3.0"
|
version "7.3.0"
|
||||||
resolved "https://registry.npmjs.org/react-datepicker/-/react-datepicker-7.3.0.tgz"
|
resolved "https://registry.npmjs.org/react-datepicker/-/react-datepicker-7.3.0.tgz"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user