Merge pull request '계산기 토글' (#728) from dev into dev-deploy

Reviewed-on: #728
This commit is contained in:
ysCha 2026-03-26 10:39:22 +09:00
commit 25fd99064e
17 changed files with 89 additions and 18 deletions

View File

@ -8,14 +8,17 @@ import { OUTER_LINE_TYPE } from '@/store/outerLineAtom'
import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall'
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
import { usePopup } from '@/hooks/usePopup'
import { useEffect } from 'react'
import { useEffect, useState } from 'react'
import { useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom'
import Image from 'next/image'
export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
const canvas = useRecoilValue(canvasState)
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [useCalcPad, setUseCalcPad] = useState(false)
const disableKeypad = !useCalcPad
const types = [
{ id: 1, name: getMessage('straight.line'), type: OUTER_LINE_TYPE.OUTER_LINE },
@ -71,6 +74,7 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
length1Ref,
arrow1,
setArrow1,
disableKeypad,
}
const rightAngleProps = {
@ -84,6 +88,7 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
setArrow1,
arrow2,
setArrow2,
disableKeypad,
}
const doublePitchProps = {
@ -105,6 +110,7 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
setArrow2,
arrow1Ref,
arrow2Ref,
disableKeypad,
}
const angleProps = {
@ -114,6 +120,7 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
length1,
setLength1,
length1Ref,
disableKeypad,
}
const diagonalLineProps = {
@ -130,6 +137,7 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
setArrow1,
arrow2,
setArrow2,
disableKeypad,
}
const onClickButton = (button) => {
@ -160,7 +168,10 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
{buttonAct === 4 && <Angle props={angleProps} />}
{buttonAct === 5 && <Diagonal props={diagonalLineProps} />}
</div>
<div className="grid-btn-wrap">
<div className="grid-btn-wrap" style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '5px' }}>
<button style={{ width: 'auto' }} type="button" onClick={() => setUseCalcPad((prev) => !prev)}>
<Image src={useCalcPad ? '/static/images/common/Icon_ON_Black.png' : '/static/images/common/Icon_OFF_Black.png'} alt="toggle" width={34} height={34} />
</button>
<button className="btn-frame modal mr5" onClick={handleRollback}>
{getMessage('modal.cover.outline.rollback')}
</button>

View File

@ -6,10 +6,14 @@ import WallMerge from '@/components/floor-plan/modal/eavesGable/type/WallMerge'
import Shed from '@/components/floor-plan/modal/eavesGable/type/Shed'
import { useEavesGableEdit } from '@/hooks/roofcover/useEavesGableEdit'
import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react'
import Image from 'next/image'
export default function EavesGableEdit({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [useCalcPad, setUseCalcPad] = useState(false)
const disableKeypad = !useCalcPad
const { type, setType, buttonMenu, TYPES, pitchRef, offsetRef, widthRef, radioTypeRef, pitchText } = useEavesGableEdit(id)
const eavesProps = {
@ -18,6 +22,7 @@ export default function EavesGableEdit({ id, pos = { x: 50, y: 230 } }) {
widthRef,
radioTypeRef,
pitchText,
disableKeypad,
}
const gableProps = {
@ -26,15 +31,18 @@ export default function EavesGableEdit({ id, pos = { x: 50, y: 230 } }) {
widthRef,
radioTypeRef,
pitchText,
disableKeypad,
}
const wallMergeProps = {
offsetRef,
radioTypeRef,
disableKeypad,
}
const shedProps = {
offsetRef,
disableKeypad,
}
return (
@ -48,8 +56,13 @@ export default function EavesGableEdit({ id, pos = { x: 50, y: 230 } }) {
</button>
))}
</div>
<div className="properties-setting-wrap outer">
<div className="setting-tit">{getMessage('setting')}</div>
<div className="properties-setting-wrap outer" style={{margin: '10px'}}>
<div className="setting-tit" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<span>{getMessage('setting')}</span>
<button style={{ width: 'auto' }} type="button" onClick={() => setUseCalcPad((prev) => !prev)}>
<Image src={useCalcPad ? '/static/images/common/Icon_ON_Black.png' : '/static/images/common/Icon_OFF_Black.png'} alt="toggle" width={34} height={34} />
</button>
</div>
{type === TYPES.EAVES && <Eaves {...eavesProps} />}
{type === TYPES.GABLE && <Gable {...gableProps} />}
{type === TYPES.WALL_MERGE && <WallMerge {...wallMergeProps} />}

View File

@ -6,7 +6,7 @@ import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText, disableKeypad }) {
const { getMessage } = useMessage()
const [type, setType] = useState('1')
const onChange = (e) => {
@ -43,6 +43,7 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
onChange={(value) => {
if (pitchRef?.current) pitchRef.current.value = value
}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
@ -77,6 +78,7 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
onChange={(value) => {
if (offsetRef?.current) offsetRef.current.value = value
}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
@ -144,6 +146,7 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
onChange={(value) => {
if (widthRef?.current) widthRef.current.value = value
}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),

View File

@ -5,7 +5,7 @@ import { useRecoilValue } from 'recoil'
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText, disableKeypad }) {
const { getMessage } = useMessage()
const [type, setType] = useState('1')
const onChange = (e) => {
@ -30,6 +30,7 @@ export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
className="input-origin block"
ref={offsetRef}
value={300}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
@ -96,6 +97,7 @@ export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
onChange={(value) => {
if (pitchRef?.current) pitchRef.current.value = value
}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
@ -129,6 +131,7 @@ export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
ref={widthRef}
value={800}
readOnly={type === '1'}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),

View File

@ -1,7 +1,7 @@
import { useMessage } from '@/hooks/useMessage'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Shed({ offsetRef }) {
export default function Shed({ offsetRef, disableKeypad }) {
const { getMessage } = useMessage()
return (
<>
@ -19,6 +19,7 @@ export default function Shed({ offsetRef }) {
className="input-origin block"
ref={offsetRef}
value={300}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),

View File

@ -3,7 +3,7 @@ import Image from 'next/image'
import { useState } from 'react'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function WallMerge({ offsetRef, radioTypeRef }) {
export default function WallMerge({ offsetRef, radioTypeRef, disableKeypad }) {
const { getMessage } = useMessage()
const [type, setType] = useState('1')
const onChange = (e) => {
@ -61,6 +61,7 @@ export default function WallMerge({ offsetRef, radioTypeRef }) {
ref={offsetRef}
value={300}
readOnly={type === '1'}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),

View File

@ -3,16 +3,22 @@ import WithDraggable from '@/components/common/draggable/WithDraggable'
import FlowLine from '@/components/floor-plan/modal/movement/type/FlowLine'
import Updown from '@/components/floor-plan/modal/movement/type/Updown'
import { useMovementSetting } from '@/hooks/roofcover/useMovementSetting'
import { useState } from 'react'
import Image from 'next/image'
export default function MovementSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage()
const { TYPE, closePopup, buttonType, type, setType, FLOW_LINE_REF, UP_DOWN_REF, handleSave } = useMovementSetting(id)
const [useCalcPad, setUseCalcPad] = useState(false)
const disableKeypad = !useCalcPad
const flowLineProps = {
FLOW_LINE_REF,
disableKeypad,
}
const updownProps = {
UP_DOWN_REF,
disableKeypad,
}
return (
@ -30,7 +36,10 @@ export default function MovementSetting({ id, pos = { x: 50, y: 230 } }) {
{type === TYPE.FLOW_LINE && <FlowLine {...flowLineProps} />}
{type === TYPE.UP_DOWN && <Updown {...updownProps} />}
</div>
<div className="grid-btn-wrap">
<div className="grid-btn-wrap" style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '5px' }}>
<button style={{ width: 'auto' }} type="button" onClick={() => setUseCalcPad((prev) => !prev)}>
<Image src={useCalcPad ? '/static/images/common/Icon_ON_Black.png' : '/static/images/common/Icon_OFF_Black.png'} alt="toggle" width={34} height={34} />
</button>
<button className="btn-frame modal act" onClick={handleSave}>
{getMessage('modal.common.save')}
</button>

View File

@ -9,7 +9,7 @@ const FLOW_LINE_TYPE = {
UP_RIGHT: 'upRight',
}
export default function FlowLine({ FLOW_LINE_REF }) {
export default function FlowLine({ FLOW_LINE_REF, disableKeypad }) {
const { getMessage } = useMessage()
const [type, setType] = useState(FLOW_LINE_TYPE.DOWN_LEFT)
const [filledInput, setFilledInput] = useState('')
@ -87,6 +87,7 @@ export default function FlowLine({ FLOW_LINE_REF }) {
value={filledInput}
onFocus={handleFocus}
onChange={(value)=>{setFilledInput(value)}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false

View File

@ -10,7 +10,7 @@ const UP_DOWN_TYPE = {
DOWN: 'down',
}
export default function Updown({ UP_DOWN_REF }) {
export default function Updown({ UP_DOWN_REF, disableKeypad }) {
const { getMessage } = useMessage()
const [type, setType] = useState(UP_DOWN_TYPE.UP)
const [filledInput, setFilledInput] = useState('100')
@ -87,6 +87,7 @@ export default function Updown({ UP_DOWN_REF }) {
value={filledInput}
onFocus={handleFocus}
onChange={(value)=>{setFilledInput(value)}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false

View File

@ -5,27 +5,34 @@ import Shed from '@/components/floor-plan/modal/roofShape/passivity/Shed'
import { useMessage } from '@/hooks/useMessage'
import { useRoofShapePassivitySetting } from '@/hooks/roofcover/useRoofShapePassivitySetting'
import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react'
import Image from 'next/image'
export default function RoofShapePassivitySetting({ id, pos = { x: 50, y: 230 } }) {
const { handleSave, handleConfirm, handleRollback, buttons, type, setType, TYPES, offsetRef, pitchRef, pitchText } =
useRoofShapePassivitySetting(id)
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [useCalcPad, setUseCalcPad] = useState(false)
const disableKeypad = !useCalcPad
const eavesProps = {
offsetRef,
pitchRef,
pitchText,
disableKeypad,
}
const gableProps = {
offsetRef,
pitchRef,
pitchText,
disableKeypad,
}
const shedProps = {
offsetRef,
disableKeypad,
}
return (
@ -55,7 +62,10 @@ export default function RoofShapePassivitySetting({ id, pos = { x: 50, y: 230 }
</button>
</div>
</div>
<div className="grid-btn-wrap">
<div className="grid-btn-wrap" style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '5px' }}>
<button style={{ width: 'auto' }} type="button" onClick={() => setUseCalcPad((prev) => !prev)}>
<Image src={useCalcPad ? '/static/images/common/Icon_ON_Black.png' : '/static/images/common/Icon_OFF_Black.png'} alt="toggle" width={34} height={34} />
</button>
<button className="btn-frame modal act" onClick={() => handleSave(id)}>
{getMessage('common.setting.finish')}
</button>

View File

@ -5,7 +5,7 @@ import { selectedRoofMaterialSelector } from '@/store/settingAtom'
import { useEffect } from 'react'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Eaves({ offsetRef, pitchRef, pitchText }) {
export default function Eaves({ offsetRef, pitchRef, pitchText, disableKeypad }) {
const { getMessage } = useMessage()
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
@ -30,6 +30,7 @@ export default function Eaves({ offsetRef, pitchRef, pitchText }) {
className="input-origin block"
ref={pitchRef}
value={currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
@ -52,6 +53,7 @@ export default function Eaves({ offsetRef, pitchRef, pitchText }) {
value={offsetRef.current?.value ?? 500} // Set default value to 500
ref={offsetRef}
onChange={() => {}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false

View File

@ -3,7 +3,7 @@ import { useRecoilValue } from 'recoil'
import { currentAngleTypeSelector } from '@/store/canvasAtom'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Gable({ offsetRef }) {
export default function Gable({ offsetRef, disableKeypad }) {
const { getMessage } = useMessage()
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
return (
@ -22,6 +22,7 @@ export default function Gable({ offsetRef }) {
value={offsetRef.current?.value ?? 300} // Set default value to 500
ref={offsetRef}
onChange={() => {}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false

View File

@ -1,7 +1,7 @@
import { useMessage } from '@/hooks/useMessage'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Shed({ offsetRef }) {
export default function Shed({ offsetRef, disableKeypad }) {
const { getMessage } = useMessage()
return (
<>
@ -19,6 +19,7 @@ export default function Shed({ offsetRef }) {
value={offsetRef.current?.value ?? 300} // Set default value to 500
ref={offsetRef}
onChange={() => {}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false

View File

@ -4,10 +4,14 @@ import WallLine from '@/components/floor-plan/modal/wallLineOffset/type/WallLine
import Offset from '@/components/floor-plan/modal/wallLineOffset/type/Offset'
import { useWallLineOffsetSetting } from '@/hooks/roofcover/useWallLineOffsetSetting'
import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react'
import Image from 'next/image'
export default function WallLineOffsetSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [useCalcPad, setUseCalcPad] = useState(false)
const disableKeypad = !useCalcPad
const {
type,
setType,
@ -30,12 +34,14 @@ export default function WallLineOffsetSetting({ id, pos = { x: 50, y: 230 } }) {
arrow2Ref,
radioTypeRef,
currentWallLineRef,
disableKeypad,
}
const offsetProps = {
length1Ref,
arrow1Ref,
currentWallLineRef,
disableKeypad,
}
return (
@ -54,7 +60,10 @@ export default function WallLineOffsetSetting({ id, pos = { x: 50, y: 230 } }) {
{type === TYPES.WALL_LINE_EDIT && <WallLine ref={wallLineEditRef} {...wallLineProps} />}
{type === TYPES.OFFSET && <Offset {...offsetProps} />}
</div>
<div className="grid-btn-wrap">
<div className="grid-btn-wrap" style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '5px' }}>
<button style={{ width: 'auto' }} type="button" onClick={() => setUseCalcPad((prev) => !prev)}>
<Image src={useCalcPad ? '/static/images/common/Icon_ON_Black.png' : '/static/images/common/Icon_OFF_Black.png'} alt="toggle" width={34} height={34} />
</button>
<button className="btn-frame modal act" onClick={handleSave}>
{getMessage('modal.common.save')}
</button>

View File

@ -3,7 +3,7 @@ import { useEffect, useState } from 'react'
import { useEvent } from '@/hooks/useEvent'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) {
export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef, disableKeypad }) {
const { getMessage } = useMessage()
const { addDocumentEventListener, initEvent } = useEvent()
// const { addDocumentEventListener, initEvent } = useContext(EventContext)
@ -84,6 +84,7 @@ export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) {
value={length1Ref.current?.value ?? 0}
ref={length1Ref}
onChange={() => {}}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false

View File

@ -3,7 +3,7 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'
import { useEvent } from '@/hooks/useEvent'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref, arrow2Ref, radioTypeRef, currentWallLineRef }, ref) {
export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref, arrow2Ref, radioTypeRef, currentWallLineRef, disableKeypad }, ref) {
const { getMessage } = useMessage()
const { addDocumentEventListener, initEvent } = useEvent()
// const { addDocumentEventListener, initEvent } = useContext(EventContext)
@ -57,6 +57,7 @@ export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref,
ref={length1Ref}
onChange={() => {}}
readOnly={type !== 1}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false
@ -105,6 +106,7 @@ export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref,
ref={length2Ref}
onChange={() => {}}
readOnly={type !== 2}
disableKeypad={disableKeypad}
options={{
allowNegative: false,
allowDecimal: false

View File

@ -7,6 +7,7 @@ import { useEffect, useRef } from 'react'
import { fabric } from 'fabric'
import { calculateAngle } from '@/util/qpolygon-utils'
import {
OUTER_LINE_TYPE,
placementShapeDrawingAngle1State,
placementShapeDrawingAngle2State,
placementShapeDrawingArrow1State,
@ -92,6 +93,7 @@ export function usePlacementShapeDrawing(id) {
useEffect(() => {
setPoints([])
setType(OUTER_LINE_TYPE.OUTER_LINE)
return () => {
const placementShapeDrawingStartPoint = canvas.getObjects().find((obj) => obj.name === 'placementShapeDrawingStartPoint')