Merge branch 'dev' into feature/test-jy

# Conflicts:
#	docs/dictionary.txt
#	src/components/Roof2.jsx
#	src/components/fabric/QPolygon.js
#	src/hooks/useMode.js
This commit is contained in:
Jaeyoung Lee 2024-10-25 10:59:07 +09:00
commit 84d5cbbf06
180 changed files with 9565 additions and 5853 deletions

12
.env
View File

@ -1,12 +0,0 @@
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
# DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
# DATABASE_URL="mongodb://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/sample_mflix?retryWrites=true&w=majority"
#DATABASE_URL = "mongodb%2Bsrv%3A%2F%2Fyoo32767%3AGuCtswjLGqUaNL0G%40cluster0.vsdtcnb.mongodb.net%2F%3FretryWrites%3Dtrue%26w%3Dmajority%26appName%3DCluster0"
# DATABASE_URL = "mongodb+srv://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/Cluster0?retryWrites=true&w=majority"
# DATABASE_URL="mongodb://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/sample_mflix?retryWrites=true&w=majority"
DATABASE_URL="mongodb+srv://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/mytest"

View File

@ -1,14 +1,8 @@
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://172.30.1.60:8080"
DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;password=Qwertqaz12345;trustServerCertificate=true"
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-local.q-cells.jp:8120/eos/login/autoLogin" NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-qa.q-cells.jp:8120/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-local.q-cells.jp:8120/qm/login/autoLogin" NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-qa.q-cells.jp:8120/qm/login/autoLogin"

View File

@ -1,12 +1,8 @@
NEXT_PUBLIC_TEST="테스트변수입니다. production"
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080" NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
DATABASE_URL=""
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-local.q-cells.jp:8120/eos/login/autoLogin" NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order.q-cells.jp/eos/login/autoLogin"
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-local.q-cells.jp:8120/qm/login/autoLogin" NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin"

View File

@ -10,7 +10,8 @@
복도치수(입력치수): inputSize 복도치수(입력치수): inputSize
실제치수: actualSize 실제치수: actualSize
테두리만: borderOnly 테두리만: borderOnly
라인해치: lineHatching 라인해치: lineHatch
Allpainted : allPainted
문자글꼴: textFont 문자글꼴: textFont
흐름방향글꼴 : flowDirectionFont 흐름방향글꼴 : flowDirectionFont
회로번호글꼴: circuitNumberFont 회로번호글꼴: circuitNumberFont
@ -24,5 +25,6 @@
개구: openSpace 개구: openSpace
도머: dormer 도머: dormer
그림자: shadow 그림자: shadow
치수선: dimensionLine
복도치수: planeSize 복도치수: planeSize
실제치수: actualSize 실제치수: actualSize

View File

@ -10,7 +10,6 @@
}, },
"dependencies": { "dependencies": {
"@nextui-org/react": "^2.4.2", "@nextui-org/react": "^2.4.2",
"@prisma/client": "^5.18.0",
"ag-grid-react": "^32.0.2", "ag-grid-react": "^32.0.2",
"axios": "^1.7.3", "axios": "^1.7.3",
"fabric": "^5.3.0", "fabric": "^5.3.0",
@ -30,7 +29,6 @@
"react-hook-form": "^7.53.0", "react-hook-form": "^7.53.0",
"react-icons": "^5.3.0", "react-icons": "^5.3.0",
"react-responsive-modal": "^6.4.2", "react-responsive-modal": "^6.4.2",
"react-toastify": "^10.0.5",
"recoil": "^0.7.7", "recoil": "^0.7.7",
"sweetalert2": "^11.14.1", "sweetalert2": "^11.14.1",
"sweetalert2-react-content": "^5.0.7", "sweetalert2-react-content": "^5.0.7",
@ -42,7 +40,6 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"postcss": "^8", "postcss": "^8",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"prisma": "^5.18.0",
"react-color-palette": "^7.2.2", "react-color-palette": "^7.2.2",
"react-select": "^5.8.1", "react-select": "^5.8.1",
"sass": "^1.77.8", "sass": "^1.77.8",

View File

@ -0,0 +1,4 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.998535 1L3.99723 3.99594L6.99593 1" stroke="#697C8F" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 6.98376L3.99319 3.99595L1.00263 6.99999" stroke="#697C8F" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View File

@ -0,0 +1,5 @@
<svg width="15" height="16" viewBox="0 0 15 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="1" width="14" height="14" rx="7" fill="white"/>
<rect x="0.5" y="1" width="14" height="14" rx="7" stroke="#94A0AD"/>
<path d="M9.741 11.059L7.509 8.827L5.277 11.059L4.512 10.294L6.744 8.062L4.512 5.83L5.277 5.065L7.509 7.297L9.741 5.065L10.506 5.83L8.274 8.062L10.506 10.294L9.741 11.059Z" fill="#94A0AD"/>
</svg>

After

Width:  |  Height:  |  Size: 427 B

View File

@ -1,27 +1,19 @@
'use client' 'use client'
import { useEffect } from 'react' // import { useEffect } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
import { ErrorBoundary } from 'next/dist/client/components/error-boundary' import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import ServerError from './error' import ServerError from './error'
import '@/styles/common.scss' import '@/styles/common.scss'
import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json'
export const QcastProvider = ({ children }) => { export const QcastProvider = ({ children }) => {
const globalLocale = useRecoilValue(globalLocaleStore) const { commonCode, findCommonCode } = useCommonCode()
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
useEffect(() => { // useEffect(() => {
if (globalLocale === 'ko') { // console.log('commonCode', commonCode)
setAppMessageState(KO) // console.log(findCommonCode(113600))
} else { // }, [commonCode, findCommonCode])
setAppMessageState(JA)
}
}, [globalLocale])
return ( return (
<> <>

View File

@ -1,11 +0,0 @@
'use client'
import { I18nProviderClient } from '@/locales/client'
export function LocaleProvider({ locale, children }) {
return (
<I18nProviderClient locale={locale} fallback={''}>
{children}
</I18nProviderClient>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Archive from '@/components/community/Archive'
import { initCheck } from '@/util/session-util'
export default async function CommunityArchivePage() {
await initCheck()
return (
<>
<Hero title="자료 다운로드" />
<div className="container flex flex-wrap items-center justify-between mx-auto p-4 m-4 border">
<Archive />
</div>
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Faq from '@/components/community/Faq'
import { initCheck } from '@/util/session-util'
export default async function CommunityFaqPage() {
await initCheck()
return (
<>
<Hero title="FAQ" />
<div className="container flex flex-wrap items-center justify-between mx-auto p-4 m-4 border">
<Faq />
</div>
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Notice from '@/components/community/Notice'
import { initCheck } from '@/util/session-util'
export default async function CommunityNoticePage() {
await initCheck()
return (
<>
<Hero title="공지사항" />
<div className="container flex flex-wrap items-center justify-between mx-auto p-4 m-4 border">
<Notice />
</div>
</>
)
}

View File

@ -1,15 +0,0 @@
'use client'
export default function ServerError() {
return (
<section className="bg-white dark:bg-gray-900">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-sm text-center">
<h1 className="mb-4 text-7xl tracking-tight font-extrabold lg:text-9xl text-primary-600 dark:text-primary-500">500</h1>
<p className="mb-4 text-3xl tracking-tight font-bold text-gray-900 md:text-4xl dark:text-white">Internal Server Error.</p>
<p className="mb-4 text-lg font-light text-gray-500 dark:text-gray-400">We are already working to solve the problem. </p>
</div>
</div>
</section>
)
}

View File

@ -1,9 +0,0 @@
import FloorPlan from '@/components/floor-plan/FloorPlan'
export default function FloorPlanPage() {
return (
<>
<FloorPlan />
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import InitSettingsModal from '@/components/InitSettingsModal'
import { initCheck } from '@/util/session-util'
export default async function InitSettingsModalPage() {
await initCheck()
return (
<>
<Hero title="Basic Settings" />
<div className="flex flex-col justify-center my-8">
<InitSettingsModal />
</div>
</>
)
}

View File

@ -1,14 +0,0 @@
import Intro from '@/components/Intro'
import { initCheck } from '@/util/session-util'
export default async function IntroPage() {
await initCheck()
return (
<>
<div className="container mx-auto p-4 m-4 border">
<Intro />
</div>
</>
)
}

View File

@ -1,19 +0,0 @@
'use client'
import { useMessage } from '@/hooks/useMessage'
export default function CompletePage() {
const { getMessage } = useMessage()
return (
<>
<div className="flex min-h-full flex-1 flex-col justify-center px-6 py-12 lg:px-8">
<h1 className="text-center text-4xl font-bold mb-10">{getMessage('join.complete.title')}</h1>
<div className="mt-10 mb-10 w-full text-center text-2xl">{getMessage('join.complete.contents')}</div>
<div className="mt-10 w-full text-center">
{getMessage('join.complete.email_comment')} :&nbsp;{getMessage('join.complete.email')}
</div>
</div>
</>
)
}

View File

@ -1,5 +0,0 @@
import Join from '@/components/auth/Join'
export default function JoinPage() {
return <>{<Join />}</>
}

View File

@ -1,42 +0,0 @@
'use client'
import { useEffect } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
import { LocaleProvider } from './LocaleProvider'
import { useCurrentLocale } from '@/locales/client'
import ServerError from './error'
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
import '@/styles/common.scss'
import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json'
export default function LocaleLayout({ children }) {
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 (
<>
<ErrorBoundary fallback={<ServerError />}>
<LocaleProvider locale={locale} fallback={<ServerError />}>
{children}
</LocaleProvider>
</ErrorBoundary>
</>
)
}

View File

@ -1,16 +0,0 @@
import Login from '@/components/auth/Login'
import { getCurrentLocale } from '@/locales/server'
export default function LoginPage() {
const currentLocale = getCurrentLocale()
const loginPageProps = {
currentLocale,
}
return (
<>
<Login {...loginPageProps} />
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Plan from '@/components/management/Plan'
import { initCheck } from '@/util/session-util'
export default async function ManagementPlanPage() {
await initCheck()
return (
<>
<Hero title="도면관리" />
<div className="container flex flex-wrap items-center justify-between mx-auto p-4 m-4 border">
<Plan />
</div>
</>
)
}

View File

@ -1,19 +0,0 @@
import React from 'react'
import Hero from '@/components/Hero'
import StuffDetail from '@/components/management/StuffDetail'
import Link from 'next/link'
export default function ManagementStuffDetailPage() {
return (
<>
<div className="pt-48 flex justify-left">
<h1 className="text-4xl archivo-black-regular">물건정보</h1>
<Link href="/management/plan">
<h1 className="text-4xl archivo-black-regular">도면작성</h1>
</Link>
</div>
<div className="m2">
<StuffDetail />
</div>
</>
)
}

View File

@ -1,21 +0,0 @@
import StuffSearchCondition from '@/components/management/StuffSearchCondition'
import Stuff from '@/components/management/Stuff'
import { initCheck } from '@/util/session-util'
import Hero from '@/components/Hero'
export default async function ManagementStuffPage() {
await initCheck()
return (
<>
<Hero title="물건현황" />
<div>
<div className="m2">
<StuffSearchCondition />
</div>
</div>
<div className="flex flex-col justify-center my-8 pt-20">
<Stuff />
</div>
</>
)
}

View File

@ -1,15 +0,0 @@
import React from 'react'
import Hero from '@/components/Hero'
import StuffDetail from '@/components/management/StuffDetail'
export default function ManagementStuffDetailPage() {
return (
<>
<div className="pt-48 flex justify-left">
<h1 className="text-4xl archivo-black-regular">물건정보</h1>
</div>
<div className="m2">
<StuffDetail />
</div>
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Company from '@/components/master/Company'
import { initCheck } from '@/util/session-util'
export default async function MasterCompanyPage() {
await initCheck()
return (
<>
<Hero title="회사정보 조회" />
<div className="container flex flex-wrap items-center justify-between mx-auto p-4 m-4 border">
<Company />
</div>
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Price from '@/components/master/Price'
import { initCheck } from '@/util/session-util'
export default async function MasterPricePage() {
await initCheck()
return (
<>
<Hero title="가격 마스터 조회" />
<div className="container flex flex-wrap items-center justify-between mx-auto p-4 m-4 border">
<Price />
</div>
</>
)
}

View File

@ -1,25 +0,0 @@
'use client'
import Link from 'next/link'
export default function NotFound() {
return (
<section className="bg-white dark:bg-gray-900">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-sm text-center">
<h1 className="mb-4 text-7xl tracking-tight font-extrabold lg:text-9xl text-primary-600 dark:text-primary-500">404</h1>
<p className="mb-4 text-3xl tracking-tight font-bold text-gray-900 md:text-4xl dark:text-white">Something's missing.</p>
<p className="mb-4 text-lg font-light text-gray-500 dark:text-gray-400">
Sorry, we can't find that page. You'll find lots to explore on the home page.{' '}
</p>
<Link
href="/"
className="inline-flex text-white bg-primary-600 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-primary-900 my-4"
>
Back to Homepage
</Link>
</div>
</div>
</section>
)
}

View File

@ -1,18 +0,0 @@
import { getSession } from '@/lib/authActions'
import MainPage from '@/components/Main'
export default async function page() {
const session = await getSession()
const mainPageProps = {
isLoggedIn: session?.isLoggedIn,
}
return (
<>
<div className="m-4">
<MainPage {...mainPageProps} />
</div>
</>
)
}

View File

@ -1,17 +0,0 @@
import Playground from '@/components/Playground'
import { initCheck } from '@/util/session-util'
export default async function PlaygroundPage() {
// const { session } = await checkSession()
// if (!session.isLoggedIn) {
// redirect('/login')
// }
await initCheck()
return (
<>
<Playground />
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Roof from '@/components/Roof'
import { initCheck } from '@/util/session-util'
export default async function RoofPage() {
await initCheck()
return (
<>
<Hero title="Drawing on canvas 2D Roof" />
<div className="flex flex-col justify-center my-8">
<Roof />
</div>
</>
)
}

View File

@ -1,128 +0,0 @@
'use client'
import { Select, SelectItem } from '@nextui-org/react'
import { useEffect, useState } from 'react'
import { useAxios } from '@/hooks/useAxios'
export default function RoofSelect() {
const [roofMaterials, setRoofMaterials] = useState([])
const [manufacturers, setManufacturers] = useState([])
const [trestles, setTrestles] = useState([])
const [modules, setModules] = useState([])
const [originTrestles, setOriginTrestles] = useState([])
const [roofMaterialId, setRoofMaterialId] = useState(null)
const [manufacturerId, setManufacturerId] = useState(null)
const [trestleId, setTrestleId] = useState(null)
const { get } = useAxios()
useEffect(() => {
get({ url: '/api/roof-material/roof-material-infos' }).then((res) => {
//TODO: error handling
if (!res) return
setRoofMaterials(res)
})
}, [])
useEffect(() => {
if (!roofMaterialId) {
return
}
get({ url: `/api/roof-material/roof-material-infos/${roofMaterialId}/trestles` }).then((res) => {
if (res.length === 0) {
return
}
setOriginTrestles(res)
const manufactural = res.map((trestle) => {
return { id: trestle.manufacturerId, name: trestle.manufacturerName }
})
// Remove duplicates
const uniqueManufactural = Array.from(new Set(manufactural.map((a) => a.id))).map((id) => {
return manufactural.find((a) => a.id === id)
})
setManufacturers(uniqueManufactural)
})
}, [roofMaterialId])
useEffect(() => {
if (!manufacturerId) {
return
}
const trestles = originTrestles.filter((trestle) => trestle.manufacturerId === manufacturerId)
setTrestles(trestles)
}, [manufacturerId])
useEffect(() => {
if (!trestleId) {
return
}
get({ url: `/api/module/module-infos?roofMaterialId=${roofMaterialId}&trestleId=${trestleId}` }).then((res) => {
if (res.length === 0) {
return
}
setModules(res)
})
}, [trestleId])
const handleRoofMaterialOnChange = (e) => {
const roofMaterialId = e.target.value
setRoofMaterialId(roofMaterialId)
setManufacturers([])
setManufacturerId(null)
setTrestleId(null)
setTrestles([])
setModules([])
}
const handleManufacturersOnChange = (e) => {
const manufacturerId = Number(e.target.value)
setTrestles([])
setManufacturerId(manufacturerId)
setTrestleId(null)
setModules([])
}
const handleTrestlesOnChange = (e) => {
const trestleId = Number(e.target.value)
setTrestleId(trestleId)
setModules([])
}
return (
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
{roofMaterials.length > 0 && (
<Select label="지붕재" className="max-w-xs" onChange={handleRoofMaterialOnChange}>
{roofMaterials.map((roofMaterial) => (
<SelectItem key={roofMaterial.id}>{roofMaterial.name}</SelectItem>
))}
</Select>
)}
{manufacturers.length > 0 && (
<Select label="제조 회사" className="max-w-xs" onChange={handleManufacturersOnChange}>
{manufacturers.map((manufacturer) => (
<SelectItem key={manufacturer.id}>{manufacturer.name}</SelectItem>
))}
</Select>
)}
{trestles.length > 0 && (
<Select label="가대" className="max-w-xs" onChange={handleTrestlesOnChange}>
{trestles.map((trestle) => (
<SelectItem key={trestle.id}>{trestle.name}</SelectItem>
))}
</Select>
)}
{modules.length > 0 && (
<Select label="설치가능 모듈" className="max-w-xs">
{modules.map((module) => (
<SelectItem key={module.id}>{module.name}</SelectItem>
))}
</Select>
)}
</div>
)
}

View File

@ -1,26 +0,0 @@
import Roof2 from '@/components/Roof2'
import RoofSelect from '@/app/[locale]/roof2/RoofSelect'
import { initCheck } from '@/util/session-util'
export default async function Roof2Page() {
const session = await initCheck()
const roof2Props = {
name: session.name || '',
userId: session.userId || '',
email: session.email || '',
isLoggedIn: session.isLoggedIn,
}
return (
<>
<div>
<div className="m-2">
<RoofSelect />
</div>
</div>
<div className="flex flex-col justify-center my-8 pt-20">
<Roof2 {...roof2Props} />
</div>
</>
)
}

View File

@ -1,16 +0,0 @@
import Hero from '@/components/Hero'
import Settings from '@/components/Settings'
import { initCheck } from '@/util/session-util'
export default async function SettingsPage() {
await initCheck()
return (
<>
<Hero title="Canvas Setting" />
<div className="flex flex-col justify-center my-8">
<Settings />
</div>
</>
)
}

View File

@ -1,10 +1,7 @@
import Hero from '@/components/Hero' import Hero from '@/components/Hero'
import Archive from '@/components/community/Archive' import Archive from '@/components/community/Archive'
import { initCheck } from '@/util/session-util'
export default async function CommunityArchivePage() { export default async function CommunityArchivePage() {
await initCheck()
return ( return (
<> <>
<Archive /> <Archive />

View File

@ -1,9 +1,6 @@
import Faq from '@/components/community/Faq' import Faq from '@/components/community/Faq'
import { initCheck } from '@/util/session-util'
export default async function CommunityFaqPage() { export default async function CommunityFaqPage() {
await initCheck()
return ( return (
<> <>
<Faq /> <Faq />

View File

@ -1,9 +1,6 @@
import Notice from '@/components/community/Notice' import Notice from '@/components/community/Notice'
import { initCheck } from '@/util/session-util'
export default async function CommunityNoticePage() { export default async function CommunityNoticePage() {
await initCheck()
return ( return (
<> <>
<Notice /> <Notice />

View File

@ -1,10 +1,7 @@
import Hero from '@/components/Hero' import Hero from '@/components/Hero'
import InitSettingsModal from '@/components/InitSettingsModal' import InitSettingsModal from '@/components/InitSettingsModal'
import { initCheck } from '@/util/session-util'
export default async function InitSettingsModalPage() { export default async function InitSettingsModalPage() {
await initCheck()
return ( return (
<> <>
<Hero title="Basic Settings" /> <Hero title="Basic Settings" />

View File

@ -2,8 +2,6 @@ import Intro from '@/components/Intro'
import { initCheck } from '@/util/session-util' import { initCheck } from '@/util/session-util'
export default async function IntroPage() { export default async function IntroPage() {
await initCheck()
return ( return (
<> <>
<div className="container mx-auto p-4 m-4 border"> <div className="container mx-auto p-4 m-4 border">

View File

@ -1,23 +1,19 @@
// import { Inter } from 'next/font/google'
import { headers } from 'next/headers' import { headers } from 'next/headers'
import { redirect } from 'next/navigation' import { redirect } from 'next/navigation'
import { getSession } from '@/lib/authActions' import { getSession } from '@/lib/authActions'
import RecoilRootWrapper from './RecoilWrapper' import RecoilRootWrapper from './RecoilWrapper'
import { ToastContainer } from 'react-toastify'
import { QcastProvider } from './QcastProvider' import { QcastProvider } from './QcastProvider'
import Header from '@/components/header/Header' import Header from '@/components/header/Header'
import QModal from '@/components/common/modal/QModal' import QModal from '@/components/common/modal/QModal'
import Dimmed from '@/components/ui/Dimmed'
import SessionProvider from './SessionProvider'
import PopupManager from '@/components/common/popupManager/PopupManager'
import './globals.css' import './globals.css'
import '../styles/style.scss' import '../styles/style.scss'
import '../styles/contents.scss' import '../styles/contents.scss'
import Dimmed from '@/components/ui/Dimmed' import Footer from '@/components/footer/Footer'
import SessionProvider from './SessionProvider'
// const inter = Inter({ subsets: ['latin'] })
export const metadata = { export const metadata = {
title: 'Create Next App', title: 'Create Next App',
@ -28,8 +24,6 @@ export default async function RootLayout({ children }) {
const headersList = headers() const headersList = headers()
const headerPathname = headersList.get('x-pathname') || '' const headerPathname = headersList.get('x-pathname') || ''
// console.log('headerPathname:', headerPathname)
// const isLoggedIn = await checkSession()
const session = await getSession() const session = await getSession()
console.log('session[layout]:', session) console.log('session[layout]:', session)
@ -75,15 +69,11 @@ export default async function RootLayout({ children }) {
<SessionProvider useSession={sessionProps}>{children}</SessionProvider> <SessionProvider useSession={sessionProps}>{children}</SessionProvider>
</QcastProvider> </QcastProvider>
</div> </div>
<footer> <Footer />
<div className="footer-inner">
<span>COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</span>
</div>
</footer>
</div> </div>
)} )}
<ToastContainer />
<QModal /> <QModal />
<PopupManager />
</body> </body>
</html> </html>
</RecoilRootWrapper> </RecoilRootWrapper>

View File

@ -1,10 +1,7 @@
import Hero from '@/components/Hero' import Hero from '@/components/Hero'
import Plan from '@/components/management/Plan' import Plan from '@/components/management/Plan'
import { initCheck } from '@/util/session-util'
export default async function ManagementPlanPage() { export default async function ManagementPlanPage() {
await initCheck()
return ( return (
<> <>
<Hero title="도면관리" /> <Hero title="도면관리" />

View File

@ -1,36 +1,14 @@
import React from 'react' import React from 'react'
import Link from 'next/link'
import Image from 'next/image'
import '@/styles/contents.scss' import '@/styles/contents.scss'
import StuffSubHeader from '@/components/management/StuffSubHeader'
import StuffHeader from '@/components/management/StuffHeader' import StuffHeader from '@/components/management/StuffHeader'
import StuffDetail from '@/components/management/StuffDetail' import StuffDetail from '@/components/management/StuffDetail'
import '@/styles/contents.scss'
import '@/styles/grid.scss'
export default function ManagementStuffDetailPage() { export default function ManagementStuffDetailPage() {
return ( return (
<> <>
<div className="sub-header"> <StuffSubHeader type={'detail'} />
<div className="sub-header-inner">
<ul className="sub-header-title-wrap">
<li className="title-item">
<Link className="sub-header-title" href={'#'}>
商品情報
</Link>
</li>
</ul>
<ul className="sub-header-location">
<li className="location-item">
<span className="home">
<Image src="/static/images/main/home_icon.svg" alt="react" width={16} height={16} />
</span>
</li>
<li className="location-item">
<span>物品及び図面管理</span>
</li>
<li className="location-item">
<span>商品情報</span>
</li>
</ul>
</div>
</div>
<div className="sub-content"> <div className="sub-content">
<div className="sub-content-inner"> <div className="sub-content-inner">
<div className="sub-content-box"> <div className="sub-content-box">

View File

@ -1,31 +1,11 @@
import StuffSearchCondition from '@/components/management/StuffSearchCondition' import StuffSearchCondition from '@/components/management/StuffSearchCondition'
import Stuff from '@/components/management/Stuff' import Stuff from '@/components/management/Stuff'
import { initCheck } from '@/util/session-util' import StuffSubHeader from '@/components/management/StuffSubHeader'
import Image from 'next/image' import '@/styles/grid.scss'
import '@/styles/contents.scss'
export default async function ManagementStuffPage() { export default async function ManagementStuffPage() {
await initCheck()
return ( return (
<> <>
<div className="sub-header"> <StuffSubHeader type={'list'} />
<div className="sub-header-inner">
<h1 className="sub-header-title">物品及び図面管理</h1>
<ul className="sub-header-location">
<li className="location-item">
<span className="home">
<Image src="/static/images/main/home_icon.svg" alt="react" width={16} height={16} />
</span>
</li>
<li className="location-item">
<span>物品及び図面管理</span>
</li>
<li className="location-item">
<span>新規物件登録</span>
</li>
</ul>
</div>
</div>
<div className="sub-content"> <div className="sub-content">
<div className="sub-content-inner"> <div className="sub-content-inner">
<div className="sub-content-box"> <div className="sub-content-box">

View File

@ -1,35 +1,11 @@
import React from 'react' import React from 'react'
import Link from 'next/link' import StuffSubHeader from '@/components/management/StuffSubHeader'
import Image from 'next/image'
import '@/styles/contents.scss' import '@/styles/contents.scss'
import StuffDetail from '@/components/management/StuffDetail' import StuffDetail from '@/components/management/StuffDetail'
export default function ManagementStuffDetailPage() { export default function ManagementStuffDetailPage() {
return ( return (
<> <>
<div className="sub-header"> <StuffSubHeader type={'temp'} />
<div className="sub-header-inner">
<ul className="sub-header-title-wrap">
<li className="title-item">
<Link className="sub-header-title" href={'#'}>
商品情報
</Link>
</li>
</ul>
<ul className="sub-header-location">
<li className="location-item">
<span className="home">
<Image src="/static/images/main/home_icon.svg" alt="react" width={16} height={16} />
</span>
</li>
<li className="location-item">
<span>物品及び図面管理</span>
</li>
<li className="location-item">
<span>商品情報</span>
</li>
</ul>
</div>
</div>
<div className="sub-content"> <div className="sub-content">
<div className="sub-content-inner"> <div className="sub-content-inner">
<div className="sub-content-box"> <div className="sub-content-box">

View File

@ -1,10 +1,7 @@
import Hero from '@/components/Hero' import Hero from '@/components/Hero'
import Company from '@/components/master/Company' import Company from '@/components/master/Company'
import { initCheck } from '@/util/session-util'
export default async function MasterCompanyPage() { export default async function MasterCompanyPage() {
await initCheck()
return ( return (
<> <>
<Hero title="회사정보 조회" /> <Hero title="회사정보 조회" />

View File

@ -1,10 +1,7 @@
import Hero from '@/components/Hero' import Hero from '@/components/Hero'
import Price from '@/components/master/Price' import Price from '@/components/master/Price'
import { initCheck } from '@/util/session-util'
export default async function MasterPricePage() { export default async function MasterPricePage() {
await initCheck()
return ( return (
<> <>
<Hero title="가격 마스터 조회" /> <Hero title="가격 마스터 조회" />

View File

@ -1,14 +1,6 @@
import Playground from '@/components/Playground' import Playground from '@/components/Playground'
import { initCheck } from '@/util/session-util'
export default async function PlaygroundPage() { export default async function PlaygroundPage() {
// const { session } = await checkSession()
// if (!session.isLoggedIn) {
// redirect('/login')
// }
await initCheck()
return ( return (
<> <>
<Playground /> <Playground />

View File

@ -1,10 +1,7 @@
import Hero from '@/components/Hero' import Hero from '@/components/Hero'
import Roof from '@/components/Roof' import Roof from '@/components/Roof'
import { initCheck } from '@/util/session-util'
export default async function RoofPage() { export default async function RoofPage() {
await initCheck()
return ( return (
<> <>
<Hero title="Drawing on canvas 2D Roof" /> <Hero title="Drawing on canvas 2D Roof" />

View File

@ -1,6 +1,6 @@
import Roof2 from '@/components/Roof2' import Roof2 from '@/components/Roof2'
import RoofSelect from '@/app/[locale]/roof2/RoofSelect'
import { initCheck } from '@/util/session-util' import { initCheck } from '@/util/session-util'
import RoofSelect from '@/app/roof2/RoofSelect'
export default async function Roof2Page() { export default async function Roof2Page() {
const session = await initCheck() const session = await initCheck()

View File

@ -1,10 +1,7 @@
import Hero from '@/components/Hero' import Hero from '@/components/Hero'
import Settings from '@/components/Settings' import Settings from '@/components/Settings'
import { initCheck } from '@/util/session-util'
export default async function SettingsPage() { export default async function SettingsPage() {
await initCheck()
return ( return (
<> <>
<Hero title="Canvas Setting" /> <Hero title="Canvas Setting" />

View File

@ -0,0 +1,23 @@
'use client'
import { globalLocaleStore } from '@/store/localeAtom'
import { useRecoilState } from 'recoil'
export default function LocaleSwitch() {
const [globalLocale, setGlobalLocale] = useRecoilState(globalLocaleStore)
return (
<span
className="locale-switch"
onClick={() => {
if (globalLocale === 'ko') {
setGlobalLocale('ja')
} else {
setGlobalLocale('ko')
}
}}
>
{globalLocale.toUpperCase()}
</span>
)
}

View File

@ -2,39 +2,32 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import { modalContent, modalState, modalProps } from '@/store/modalAtom'
import { sessionStore } from '@/store/commonAtom' import { sessionStore } from '@/store/commonAtom'
import { useAxios } from '@/hooks/useAxios' import { useAxios } from '@/hooks/useAxios'
import { globalLocaleStore } from '@/store/localeAtom' import { globalLocaleStore } from '@/store/localeAtom'
import MainContents from './main/MainContents' import MainContents from './main/MainContents'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { stuffSearchState } from '@/store/stuffAtom' import { stuffSearchState } from '@/store/stuffAtom'
import { useForm } from 'react-hook-form'
import '@/styles/contents.scss' import '@/styles/contents.scss'
import ChangePasswordPop from './main/ChangePasswordPop' import ChangePasswordPop from './main/ChangePasswordPop'
import { searchState } from '@/store/boardAtom' import { searchState } from '@/store/boardAtom'
export default function MainPage() { export default function MainPage() {
const [sessionState, setSessionState] = useRecoilState(sessionStore) const sessionState = useRecoilValue(sessionStore)
const globalLocaleState = useRecoilValue(globalLocaleStore) const globalLocaleState = useRecoilValue(globalLocaleStore)
const { get } = useAxios(globalLocaleState) const { promiseGet } = useAxios(globalLocaleState)
const router = useRouter() const router = useRouter()
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [searchTxt, setSearchTxt] = useState('') const [searchTxt, setSearchTxt] = useState('')
const [searchRadioType, setSearchRadioType] = useState('object') const [searchRadioType, setSearchRadioType] = useState('object')
//
const [saleStoreId, setSaleStoreId] = useState('') const [saleStoreId, setSaleStoreId] = useState('')
const [saleStoreName, setSaleStoreName] = useState('') const [saleStoreName, setSaleStoreName] = useState('')
const [objectList, setObjectList] = useState([])
const [businessCharger, setBusinessCharger] = useState('')
const [businessChargerMail, setBusinessChargerMail] = useState('')
const [businessChargerTel, setBusinessChargerTel] = useState('')
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
const [searchForm, setSearchForm] = useRecoilState(searchState) const [searchForm, setSearchForm] = useRecoilState(searchState)
@ -47,17 +40,15 @@ export default function MainPage() {
const fetchObjectList = async () => { const fetchObjectList = async () => {
try { try {
// const apiUrl = `/api/main-page/object/X167/list`
const apiUrl = `/api/main-page/object/${sessionState?.storeId}/list` const apiUrl = `/api/main-page/object/${sessionState?.storeId}/list`
const res = await get({ url: apiUrl }) await promiseGet({
if (res) { url: apiUrl,
setSaleStoreId(res.saleStoreId) }).then((res) => {
setSaleStoreName(res.saleStoreName) if (res.status === 200) {
setObjectList(res.objectList) setSaleStoreId(res.data.saleStoreId)
setBusinessCharger(res.businessCharger) setSaleStoreName(res.data.saleStoreName)
setBusinessChargerMail(res.businessChargerMail) }
setBusinessChargerTel(res.businessChargerTel) })
}
} catch (error) { } catch (error) {
console.error('MAIN API fetching error:', error) console.error('MAIN API fetching error:', error)
} }
@ -143,12 +134,7 @@ export default function MainPage() {
<button className="search-icon" onClick={handleOnSubmit}></button> <button className="search-icon" onClick={handleOnSubmit}></button>
</div> </div>
</div> </div>
<MainContents <MainContents />
objectList={objectList}
businessCharger={businessCharger}
businessChargerMail={businessChargerMail}
businessChargerTel={businessChargerTel}
/>
</div> </div>
</> </>
)) || ( )) || (

View File

@ -138,7 +138,7 @@ export default function Playground() {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
pagePerBlock: 10, pagePerBlock: 10,
totalCount: 501, totalCount: 26,
handleChangePage: (page) => { handleChangePage: (page) => {
console.log('page', page) console.log('page', page)
}, },

View File

@ -0,0 +1,21 @@
'use client'
import { useMessage } from '@/hooks/useMessage'
export default function AutoLoginPage() {
const { getMessage } = useMessage()
return (
<div className="login-input-frame">
<div className="login-frame-tit ">
<span>{getMessage('site.name')}</span>
{getMessage('site.sub_name')}
</div>
<div className="login-input-wrap">
<div className="login-area id" style={{ fontWeight: 'bolder' }}>
{getMessage('login.auto.page.text')}
</div>
</div>
</div>
)
}

View File

@ -15,6 +15,8 @@ import Cookies from 'js-cookie'
import { useSearchParams } from 'next/navigation' import { useSearchParams } from 'next/navigation'
import AutoLogin from './AutoLogin'
export default function Login() { export default function Login() {
// //
const initParams = useSearchParams() const initParams = useSearchParams()
@ -69,6 +71,10 @@ export default function Login() {
const { promisePost, promisePatch, post } = useAxios(globalLocaleState) const { promisePost, promisePatch, post } = useAxios(globalLocaleState)
// focus state
const [idFocus, setIdFocus] = useState(false)
const [secFocus, setSecFocus] = useState(false)
// login process // login process
const loginProcess = async (e) => { const loginProcess = async (e) => {
e.preventDefault() e.preventDefault()
@ -180,8 +186,7 @@ export default function Login() {
<Link href={'/login'} className="login-logo"> <Link href={'/login'} className="login-logo">
<Image src="/static/images/main/login-logo.svg" alt="react" width={236} height={43} styles={{ width: '236px', height: '43px' }} priority /> <Image src="/static/images/main/login-logo.svg" alt="react" width={236} height={43} styles={{ width: '236px', height: '43px' }} priority />
</Link> </Link>
{!autoLoginParam && passwordReset === 1 && (
{passwordReset === 1 && (
<> <>
<div className="login-input-frame"> <div className="login-input-frame">
<form onSubmit={loginProcess} className="space-y-6"> <form onSubmit={loginProcess} className="space-y-6">
@ -190,7 +195,7 @@ export default function Login() {
{getMessage('site.sub_name')} {getMessage('site.sub_name')}
</div> </div>
<div className="login-input-wrap"> <div className="login-input-wrap">
<div className="login-area id"> <div className={`login-area id ${idFocus ? 'focus' : ''}`}>
<input <input
type="text" type="text"
className="login-input" className="login-input"
@ -202,6 +207,8 @@ export default function Login() {
onChange={(e) => { onChange={(e) => {
setUserId(e.target.value) setUserId(e.target.value)
}} }}
onFocus={() => setIdFocus(true)}
onBlur={() => setIdFocus(false)}
/> />
<button <button
type="button" type="button"
@ -211,7 +218,7 @@ export default function Login() {
}} }}
></button> ></button>
</div> </div>
<div className="login-area password"> <div className={`login-area password ${secFocus ? 'focus' : ''}`}>
<input <input
type={passwordVisible ? 'text' : 'password'} type={passwordVisible ? 'text' : 'password'}
className="login-input" className="login-input"
@ -223,8 +230,11 @@ export default function Login() {
onChange={(e) => { onChange={(e) => {
setPasswordVisible(passwordVisible) setPasswordVisible(passwordVisible)
}} }}
onFocus={() => setSecFocus(true)}
onBlur={() => setSecFocus(false)}
/> />
<button <button
type="button"
className={`password-hidden ${passwordVisible ? 'visible' : ''}`} className={`password-hidden ${passwordVisible ? 'visible' : ''}`}
onClick={(e) => { onClick={(e) => {
e.preventDefault() e.preventDefault()
@ -266,7 +276,7 @@ export default function Login() {
</div> </div>
</> </>
)} )}
{passwordReset === 2 && ( {!autoLoginParam && passwordReset === 2 && (
<> <>
<div className="login-input-frame"> <div className="login-input-frame">
<div className="login-frame-tit pw-reset"> <div className="login-frame-tit pw-reset">
@ -274,7 +284,7 @@ export default function Login() {
{getMessage('login.init_password.sub_title')} {getMessage('login.init_password.sub_title')}
</div> </div>
<div className="login-input-wrap"> <div className="login-input-wrap">
<div className="login-area id"> <div className={`login-area id ${idFocus ? 'focus' : ''}`}>
<input <input
type="text" type="text"
id="checkId" id="checkId"
@ -286,6 +296,8 @@ export default function Login() {
onChange={(e) => { onChange={(e) => {
setCheckId(e.target.value) setCheckId(e.target.value)
}} }}
onFocus={() => setIdFocus(true)}
onBlur={() => setIdFocus(false)}
/> />
<button <button
type="button" type="button"
@ -295,7 +307,7 @@ export default function Login() {
}} }}
></button> ></button>
</div> </div>
<div className="login-area email"> <div className={`login-area email ${secFocus ? 'focus' : ''}`}>
<input <input
id="checkEmail" id="checkEmail"
name="checkEmail" name="checkEmail"
@ -307,6 +319,8 @@ export default function Login() {
setCheckEmail(e.target.value) setCheckEmail(e.target.value)
}} }}
placeholder={getMessage('login.init_password.email.placeholder')} placeholder={getMessage('login.init_password.email.placeholder')}
onFocus={() => setSecFocus(true)}
onBlur={() => setSecFocus(false)}
/> />
<button <button
type="button" type="button"
@ -328,6 +342,7 @@ export default function Login() {
</div> </div>
</> </>
)} )}
{autoLoginParam && <AutoLogin />}
</div> </div>
<div className="login-copyright">COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</div> <div className="login-copyright">COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</div>
</div> </div>

View File

@ -1,11 +1,30 @@
import { HexColorPicker } from 'react-colorful' import { HexColorPicker } from 'react-colorful'
import { useMessage } from '@/hooks/useMessage'
export default function ColorPicker(props) { export default function ColorPicker(props) {
const { color, setColor } = props const { color, setColor } = props
const { getMessage } = useMessage()
const defaultColors = ['#EA575D', '#F29955', '#F2C957', '#32975D', '#3D7FED', '#828282', '#ffffff', '#000000']
return ( return (
<> <>
<HexColorPicker color={color} onChange={setColor} /> <div>
<HexColorPicker color={color} onChange={setColor} />
</div>
<div className="hex-color-box">
<div className="color-box-tit">HEX</div>
<div className="color-hex-input">
<input type="text" className="input-origin" value={color} onChange={(e) => setColor(e.target.value)} />
</div>
<div className="color-box" style={{ backgroundColor: color }}></div>
</div>
<div className="default-color-wrap">
<div className="default-tit">{getMessage('modal.color.picker.default.color')}</div>
<div className="color-button-wrap">
{defaultColors.map((color, index) => (
<button key={index} className="default-color" style={{ backgroundColor: color }} onClick={() => setColor(color)}></button>
))}
</div>
</div>
</> </>
) )
} }

View File

@ -0,0 +1,62 @@
import WithDraggable from '@/components/common/draggable/WithDraggable'
import ColorPicker from '@/components/common/color-picker/ColorPicker'
import { useMessage } from '@/hooks/useMessage'
import { useEffect, useState } from 'react'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function ColorPickerModal(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState) //
const { isShow, setIsShow, pos = contextPopupPosition, color = '#ff0000', setColor, id } = props
const { getMessage } = useMessage()
const [originColor, setOriginColor] = useState(color)
const { closePopup } = usePopup()
useEffect(() => {
setOriginColor(color)
}, [isShow])
return (
<WithDraggable isShow={true} pos={pos ?? ''}>
<div className={`modal-pop-wrap lr mount`}>
<div className="modal-head">
<h1 className="title">{getMessage('modal.color.picker.title')}</h1>
<button
className="modal-close"
onClick={() => {
if (setIsShow) {
setIsShow(false)
}
console.log(id)
closePopup(id)
}}
>
닫기
</button>
</div>
<div className="modal-body">
<div className="color-setting-wrap">
<div className="color-tit">COLOR PICKER</div>
<div className="color-picker">
<ColorPicker color={originColor} setColor={setOriginColor} />
</div>
</div>
<div className="grid-btn-wrap">
<button
className="btn-frame modal act"
onClick={() => {
if (setColor) setColor(originColor)
if (setIsShow) setIsShow(false)
closePopup(id)
}}
>
{getMessage('common.message.save')}
</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -0,0 +1,146 @@
import WithDraggable from '@/components/common/draggable/WithDraggable'
import QSelectBox from '@/components/common/select/QSelectBox'
import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { useRecoilState, useRecoilValue } from 'recoil'
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
import { contextPopupPositionState } from '@/store/popupAtom'
const fonts = [
{ name: 'MS PGothic', value: 'MS PGothic' },
{ name: '@Yu Gothic', value: '@Yu Gothic' },
{ name: 'Yu Gothic', value: 'Yu Gothic' },
{ name: '@Yu Gothic UI', value: '@Yu Gothic UI' },
{ name: 'Yu Gothic UI', value: 'Yu Gothic UI' },
]
const fontOptions = [
{ name: '보통', value: 'normal' },
{ name: '기울임꼴', value: 'italic' },
{
name: '굵게',
value: 'bold',
},
{ name: '굵은 기울임꼴', value: 'boldAndItalic' },
]
const fontSizes = [
...Array.from({ length: 4 }).map((_, index) => {
return { name: index + 8, value: index + 8 }
}),
...Array.from({ length: 9 }).map((_, index) => {
return { name: (index + 6) * 2, value: (index + 6) * 2 }
}),
{ name: 36, value: 36 },
{ name: 48, value: 48 },
{ name: 72, value: 72 },
]
const fontColors = [
{ name: '검정색', value: 'black' },
{ name: '빨강색', value: 'red' },
{ name: '파랑색', value: 'blue' },
{ name: '회색', value: 'gray' },
{ name: '황색', value: 'yellow' },
{ name: '녹색', value: 'green' },
{ name: '분홍색', value: 'pink' },
{ name: '황금색', value: 'gold' },
{ name: '남색', value: 'darkblue' },
]
export default function FontSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, setIsShow, pos = contextPopupPosition, type } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
const currentFont = useRecoilValue(fontSelector(type))
const [selectedFont, setSelectedFont] = useState(currentFont.fontFamily)
const [selectedFontWeight, setSelectedFontWeight] = useState(currentFont.fontWeight)
const [selectedFontSize, setSelectedFontSize] = useState(currentFont.fontSize)
const [selectedFontColor, setSelectedFontColor] = useState(currentFont.fontColor)
const handleSaveBtn = () => {
setGlobalFont((prev) => {
return {
...prev,
[type]: {
fontFamily: selectedFont,
fontSize: selectedFontSize,
fontColor: selectedFontColor,
fontWeight: selectedFontWeight,
},
}
})
if (setIsShow) setIsShow(false)
closePopup(id)
}
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lrr mount`}>
<div className="modal-head">
<h1 className="title">{getMessage('modal.font')}</h1>
<button
className="modal-close"
onClick={() => {
if (setIsShow) setIsShow(false)
closePopup(id)
}}
>
닫기
</button>
</div>
<div className="modal-body">
<div className="slope-wrap">
<div className="font-option-warp">
<div className="font-option-item">
<div className="option-item-tit">{getMessage('modal.font')}(F)</div>
<div className="grid-select">
<QSelectBox options={fonts} value={selectedFont} onChange={(e) => setSelectedFont(e)} />
</div>
</div>
<div className="font-option-item">
<div className="option-item-tit">{getMessage('modal.font.style')}(Y)</div>
<div className="grid-select">
<QSelectBox options={fontOptions} value={selectedFontWeight} onChange={(e) => setSelectedFontWeight(e)} />
</div>
</div>
<div className="font-option-item">
<div className="option-item-tit">{getMessage('modal.font.size')}(S)</div>
<div className="grid-select">
<QSelectBox options={fontSizes} value={selectedFontSize} onChange={(e) => setSelectedFontSize(e)} />
</div>
</div>
<div className="font-option-item">
<div className="option-item-tit">{getMessage('modal.font.color')}</div>
<div className="grid-select">
<QSelectBox title={''} options={fontColors} value={selectedFontColor} onChange={(e) => setSelectedFontColor(e)} />
</div>
</div>
</div>
<div className="font-ex-wrap">
<div className="font-ex-tit">{getMessage('modal.font.setting.display')}</div>
<div className="font-ex-box">
<span
style={{
fontFamily: selectedFont?.value ?? '',
fontSize: selectedFontSize?.value ?? '12px',
fontWeight: '400',
color: selectedFontColor?.value ?? 'black',
}}
>
Aaあぁアァ
</span>
</div>
</div>
<div className="normal-font">{getMessage('modal.font.setting.info')}</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act" onClick={handleSaveBtn}>
{getMessage('modal.common.save')}
</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -31,7 +31,7 @@ export default function QPagination(props) {
<button <button
onClick={() => { onClick={() => {
if (currentPage === totalPages) return if (currentPage === totalPages) return
handlePage(Math.max(1, pageGroup * pagePerBlock + 1)) if (pageGroup * pagePerBlock + 1 <= totalPages) handlePage(Math.max(1, pageGroup * pagePerBlock + 1))
}} }}
></button> ></button>
</li> </li>

View File

@ -0,0 +1,9 @@
'use client'
import { useRecoilState } from 'recoil'
import { popupState } from '@/store/popupAtom'
import { Fragment } from 'react'
export default function PopupManager() {
const [popup, setPopup] = useRecoilState(popupState)
return popup.children?.map((child) => <Fragment key={child.id}>{child.component}</Fragment>)
}

View File

@ -20,7 +20,7 @@ export default function QSelectBox({ title = '', options, onChange, value }) {
<ul className="select-item-wrap"> <ul className="select-item-wrap">
{options?.map((option) => ( {options?.map((option) => (
<li key={option.id} className="select-item" onClick={() => handleClickSelectOption(option)}> <li key={option.id} className="select-item" onClick={() => handleClickSelectOption(option)}>
<button>{option.name}</button> <button key={option.id + 'btn'}>{option.name}</button>
</li> </li>
))} ))}
</ul> </ul>

View File

@ -61,7 +61,7 @@ export default function Archive() {
<div className="sub-content"> <div className="sub-content">
<div className="sub-content-inner"> <div className="sub-content-inner">
<div className="sub-table-box"> <div className="sub-table-box">
<Search title={boardType.boardTitle} subTitle={boardType.subTitle} isSelectUse={true} /> <Search title={boardType.boardTitle} subTitle={boardType.subTitle} isSelectUse={false} />
<ArchiveTable clsCode={boardType.clsCode} /> <ArchiveTable clsCode={boardType.clsCode} />
</div> </div>
</div> </div>

View File

@ -45,7 +45,7 @@ export default function ArchiveTable({ clsCode }) {
} }
fetchData() fetchData()
}, [search.searchValue]) }, [search.searchValue, search.searchFlag])
// //
const handleDetailFileListDown = async (noticeNo) => { const handleDetailFileListDown = async (noticeNo) => {
@ -74,30 +74,34 @@ export default function ArchiveTable({ clsCode }) {
return ( return (
<> <>
<div className="file-down-list"> {boardList.length > 0 ? (
{boardList?.map((board) => ( <div className="file-down-list">
<div key={board.noticeNo} className="file-down-item"> {boardList?.map((board) => (
<div className="file-item-info"> <div key={board.noticeNo} className="file-down-item">
<div className="item-num"> <div className="file-item-info">
{/* 번호 */} <div className="item-num">
{board.rowNumber} {/* 번호 */}
{board.rowNumber}
</div>
<div className="item-name">
{/* 제목 */}
{board.title}
</div>
<div className="item-date">
{/* 등록일 */}
{getMessage('board.sub.updDt')} : {board.uptDt ? board.uptDt : board.regDt}
</div>
</div> </div>
<div className="item-name"> <div className="file-down-box">
{/* 제목 */} {/* 첨부파일 */}
{board.title} <button type="button" className="file-down-btn" onClick={() => handleDetailFileListDown(board.noticeNo)}></button>
</div>
<div className="item-date">
{/* 등록일 */}
{getMessage('board.sub.updDt')} : {board.uptDt ? board.uptDt : board.regDt}
</div> </div>
</div> </div>
<div className="file-down-box"> ))}
{/* 첨부파일 */} </div>
<button type="button" className="file-down-btn" onClick={() => handleDetailFileListDown(board.noticeNo)}></button> ) : (
</div> <div className="file-down-nodata">{getMessage('common.message.no.data')}</div>
</div> )}
))}
</div>
</> </>
) )
} }

View File

@ -26,10 +26,9 @@ export const QLine = fabric.util.createClass(fabric.Line, {
}) })
this.idx = options.idx ?? 0 this.idx = options.idx ?? 0
this.direction = options.direction ?? getDirectionByPoint({ x: this.x1, y: this.y1 }, { x: this.x2, y: this.y2 })
this.setLength() this.setLength()
this.direction = options.direction ?? getDirectionByPoint({ x: this.x1, y: this.y1 }, { x: this.x2, y: this.y2 })
this.startPoint = { x: this.x1, y: this.y1 } this.startPoint = { x: this.x1, y: this.y1 }
this.endPoint = { x: this.x2, y: this.y2 } this.endPoint = { x: this.x2, y: this.y2 }
@ -58,11 +57,10 @@ export const QLine = fabric.util.createClass(fabric.Line, {
}) })
this.on('removed', () => { this.on('removed', () => {
const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id) const children = this.canvas.getObjects().filter((obj) => obj.parentId === this.id)
if (thisText) { children.forEach((child) => {
this.canvas.remove(thisText) this.canvas.remove(child)
} })
this.text = null
}) })
}, },

View File

@ -2,7 +2,7 @@ import { fabric } from 'fabric'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { QLine } from '@/components/fabric/QLine' import { QLine } from '@/components/fabric/QLine'
import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util' import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util'
import { calculateAngle, drawRidgeRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils' import { calculateAngle, drawRidgeRoof, drawHippedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils'
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import { LINE_TYPE } from '@/common/common' import { LINE_TYPE } from '@/common/common'
@ -131,13 +131,9 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
this.on('modified', (e) => { this.on('modified', (e) => {
this.addLengthText() this.addLengthText()
// if (this.arrow) {
// drawDirectionArrow(this)
// }
}) })
this.on('selected', () => { this.on('selected', () => {
// drawDirectionArrow(this)
Object.keys(this.controls).forEach((controlKey) => { Object.keys(this.controls).forEach((controlKey) => {
if (controlKey !== 'ml' && controlKey !== 'mr') { if (controlKey !== 'ml' && controlKey !== 'mr') {
this.setControlVisible(controlKey, false) this.setControlVisible(controlKey, false)
@ -146,22 +142,10 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
}) })
this.on('removed', () => { this.on('removed', () => {
const thisText = this.canvas.getObjects().filter((obj) => obj.name === 'lengthText' && obj.parentId === this.id) const children = this.canvas.getObjects().filter((obj) => obj.parentId === this.id)
thisText.forEach((text) => { children.forEach((child) => {
this.canvas.remove(text) this.canvas.remove(child)
}) })
this.texts = null
if (this.arrow) {
this.canvas.remove(this.arrow)
this.canvas
.getObjects()
.filter((obj) => obj.name === 'directionText' && obj.parent === this.arrow)
.forEach((text) => {
this.canvas.remove(text)
})
this.arrow = null
}
}) })
// polygon.fillCell({ width: 50, height: 30, padding: 10 }) // polygon.fillCell({ width: 50, height: 30, padding: 10 })
@ -246,23 +230,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
let midPoint let midPoint
switch (this.direction) { midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
case 'north':
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2 - 30)
break
case 'west':
midPoint = new fabric.Point((start.x + end.x) / 2 - 30, (start.y + end.y) / 2)
break
case 'south':
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2 + 30)
break
case 'east':
midPoint = new fabric.Point((start.x + end.x) / 2 + 30, (start.y + end.y) / 2)
break
default:
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
break
}
const degree = (Math.atan2(dy, dx) * 180) / Math.PI const degree = (Math.atan2(dy, dx) * 180) / Math.PI

View File

@ -4,15 +4,26 @@ import { useEffect, useRef } from 'react'
import { useCanvas } from '@/hooks/useCanvas' import { useCanvas } from '@/hooks/useCanvas'
import { useEvent } from '@/hooks/useEvent' import { useEvent } from '@/hooks/useEvent'
import QContextMenu from '@/components/common/context-menu/QContextMenu' import { usePlan } from '@/hooks/usePlan'
import { useContextMenu } from '@/hooks/useContextMenu' import { useContextMenu } from '@/hooks/useContextMenu'
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { currentObjectState } from '@/store/canvasAtom' import { currentObjectState } from '@/store/canvasAtom'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import QContextMenu from '@/components/common/context-menu/QContextMenu'
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
export default function CanvasFrame({ plan }) { export default function CanvasFrame({ plan }) {
const canvasRef = useRef(null) const canvasRef = useRef(null)
const { canvas } = useCanvas('canvas') const { canvas } = useCanvas('canvas')
const { contextMenu, currentContextMenu, setCurrentContextMenu } = useContextMenu() const { handleZoomClear } = useCanvasEvent()
const { contextMenu, currentContextMenu, setCurrentContextMenu, handleClick } = useContextMenu({
externalFn: {
handleZoomClear,
},
})
const { checkCanvasObjectEvent, checkUnsavedCanvasPlan } = usePlan()
const { canvasLoadInit } = useCanvasConfigInitialize()
const currentObject = useRecoilValue(currentObjectState)
useEvent() useEvent()
@ -22,6 +33,7 @@ export default function CanvasFrame({ plan }) {
if (plan?.canvasStatus) { if (plan?.canvasStatus) {
canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () { canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () {
canvas?.renderAll() // . canvas?.renderAll() // .
canvasLoadInit() //config
}) })
} }
} }
@ -34,18 +46,28 @@ export default function CanvasFrame({ plan }) {
const onClickContextMenu = (index) => {} const onClickContextMenu = (index) => {}
return ( return (
<div className="canvas-frame flex justify-center"> <div className="canvas-frame">
<canvas ref={canvasRef} id={'canvas'}></canvas> <canvas ref={canvasRef} id="canvas" style={{ position: 'relative' }}></canvas>
<QContextMenu contextRef={canvasRef} canvasProps={canvas}> <QContextMenu contextRef={canvasRef} canvasProps={canvas}>
{contextMenu.map((menus, index) => ( {contextMenu.map((menus, index) => (
<ul key={index}> <ul key={index}>
{menus.map((menu) => ( {menus.map((menu) => (
<li onClick={(e) => setCurrentContextMenu(menu)}>{menu.name}</li> <li
key={menu.id}
onClick={(e) => {
if (menu.fn) {
menu.fn()
}
handleClick(e, menu)
}}
>
{menu.name}
</li>
))} ))}
</ul> </ul>
))} ))}
</QContextMenu> </QContextMenu>
{currentContextMenu?.component}
</div> </div>
) )
} }

View File

@ -7,36 +7,36 @@ import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import { usePlan } from '@/hooks/usePlan' import { usePlan } from '@/hooks/usePlan'
import { globalLocaleStore } from '@/store/localeAtom' import { globalLocaleStore } from '@/store/localeAtom'
import { sessionStore } from '@/store/commonAtom'
import { SessionContext } from '@/app/SessionProvider' import { SessionContext } from '@/app/SessionProvider'
export default function CanvasLayout() { export default function CanvasLayout(props) {
const { menuNumber } = props
const { session } = useContext(SessionContext) const { session } = useContext(SessionContext)
console.log('session >>> ', session)
const [objectNo, setObjectNo] = useState('test123240822001') // const [objectNo, setObjectNo] = useState('test123240822001') //
const sessionState = useRecoilValue(sessionStore)
const globalLocaleState = useRecoilValue(globalLocaleStore) const globalLocaleState = useRecoilValue(globalLocaleStore)
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { plans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan() const { plans, modifiedPlans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan()
useEffect(() => { useEffect(() => {
console.log('loadCanvasPlanData 실행, sessionState.userId >>> ', sessionState.userId) loadCanvasPlanData(session.userId, objectNo)
loadCanvasPlanData(sessionState.userId, objectNo)
}, []) }, [])
return ( return (
<div className="canvas-layout"> <div className="canvas-layout">
<div className="canvas-page-list"> <div className={`canvas-page-list ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
<div className="canvas-plane-wrap"> <div className="canvas-plane-wrap">
{plans.map((plan) => ( {plans.map((plan) => (
<button <button
key={`plan-${plan.id}`} key={`plan-${plan.id}`}
className={`canvas-page-box ${plan.isCurrent === true ? 'on' : ''}`} className={`canvas-page-box ${plan.isCurrent === true ? 'on' : ''}`}
onClick={() => handleCurrentPlan(sessionState.userId, plan.id)} onClick={() => handleCurrentPlan(session.userId, plan.id)}
> >
<span>{plan.name}</span> <span>
{plan.name}
{modifiedPlans.some((modifiedPlan) => modifiedPlan === plan.id) && ' [ M ]'}
</span>
<i <i
className="close" className="close"
onClick={(e) => onClick={(e) =>
@ -53,7 +53,7 @@ export default function CanvasLayout() {
))} ))}
</div> </div>
{plans.length < 10 && ( {plans.length < 10 && (
<button className="plane-add" onClick={() => handleAddPlan(sessionState.userId, objectNo)}> <button className="plane-add" onClick={() => handleAddPlan(session.userId, objectNo)}>
<span></span> <span></span>
</button> </button>
)} )}

View File

@ -6,20 +6,27 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import MenuDepth01 from './MenuDepth01' import MenuDepth01 from './MenuDepth01'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { v4 as uuidv4 } from 'uuid'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { usePlan } from '@/hooks/usePlan' import { usePlan } from '@/hooks/usePlan'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import { useEvent } from '@/hooks/useEvent'
import { canvasState, canvasZoomState, currentCanvasPlanState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom' import { canvasState, canvasZoomState, currentCanvasPlanState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom'
import { sessionStore } from '@/store/commonAtom' import { sessionStore } from '@/store/commonAtom'
import { outerLinePointsState } from '@/store/outerLineAtom' import { outerLinePointsState } from '@/store/outerLineAtom'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
import { settingModalFirstOptionsState, wordDisplaySelector } from '@/store/settingAtom'
import { MENU } from '@/common/common' import { MENU } from '@/common/common'
import KO from '@/locales/ko.json' import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json' import JA from '@/locales/ja.json'
import { settingModalFirstOptionsState } from '@/store/settingAtom' import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import { popupState } from '@/store/popupAtom'
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
import { usePopup } from '@/hooks/usePopup'
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
import { useCommonUtils } from '@/hooks/common/useCommonUtils'
const canvasMenus = [ const canvasMenus = [
{ index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING }, { index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING },
@ -32,28 +39,9 @@ const canvasMenus = [
] ]
export default function CanvasMenu(props) { export default function CanvasMenu(props) {
const { const { menuNumber, setMenuNumber } = props
setShowCanvasSettingModal,
showOutlineModal,
setShowOutlineModal,
setShowPlaceShapeModal,
setShowSlopeSettingModal,
setShowPlacementSurfaceSettingModal,
setShowPlaceShapeDrawingModal,
setShowRoofShapeSettingModal,
setShowObjectSettingModal,
setShowRoofShapePassivitySettingModal,
setShowAuxiliaryModal,
setShowEavesGableEditModal,
setShowMovementModal,
setShowWallLineOffsetSettingModal,
setShowRoofAllocationSettingModal,
setShowBasicSettingModal,
setShowCircuitTrestleSettingModal,
setShowPropertiesSettingModal,
} = props
const [menuNumber, setMenuNumber] = useState(null) const { addPopup, closePopup } = usePopup()
const [type, setType] = useState('') const [type, setType] = useState('')
const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState) const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState)
@ -63,6 +51,7 @@ export default function CanvasMenu(props) {
const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState) const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState)
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
const { handleZoomClear } = useCanvasEvent()
const globalLocale = useRecoilValue(globalLocaleStore) const globalLocale = useRecoilValue(globalLocaleStore)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -71,8 +60,23 @@ export default function CanvasMenu(props) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { saveCanvas } = usePlan() const { saveCanvas } = usePlan()
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { initEvent, addCanvasMouseEventListener, addDocumentEventListener } = useEvent()
const [commonFunctionState, setCommonFunctionState] = useState({
text: false,
dimension: false,
distance: false,
})
const { commonFunctions } = useCommonUtils({
commonFunctionState,
setCommonFunctionState,
})
const [popup, setPopup] = useRecoilState(popupState)
const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }]
const onClickNav = (menu) => { const onClickNav = (menu) => {
setMenuNumber(menu.index) setMenuNumber(menu.index)
setCurrentMenu(menu.title) setCurrentMenu(menu.title)
@ -94,22 +98,6 @@ export default function CanvasMenu(props) {
} }
} }
const menuProps = { const menuProps = {
setShowOutlineModal,
setShowPlaceShapeModal,
setShowRoofShapeSettingModal,
setShowRoofShapePassivitySettingModal,
setShowAuxiliaryModal,
setShowEavesGableEditModal,
setShowMovementModal,
setShowSlopeSettingModal,
setShowPlacementSurfaceSettingModal,
setShowPlaceShapeDrawingModal,
setShowWallLineOffsetSettingModal,
setShowRoofAllocationSettingModal,
setShowObjectSettingModal,
setShowBasicSettingModal,
setShowCircuitTrestleSettingModal,
setShowPropertiesSettingModal,
type, type,
} }
@ -119,7 +107,6 @@ export default function CanvasMenu(props) {
if (menuNumber === 1) { if (menuNumber === 1) {
onClickPlacementInitialMenu() onClickPlacementInitialMenu()
} }
if (menuNumber !== 2 && showOutlineModal) setShowOutlineModal(false)
}, [menuNumber, type]) }, [menuNumber, type])
// (btn08) // (btn08)
@ -133,12 +120,17 @@ export default function CanvasMenu(props) {
// }) // })
} }
const [placementInitialId, setPlacementInitialId] = useState(uuidv4())
const placementInitialProps = {
id: placementInitialId,
pos: {
x: 50,
y: 180,
},
}
const onClickPlacementInitialMenu = () => { const onClickPlacementInitialMenu = () => {
setShowOutlineModal(false) addPopup(placementInitialId, 1, <PlacementShapeSetting {...placementInitialProps} />)
setShowCanvasSettingModal(false) // setShowPlaceShapeModal(true)
setShowEavesGableEditModal(false)
setShowMovementModal(false)
setShowPlaceShapeModal(true)
} }
const handleClear = () => { const handleClear = () => {
@ -146,12 +138,17 @@ export default function CanvasMenu(props) {
setPlacementPoints([]) setPlacementPoints([])
canvas?.clear() canvas?.clear()
} }
//
// const handleZoomClear = () => {
// setCanvasZoom(100)
// canvas.set({ zoom: 1 })
// canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
// canvas.renderAll()
// }
const handleZoomClear = () => { const handlePopup = () => {
setCanvasZoom(100) const id = uuidv4()
canvas.set({ zoom: 1 }) addPopup(id, 0, <SettingModal01 id={id} />)
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
canvas.renderAll()
} }
useEffect(() => { useEffect(() => {
@ -191,15 +188,16 @@ export default function CanvasMenu(props) {
</div> </div>
} }
<div className="btn-from"> <div className="btn-from">
<button className="btn01" onClick={() => {}}></button> <button className={`btn01 ${commonFunctionState.text ? 'active' : ''}`} onClick={() => commonFunctions('text')}></button>
<button className="btn02 active"></button> <button className={`btn02 ${commonFunctionState.dimension ? 'active' : ''} `} onClick={() => commonFunctions('dimension')}></button>
<button className="btn03 "></button> <button className={`btn03 ${commonFunctionState.distance ? 'active' : ''} `} onClick={() => commonFunctions('distance')}></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={() => setShowCanvasSettingModal(true)}></button> {/*<button className="btn04" onClick={() => setShowCanvasSettingModal(true)}></button>*/}
<button className="btn04" onClick={handlePopup}></button>
<button className="btn05"></button> <button className="btn05"></button>
<button className="btn06"></button> <button className="btn06"></button>
</div> </div>

View File

@ -5,95 +5,27 @@ import { useRecoilState, useRecoilValue } from 'recoil'
import { useAxios } from '@/hooks/useAxios' import { useAxios } from '@/hooks/useAxios'
import { globalLocaleStore } from '@/store/localeAtom' import { globalLocaleStore } from '@/store/localeAtom'
import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom' import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
import '@/styles/contents.scss'
import CanvasMenu from '@/components/floor-plan/CanvasMenu' import CanvasMenu from '@/components/floor-plan/CanvasMenu'
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
import CanvasLayout from '@/components/floor-plan/CanvasLayout' import CanvasLayout from '@/components/floor-plan/CanvasLayout'
import DotLineGrid from '@/components/floor-plan/modal/grid/DotLineGrid' import '@/styles/contents.scss'
import WallLineSetting from '@/components/floor-plan/modal/outerlinesetting/WallLineSetting'
import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting'
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
import GridColorSetting from './modal/grid/GridColorSetting'
import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
import PlacementShapeDrawing from '@/components/floor-plan/modal/placementShape/PlacementShapeDrawing'
import Slope from '@/components/floor-plan/modal/Slope'
import AuxiliaryDrawing from '@/components/floor-plan/modal/auxiliary/AuxiliaryDrawing'
import EavesGableEdit from '@/components/floor-plan/modal/eavesGable/EavesGableEdit'
import WallLineOffsetSetting from '@/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting'
import ObjectSetting from '@/components/floor-plan/modal/object/ObjectSetting'
import PlacementSurfaceSetting from '@/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting'
import RoofShapePassivitySetting from '@/components/floor-plan/modal/roofShape/RoofShapePassivitySetting'
import MovementSetting from '@/components/floor-plan/modal/movement/MovementSetting'
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
import BasicSetting from '@/components/floor-plan/modal/basic/BasicSetting'
import CircuitTrestleSetting from '@/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting'
export default function FloorPlan() { export default function FloorPlan() {
const [showCanvasSettingModal, setShowCanvasSettingModal] = useState(false)
const [showOutlineModal, setShowOutlineModal] = useState(false)
const [showPlaceShapeModal, setShowPlaceShapeModal] = useState(false)
const [showPropertiesSettingModal, setShowPropertiesSettingModal] = useState(false)
const [showRoofShapeSettingModal, setShowRoofShapeSettingModal] = useState(false)
const [showRoofShapePassivitySettingModal, setShowRoofShapePassivitySettingModal] = useState(false)
const [showAuxiliaryModal, setShowAuxiliaryModal] = useState(false)
const [showSlopeSettingModal, setShowSlopeSettingModal] = useState(false)
const [showPlacementSurfaceSettingModal, setShowPlacementSurfaceSettingModal] = useState(false)
const [showPlaceShapeDrawingModal, setShowPlaceShapeDrawingModal] = useState(false)
const [showObjectSettingModal, setShowObjectSettingModal] = useState(false)
const [showEavesGableEditModal, setShowEavesGableEditModal] = useState(false)
const [showMovementModal, setShowMovementModal] = useState(false)
const [showWallLineOffsetSettingModal, setShowWallLineOffsetSettingModal] = useState(false)
const [showRoofAllocationSettingModal, setShowRoofAllocationSettingModal] = useState(false)
const [showBasicSettingModal, setShowBasicSettingModal] = useState(false)
const [showCircuitTrestleSettingModal, setShowCircuitTrestleSettingModal] = useState(false)
const globalLocaleState = useRecoilValue(globalLocaleStore) const globalLocaleState = useRecoilValue(globalLocaleStore)
const { get } = useAxios(globalLocaleState) const { get } = useAxios(globalLocaleState)
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
const [objectNo, setObjectNo] = useState('test123240912001') // const [objectNo, setObjectNo] = useState('test123240912001') //
const [showDotLineGridModal, setShowDotLineGridModal] = useState(false) const [menuNumber, setMenuNumber] = useState(null)
const [showGridCopyModal, setShowGridCopyModal] = useState(false)
const [showGridMoveModal, setShowGridMoveModal] = useState(false)
const [showColorPickerModal, setShowColorPickerModal] = useState(false)
const canvasSettingProps = {
setShowCanvasSettingModal,
setShowDotLineGridModal,
setShowColorPickerModal,
}
const outlineProps = {
setShowOutlineModal,
setShowPropertiesSettingModal,
}
const modalProps = { const modalProps = {
setShowCanvasSettingModal, menuNumber,
showOutlineModal, setMenuNumber,
setShowOutlineModal,
setShowPlaceShapeModal,
setShowSlopeSettingModal,
setShowPlacementSurfaceSettingModal,
setShowPlaceShapeDrawingModal,
setShowRoofShapeSettingModal,
setShowObjectSettingModal,
setShowRoofShapePassivitySettingModal,
setShowAuxiliaryModal,
setShowEavesGableEditModal,
setShowMovementModal,
setShowWallLineOffsetSettingModal,
setShowRoofAllocationSettingModal,
setShowBasicSettingModal,
setShowCircuitTrestleSettingModal,
setShowPropertiesSettingModal,
} }
useEffect(() => { useEffect(() => {
console.log('FloorPlan useEffect 실행') console.log('FloorPlan useEffect 실행')
fetchSettings() fetchSettings()
}, [showOutlineModal, objectNo]) }, [objectNo])
// Canvas Setting // Canvas Setting
const fetchSettings = async () => { const fetchSettings = async () => {
@ -120,49 +52,13 @@ export default function FloorPlan() {
console.error('Data fetching error:', error) console.error('Data fetching error:', error)
} }
} }
const dotLineProps = {
showDotLineGridModal,
setShowDotLineGridModal,
}
const gridColorProps = {
setShowColorPickerModal,
}
const propertiesSettingProps = {
setShowPropertiesSettingModal,
}
useEffect(() => {}, [showOutlineModal])
return ( return (
<> <>
<div className="canvas-wrap"> <div className="canvas-wrap">
<CanvasMenu {...modalProps} /> <CanvasMenu {...modalProps} />
<div className="canvas-content"> <div className={`canvas-content ${menuNumber === 2 || menuNumber === 3 || menuNumber === 4 ? 'active' : ''}`}>
<CanvasLayout /> <CanvasLayout menuNumber={menuNumber} />
{showCanvasSettingModal && <SettingModal01 {...canvasSettingProps} />}
{showOutlineModal && <WallLineSetting {...outlineProps} />}
{showDotLineGridModal && <DotLineGrid {...dotLineProps} />}
{showColorPickerModal && <GridColorSetting {...gridColorProps} />}
{showPropertiesSettingModal && <PropertiesSetting {...propertiesSettingProps} />}
{showPlaceShapeModal && <PlacementShapeSetting setShowPlaceShapeModal={setShowPlaceShapeModal} />}
{showRoofShapeSettingModal && <RoofShapeSetting setShowRoofShapeSettingModal={setShowRoofShapeSettingModal} />}
{showRoofShapePassivitySettingModal && (
<RoofShapePassivitySetting setShowRoofShapePassivitySettingModal={setShowRoofShapePassivitySettingModal} />
)}
{showAuxiliaryModal && <AuxiliaryDrawing setShowAuxiliaryModal={setShowAuxiliaryModal} />}
{showSlopeSettingModal && <Slope setShowSlopeSettingModal={setShowSlopeSettingModal} />}
{showPlaceShapeDrawingModal && <PlacementShapeDrawing setShowPlaceShapeDrawingModal={setShowPlaceShapeDrawingModal} />}
{showEavesGableEditModal && <EavesGableEdit setShowEavesGableEditModal={setShowEavesGableEditModal} />}
{showMovementModal && <MovementSetting setShowMovementModal={setShowMovementModal} />}
{showRoofAllocationSettingModal && <RoofAllocationSetting setShowRoofAllocationSettingModal={setShowRoofAllocationSettingModal} />}
{showWallLineOffsetSettingModal && <WallLineOffsetSetting setShowWallLineOffsetSettingModal={setShowWallLineOffsetSettingModal} />}
{showObjectSettingModal && <ObjectSetting setShowObjectSettingModal={setShowObjectSettingModal} />}
{showPlacementSurfaceSettingModal && <PlacementSurfaceSetting setShowPlacementSurfaceSettingModal={setShowPlacementSurfaceSettingModal} />}
{showBasicSettingModal && <BasicSetting setShowBasicSettingModal={setShowBasicSettingModal} />}
{showCircuitTrestleSettingModal && <CircuitTrestleSetting setShowCircuitTrestleSettingModal={setShowCircuitTrestleSettingModal} />}
</div> </div>
</div> </div>
</> </>

View File

@ -6,85 +6,92 @@ import { MENU } from '@/common/common'
import { currentMenuState } from '@/store/canvasAtom' import { currentMenuState } from '@/store/canvasAtom'
import { useSetRecoilState } from 'recoil' import { useSetRecoilState } from 'recoil'
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
import { usePopup } from '@/hooks/usePopup'
import { v4 as uuidv4 } from 'uuid'
import WallLineSetting from '@/components/floor-plan/modal/outerlinesetting/WallLineSetting'
import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
import RoofShapePassivitySetting from '@/components/floor-plan/modal/roofShape/RoofShapePassivitySetting'
import AuxiliaryDrawing from '@/components/floor-plan/modal/auxiliary/AuxiliaryDrawing'
import EavesGableEdit from '@/components/floor-plan/modal/eavesGable/EavesGableEdit'
import MovementSetting from '@/components/floor-plan/modal/movement/MovementSetting'
import WallLineOffsetSetting from '@/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting'
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
import Slope from '@/components/floor-plan/modal/Slope'
import ObjectSetting from '@/components/floor-plan/modal/object/ObjectSetting'
import PlacementShapeDrawing from '@/components/floor-plan/modal/placementShape/PlacementShapeDrawing'
import PlacementSurfaceSetting from '@/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting'
import BasicSetting from '@/components/floor-plan/modal/basic/BasicSetting'
import CircuitTrestleSetting from '@/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting'
export default function MenuDepth01(props) { export default function MenuDepth01(props) {
const { const { type } = props
setShowOutlineModal,
type,
setShowPlaceShapeModal,
setShowRoofShapeSettingModal,
setShowRoofShapePassivitySettingModal,
setShowAuxiliaryModal,
setShowEavesGableEditModal,
setShowMovementModal,
setShowSlopeSettingModal,
setShowPlacementSurfaceSettingModal,
setShowPlaceShapeDrawingModal,
setShowWallLineOffsetSettingModal,
setShowRoofAllocationSettingModal,
setShowObjectSettingModal,
setShowBasicSettingModal,
setShowCircuitTrestleSettingModal,
setShowPropertiesSettingModal,
} = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [activeMenu, setActiveMenu] = useState() const [activeMenu, setActiveMenu] = useState()
const setCurrentMenu = useSetRecoilState(currentMenuState) const setCurrentMenu = useSetRecoilState(currentMenuState)
const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch() const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch()
const { addPopup } = usePopup()
const [outlineId, setOutlineId] = useState(uuidv4())
const onClickMenu = ({ id, menu, name }) => { const onClickMenu = ({ id, menu, name }) => {
setActiveMenu(menu) setActiveMenu(menu)
setShowOutlineModal(menu === MENU.ROOF_COVERING.EXTERIOR_WALL_LINE)
setCurrentMenu(menu) setCurrentMenu(menu)
setShowPlaceShapeModal(false)
if (type === 'outline') { if (type === 'outline') {
setShowOutlineModal(id === 0) switch (id) {
setShowRoofShapeSettingModal(id === 1) case 0:
setShowRoofShapePassivitySettingModal(id === 2) addPopup(outlineId, 1, <WallLineSetting id={outlineId} />)
setShowAuxiliaryModal(id === 3) break
setShowEavesGableEditModal(id === 4) case 1:
setShowMovementModal(id === 5) addPopup(outlineId, 1, <RoofShapeSetting id={outlineId} />)
setShowWallLineOffsetSettingModal(id === 6) break
setShowRoofAllocationSettingModal(id === 7) case 2:
setShowPlaceShapeDrawingModal(false) addPopup(outlineId, 1, <RoofShapePassivitySetting id={outlineId} />)
setShowPropertiesSettingModal(false) break
setShowCircuitTrestleSettingModal(false) case 3:
addPopup(outlineId, 1, <AuxiliaryDrawing id={outlineId} />)
break
case 4:
addPopup(outlineId, 1, <EavesGableEdit id={outlineId} />)
break
case 5:
addPopup(outlineId, 1, <MovementSetting id={outlineId} />)
break
case 6:
addPopup(outlineId, 1, <WallLineOffsetSetting id={outlineId} />)
break
case 7:
addPopup(outlineId, 1, <RoofAllocationSetting id={outlineId} />)
break
}
} }
if (type === 'surface') { if (type === 'surface') {
setShowOutlineModal(false) switch (id) {
setShowRoofShapeSettingModal(false) case 0:
setShowRoofShapePassivitySettingModal(false) addPopup(outlineId, 1, <Slope id={outlineId} />)
setShowAuxiliaryModal(false) break
setShowEavesGableEditModal(false) case 1:
setShowMovementModal(false) addPopup(outlineId, 1, <PlacementShapeDrawing id={outlineId} />)
setShowWallLineOffsetSettingModal(false) break
setShowRoofAllocationSettingModal(false) case 2:
setShowPropertiesSettingModal(false) addPopup(outlineId, 1, <PlacementSurfaceSetting id={outlineId} />)
setShowCircuitTrestleSettingModal(false) break
setShowSlopeSettingModal(id === 0) case 3:
setShowPlaceShapeDrawingModal(id === 1) addPopup(outlineId, 1, <ObjectSetting id={outlineId} />)
setShowPlacementSurfaceSettingModal(id === 2) break
setShowObjectSettingModal(id === 3) case 4:
deleteAllSurfacesAndObjects()
// break
if (id === 4) {
deleteAllSurfacesAndObjects()
} }
} }
if (type === 'module') { if (type === 'module') {
setShowOutlineModal(false) switch (id) {
setShowRoofShapeSettingModal(false) case 0:
setShowRoofShapePassivitySettingModal(false) addPopup(outlineId, 1, <BasicSetting id={outlineId} />)
setShowAuxiliaryModal(false) break
setShowEavesGableEditModal(false) case 1:
setShowMovementModal(false) addPopup(outlineId, 1, <CircuitTrestleSetting id={outlineId} />)
setShowWallLineOffsetSettingModal(false) break
setShowRoofAllocationSettingModal(false) }
setShowPropertiesSettingModal(false)
setShowBasicSettingModal(id === 0)
setShowCircuitTrestleSettingModal(id === 1)
} }
} }

View File

@ -3,17 +3,20 @@ import WithDraggable from '@/components/common/draggable/WithDraggable'
import { globalPitchState } from '@/store/canvasAtom' import { globalPitchState } from '@/store/canvasAtom'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { useRef } from 'react' import { useRef } from 'react'
import { usePopup } from '@/hooks/usePopup'
export default function Slope({ setShowSlopeSettingModal }) { export default function Slope({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [globalPitch, setGlobalPitch] = useRecoilState(globalPitchState) const [globalPitch, setGlobalPitch] = useRecoilState(globalPitchState)
const inputRef = useRef() const inputRef = useRef()
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xxxm`}> <div className={`modal-pop-wrap xxxm`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.placement.surface.slope.setting')} </h1> <h1 className="title">{getMessage('plan.menu.placement.surface.slope.setting')} </h1>
<button className="modal-close" onClick={() => setShowSlopeSettingModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>
@ -34,7 +37,7 @@ export default function Slope({ setShowSlopeSettingModal }) {
className="btn-frame modal act" className="btn-frame modal act"
onClick={() => { onClick={() => {
setGlobalPitch(inputRef.current.value) setGlobalPitch(inputRef.current.value)
setShowSlopeSettingModal(false) closePopup(id)
}} }}
> >
{getMessage('modal.common.save')} {getMessage('modal.common.save')}

View File

@ -0,0 +1,55 @@
import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function AuxiliaryCopy(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm`}>
<div className="modal-head">
<h1 className="title">補助線のコピー </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="grid-option-tit">コピーする方向を入力してください</div>
<div className="grid-option-wrap">
<div className="grid-option-box">
<div className="move-form">
<p className="mb5">長さ</p>
<div className="input-move-wrap mb5">
<div className="input-move">
<input type="text" className="input-origin" defaultValue={910} />
</div>
<span>mm</span>
</div>
<div className="input-move-wrap">
<div className="input-move">
<input type="text" className="input-origin" defaultValue={910} />
</div>
<span>mm</span>
</div>
</div>
<div className="direction-move-wrap">
<button className="direction up"></button>
<button className="direction down act"></button>
<button className="direction left"></button>
<button className="direction right"></button>
</div>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -1,4 +1,3 @@
import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle' import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle'
@ -6,12 +5,13 @@ import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch'
import Angle from '@/components/floor-plan/modal/lineTypes/Angle' import Angle from '@/components/floor-plan/modal/lineTypes/Angle'
import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal' import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal'
import { OUTER_LINE_TYPE } from '@/store/outerLineAtom' import { OUTER_LINE_TYPE } from '@/store/outerLineAtom'
import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall'
import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall' import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall'
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing' import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
import { usePopup } from '@/hooks/usePopup'
export default function AuxiliaryDrawing({ setShowAuxiliaryModal }) { export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const types = [ const types = [
{ id: 1, name: getMessage('straight.line'), type: OUTER_LINE_TYPE.OUTER_LINE }, { id: 1, name: getMessage('straight.line'), type: OUTER_LINE_TYPE.OUTER_LINE },
@ -49,7 +49,7 @@ export default function AuxiliaryDrawing({ setShowAuxiliaryModal }) {
handleFix, handleFix,
buttonAct, buttonAct,
setButtonAct, setButtonAct,
} = useAuxiliaryDrawing(setShowAuxiliaryModal) } = useAuxiliaryDrawing(id)
const outerLineProps = { const outerLineProps = {
length1, length1,
@ -123,11 +123,11 @@ export default function AuxiliaryDrawing({ setShowAuxiliaryModal }) {
setType(button.type) setType(button.type)
} }
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap r`}> <div className={`modal-pop-wrap r`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.auxiliary.drawing')}</h1> <h1 className="title">{getMessage('modal.auxiliary.drawing')}</h1>
<button className="modal-close" onClick={() => setShowAuxiliaryModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>
@ -151,8 +151,8 @@ export default function AuxiliaryDrawing({ setShowAuxiliaryModal }) {
<button className="btn-frame modal mr5" onClick={handleRollback}> <button className="btn-frame modal mr5" onClick={handleRollback}>
{getMessage('modal.cover.outline.rollback')} {getMessage('modal.cover.outline.rollback')}
</button> </button>
<button className="btn-frame modal act" onClick={() => handleFix(setShowAuxiliaryModal)}> <button className="btn-frame modal act" onClick={() => handleFix(id)}>
{getMessage('modal.cover.outline.fix')} {getMessage('apply')}
</button> </button>
</div> </div>
</div> </div>

View File

@ -1,14 +1,20 @@
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { usePopup } from '@/hooks/usePopup'
export default function AuxiliaryMove({ setCurrentContextMenu }) { export default function AuxiliaryMove(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
return ( return (
<WithDraggable isShow={true} pos={{ x: 0, y: 150 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm`}> <div className={`modal-pop-wrap xm`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">補助線の移動 </h1> <h1 className="title">補助線の移動 </h1>
<button className="modal-close" onClick={() => setCurrentContextMenu(null)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -1,14 +1,20 @@
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function AuxiliarySize({ setCurrentContextMenu }) { export default function AuxiliarySize(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
return ( return (
<WithDraggable isShow={true} pos={{ x: 0, y: 150 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm`}> <div className={`modal-pop-wrap xm`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">補助線サイズ変更 </h1> <h1 className="title">補助線サイズ変更 </h1>
<button className="modal-close" onClick={() => setCurrentContextMenu(null)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -8,17 +8,19 @@ import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/Pitch
import Placement from '@/components/floor-plan/modal/basic/step/Placement' import Placement from '@/components/floor-plan/modal/basic/step/Placement'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { canvasSettingState } from '@/store/canvasAtom' import { canvasSettingState } from '@/store/canvasAtom'
import { usePopup } from '@/hooks/usePopup'
export default function BasicSetting({ setShowBasicSettingModal }) { export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [tabNum, setTabNum] = useState(1) const [tabNum, setTabNum] = useState(1)
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lx-2`}> <div className={`modal-pop-wrap lx-2`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.module.circuit.setting.default')}</h1> <h1 className="title">{getMessage('plan.menu.module.circuit.setting.default')}</h1>
<button className="modal-close" onClick={() => setShowBasicSettingModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -6,6 +6,19 @@ export default function Orientation({ setTabNum }) {
const [compasDeg, setCompasDeg] = useState(0) const [compasDeg, setCompasDeg] = useState(0)
const [hasAnglePassivity, setHasAnglePassivity] = useState(false) const [hasAnglePassivity, setHasAnglePassivity] = useState(false)
const getDegree = (degree) => {
if (degree % 15 === 0) return degree
let value = Math.floor(degree / 15)
const remain = ((degree / 15) % 1).toFixed(5)
if (remain > 0.4) {
value++
}
return value * 15
}
return ( return (
<> <>
<div className="properties-setting-wrap"> <div className="properties-setting-wrap">
@ -18,7 +31,7 @@ export default function Orientation({ setTabNum }) {
{Array.from({ length: 180 / 15 }).map((dot, index) => ( {Array.from({ length: 180 / 15 }).map((dot, index) => (
<div <div
key={index} key={index}
className={`circle ${compasDeg === 15 * (12 + index) ? 'act' : ''}`} className={`circle ${getDegree(compasDeg) === 15 * (12 + index) ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * (12 + index))} onClick={() => setCompasDeg(15 * (12 + index))}
> >
{index === 0 && <i>180°</i>} {index === 0 && <i>180°</i>}
@ -26,13 +39,13 @@ export default function Orientation({ setTabNum }) {
</div> </div>
))} ))}
{Array.from({ length: 180 / 15 }).map((dot, index) => ( {Array.from({ length: 180 / 15 }).map((dot, index) => (
<div key={index} className={`circle ${compasDeg === 15 * index ? 'act' : ''}`} onClick={() => setCompasDeg(15 * index)}> <div key={index} className={`circle ${getDegree(compasDeg) === 15 * index ? 'act' : ''}`} onClick={() => setCompasDeg(15 * index)}>
{index === 0 && <i>0°</i>} {index === 0 && <i>0°</i>}
{index === 6 && <i>90°</i>} {index === 6 && <i>90°</i>}
</div> </div>
))} ))}
<div className="compas"> <div className="compas">
<div className="compas-arr" style={{ transform: `rotate(${compasDeg}deg)` }}></div> <div className="compas-arr" style={{ transform: `rotate(${getDegree(compasDeg)}deg)` }}></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,9 +4,11 @@ import PowerConditionalSelect from '@/components/floor-plan/modal/circuitTrestle
import CircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation' import CircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation'
import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp' import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
export default function CircuitTrestleSetting({ setShowCircuitTrestleSettingModal }) { export default function CircuitTrestleSetting({ id }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [tabNum, setTabNum] = useState(1) const [tabNum, setTabNum] = useState(1)
const [circuitAllocationType, setCircuitAllocationType] = useState(1) const [circuitAllocationType, setCircuitAllocationType] = useState(1)
const circuitProps = { const circuitProps = {
@ -14,11 +16,11 @@ export default function CircuitTrestleSetting({ setShowCircuitTrestleSettingModa
setCircuitAllocationType, setCircuitAllocationType,
} }
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={{ x: 50, y: 230 }}>
<div className={`modal-pop-wrap lx-2`}> <div className={`modal-pop-wrap lx-2`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.circuit.trestle.setting')} </h1> <h1 className="title">{getMessage('modal.circuit.trestle.setting')} </h1>
<button className="modal-close" onClick={() => setShowCircuitTrestleSettingModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -0,0 +1,74 @@
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { useMessage } from '@/hooks/useMessage'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import QSelectBox from '@/components/common/select/QSelectBox'
export default function DimensionLineSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, setIsShow, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }]
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm`}>
<div className="modal-head">
<h1 className="title">表示の変更 </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="guide">寸法線に表示する数値を入力してください</div>
<div className="mb-box">
<div className="slope-wrap">
<div className="outline-form mb15">
<span className="mr10">既存の長さ</span>
<div className="input-grid mr5">
<input type="text" className="input-origin block" defaultValue={5933} readOnly />
</div>
</div>
<div className="mb-box">
<div className="outline-form">
<span className="mr10">変更の長さ</span>
<div className="input-grid mr5">
<input type="text" className="input-origin block" defaultValue={0} />
</div>
</div>
</div>
<div className="d-check-box pop">
<input type="checkbox" id="ch99" />
<label htmlFor="ch99">コーナーゴールの場合</label>
</div>
</div>
</div>
<div className="slope-wrap">
<div className="warning">傾斜を着せてください</div>
<div className="display-change-wrap">
<div className="outline-form mb15">
<span className="mr10">傾斜</span>
<div className="grid-select mr10">
<QSelectBox title={'0'} option={SelectOption01} />
</div>
<span className="thin">寸法</span>
</div>
<div className="outline-form">
<span className="mr10">傾斜</span>
<div className="grid-select mr10">
<QSelectBox title={'0'} option={SelectOption01} />
</div>
<span className="thin">寸法</span>
</div>
</div>
<div className="warning">傾き設定されている場合入力した数値に傾き計算をした数値が表示されます</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -0,0 +1,67 @@
import WithDraggable from '@/components/common/draggable/withDraggable'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function Distance(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition, distance } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xxxm`}>
<div className="modal-head">
<h1 className="title">距離測定 </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="slope-wrap">
<div className="eaves-keraba-table">
<div className="eaves-keraba-item">
<div className="eaves-keraba-th">2点間距離</div>
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '98px' }}>
<input type="text" className="input-origin block" defaultValue={0} value={distance.diagonal} readOnly />
</div>
<span className="thin">mm</span>
</div>
</div>
</div>
<div className="eaves-keraba-item">
<div className="eaves-keraba-th">水平距離</div>
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '98px' }}>
<input type="text" className="input-origin block" defaultValue={0} value={distance.horizon} readOnly />
</div>
<span className="thin">mm</span>
</div>
</div>
</div>
<div className="eaves-keraba-item">
<div className="eaves-keraba-th">垂直距離</div>
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '98px' }}>
<input type="text" className="input-origin block" defaultValue={0} value={distance.vertical} readOnly />
</div>
<span className="thin">mm</span>
</div>
</div>
</div>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">確認</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -1,16 +1,17 @@
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useState } from 'react'
import Eaves from '@/components/floor-plan/modal/eavesGable/type/Eaves' import Eaves from '@/components/floor-plan/modal/eavesGable/type/Eaves'
import Gable from '@/components/floor-plan/modal/eavesGable/type/Gable' import Gable from '@/components/floor-plan/modal/eavesGable/type/Gable'
import WallMerge from '@/components/floor-plan/modal/eavesGable/type/WallMerge' import WallMerge from '@/components/floor-plan/modal/eavesGable/type/WallMerge'
import Shed from '@/components/floor-plan/modal/eavesGable/type/Shed' import Shed from '@/components/floor-plan/modal/eavesGable/type/Shed'
import { useEavesGableEdit } from '@/hooks/roofcover/useEavesGableEdit' import { useEavesGableEdit } from '@/hooks/roofcover/useEavesGableEdit'
import { usePopup } from '@/hooks/usePopup'
export default function EavesGableEdit({ setShowEavesGableEditModal }) { export default function EavesGableEdit({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const { type, setType, buttonMenu, TYPES, pitchRef, offsetRef, widthRef, radioTypeRef } = useEavesGableEdit(setShowEavesGableEditModal) const { type, setType, buttonMenu, TYPES, pitchRef, offsetRef, widthRef, radioTypeRef } = useEavesGableEdit(id)
const eavesProps = { const eavesProps = {
pitchRef, pitchRef,
offsetRef, offsetRef,
@ -35,11 +36,11 @@ export default function EavesGableEdit({ setShowEavesGableEditModal }) {
} }
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap r`}> <div className={`modal-pop-wrap r`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.eaves.gable.edit')}</h1> <h1 className="title">{getMessage('modal.eaves.gable.edit')}</h1>
<button className="modal-close" onClick={() => setShowEavesGableEditModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -0,0 +1,150 @@
import WithDraggable from '@/components/common/draggable/withDraggable'
import { useState } from 'react'
import QSelectBox from '@/components/common/select/QSelectBox'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
const SelectOption01 = [{ name: 'M' }, { name: 'M' }, { name: 'M' }, { name: 'M' }]
export default function FlowDirectionSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [compasDeg, setCompasDeg] = useState(0)
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lx`}>
<div className="modal-head">
<h1 className="title">面フローの設定 </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="drawing-flow-wrap">
<div className="discrimination-box">
<div className="discrimination-tit mb15">流れ方向の設定</div>
<div className="guide">流れ方向を選択してください</div>
<div className="object-direction-wrap">
<div className="plane-direction">
<span className="top"></span>
<span className="right">ドン</span>
<span className="bottom"></span>
<span className="left">立つ</span>
<button className="plane-btn up"></button>
<button className="plane-btn right"></button>
<button className="plane-btn down act"></button>
<button className="plane-btn left"></button>
</div>
</div>
</div>
<div className="discrimination-box">
<div className="discrimination-tit mb15">方位設定</div>
<div className="guide">シミュレーション計算の方向を指定します面が向いている方位を選択してください</div>
<div className="mb-box">
<div className="d-check-radio pop mb15">
<input type="radio" name="radio01" id="ra01" />
<label htmlFor="ra01">8方位に選ぶ</label>
</div>
<div className="grid-select ">
<QSelectBox title={'M'} options={SelectOption01} />
</div>
</div>
<div className="mb-box">
<div className="d-check-radio pop">
<input type="radio" name="radio02" id="ra02" />
<label htmlFor="ra02">24方位から選択する (表記は8方位です)</label>
</div>
</div>
<div className="compas-box">
<div className="compas-box-inner">
<div className={`circle ${compasDeg === 180 ? 'act' : ''}`} onClick={() => setCompasDeg(180)}>
<i>13</i>
</div>
<div className={`circle ${compasDeg === 195 ? 'act' : ''}`} onClick={() => setCompasDeg(195)}>
<i>12</i>
</div>
<div className={`circle ${compasDeg === 210 ? 'act' : ''}`} onClick={() => setCompasDeg(210)}>
<i>11</i>
</div>
<div className={`circle ${compasDeg === 225 ? 'act' : ''}`} onClick={() => setCompasDeg(225)}>
<i>10</i>
</div>
<div className={`circle ${compasDeg === 240 ? 'act' : ''}`} onClick={() => setCompasDeg(240)}>
<i>9</i>
</div>
<div className={`circle ${compasDeg === 255 ? 'act' : ''}`} onClick={() => setCompasDeg(255)}>
<i>8</i>
</div>
<div className={`circle ${compasDeg === 270 ? 'act' : ''}`} onClick={() => setCompasDeg(270)}>
<i>7</i>
</div>
<div className={`circle ${compasDeg === 285 ? 'act' : ''}`} onClick={() => setCompasDeg(285)}>
<i>6</i>
</div>
<div className={`circle ${compasDeg === 300 ? 'act' : ''}`} onClick={() => setCompasDeg(300)}>
<i>5</i>
</div>
<div className={`circle ${compasDeg === 315 ? 'act' : ''}`} onClick={() => setCompasDeg(315)}>
<i>4</i>
</div>
<div className={`circle ${compasDeg === 330 ? 'act' : ''}`} onClick={() => setCompasDeg(330)}>
<i>3</i>
</div>
<div className={`circle ${compasDeg === 345 ? 'act' : ''}`} onClick={() => setCompasDeg(345)}>
<i>2</i>
</div>
<div className={`circle ${compasDeg === 0 ? 'act' : ''}`} onClick={() => setCompasDeg(0)}>
<i>1</i>
</div>
<div className={`circle ${compasDeg === 15 ? 'act' : ''}`} onClick={() => setCompasDeg(15)}>
<i>24</i>
</div>
<div className={`circle ${compasDeg === 30 ? 'act' : ''}`} onClick={() => setCompasDeg(30)}>
<i>23</i>
</div>
<div className={`circle ${compasDeg === 45 ? 'act' : ''}`} onClick={() => setCompasDeg(45)}>
<i>22</i>
</div>
<div className={`circle ${compasDeg === 60 ? 'act' : ''}`} onClick={() => setCompasDeg(60)}>
<i>21</i>
</div>
<div className={`circle ${compasDeg === 75 ? 'act' : ''}`} onClick={() => setCompasDeg(75)}>
<i>20</i>
</div>
<div className={`circle ${compasDeg === 90 ? 'act' : ''}`} onClick={() => setCompasDeg(90)}>
<i>19</i>
</div>
<div className={`circle ${compasDeg === 105 ? 'act' : ''}`} onClick={() => setCompasDeg(105)}>
<i>18</i>
</div>
<div className={`circle ${compasDeg === 120 ? 'act' : ''}`} onClick={() => setCompasDeg(120)}>
<i>17</i>
</div>
<div className={`circle ${compasDeg === 135 ? 'act' : ''}`} onClick={() => setCompasDeg(135)}>
<i>16</i>
</div>
<div className={`circle ${compasDeg === 150 ? 'act' : ''}`} onClick={() => setCompasDeg(150)}>
<i>15</i>
</div>
<div className={`circle ${compasDeg === 165 ? 'act' : ''}`} onClick={() => setCompasDeg(165)}>
<i>14</i>
</div>
<div className="compas">
<div className="compas-arr" style={{ transform: `rotate(${compasDeg}deg)` }}></div>
</div>
</div>
</div>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -7,31 +7,48 @@ import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState
import { onlyNumberInputChange } from '@/util/input-utils' import { onlyNumberInputChange } from '@/util/input-utils'
import { fabric } from 'fabric' import { fabric } from 'fabric'
import { gridColorState } from '@/store/gridAtom' import { gridColorState } from '@/store/gridAtom'
import { settingModalGridOptionsState } from '@/store/settingAtom' import { gridDisplaySelector, settingModalGridOptionsState } from '@/store/settingAtom'
import { useAxios } from '@/hooks/useAxios' import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import { usePopup } from '@/hooks/usePopup'
const TYPE = { const TYPE = {
DOT: 'DOT', DOT: 'DOT',
LINE: 'LINE', LINE: 'LINE',
} }
const defaultDotLineGridSetting = {
INTERVAL: {
type: 2, // 1: , , 2:
ratioInterval: 910,
verticalInterval: 910,
horizontalInterval: 910,
dimension: 1, //
},
DOT: false,
LINE: false,
}
export default function DotLineGrid(props) { export default function DotLineGrid(props) {
// const [modalOption, setModalOption] = useRecoilState(modalState); //modal state // const [modalOption, setModalOption] = useRecoilState(modalState); //modal state
const [objectNo, setObjectNo] = useState('test123240912001') // const [objectNo, setObjectNo] = useState('test123240912001') //
const [close, setClose] = useState(false) const [close, setClose] = useState(false)
const { setShowDotLineGridModal } = props const { id, setIsShow, pos = { x: 840, y: -815 } } = props
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
const gridColor = useRecoilValue(gridColorState)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState) const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState)
const [currentSetting, setCurrentSetting] = useState(
JSON.stringify(dotLineGridSetting) === JSON.stringify(defaultDotLineGridSetting) ? { ...defaultDotLineGridSetting } : { ...dotLineGridSetting },
)
const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState) const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState)
const interval = useRecoilValue(dotLineIntervalSelector) const interval = useRecoilValue(dotLineIntervalSelector)
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { get, post } = useAxios() const { get, post } = useAxios()
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { closePopup } = usePopup()
useEffect(() => { useEffect(() => {
return () => { return () => {
@ -54,7 +71,7 @@ export default function DotLineGrid(props) {
// //
useEffect(() => { useEffect(() => {
console.log('DotLineGrid useEffect 실행') console.log('DotLineGrid useEffect 실행')
fetchGridSettings() // fetchGridSettings()
}, [objectNo]) }, [objectNo])
const HandleClickClose = () => { const HandleClickClose = () => {
@ -67,7 +84,7 @@ export default function DotLineGrid(props) {
const handleCheckBoxChange = (e) => { const handleCheckBoxChange = (e) => {
const { value, checked } = e.target const { value, checked } = e.target
setDotLineGridSettingState((prev) => { setCurrentSetting((prev) => {
return { return {
...prev, ...prev,
[value]: checked, [value]: checked,
@ -98,150 +115,34 @@ export default function DotLineGrid(props) {
setSelectOption(matchedOption) setSelectOption(matchedOption)
// //
setDotLineGridSettingState(patternData) setCurrentSetting(patternData)
} catch (error) { } catch (error) {
console.error('Data fetching error:', error) console.error('Data fetching error:', error)
} }
} }
const handleSave = async () => { const handleSave = async () => {
if (!currentSetting.DOT && !currentSetting.LINE) {
swalFire({ text: '배치할 그리드를 설정해주세요.' })
return
}
try { try {
const patternData = { const patternData = {
objectNo, objectNo,
dotGridDisplay: dotLineGridSetting.DOT, dotGridDisplay: currentSetting.DOT,
lineGridDisplay: dotLineGridSetting.LINE, lineGridDisplay: currentSetting.LINE,
gridType: dotLineGridSetting.INTERVAL.type, gridType: currentSetting.INTERVAL.type,
gridHorizon: dotLineGridSetting.INTERVAL.horizontalInterval, gridHorizon: currentSetting.INTERVAL.horizontalInterval / 10,
gridVertical: dotLineGridSetting.INTERVAL.verticalInterval, gridVertical: currentSetting.INTERVAL.verticalInterval / 10,
gridRatio: dotLineGridSetting.INTERVAL.ratioInterval, gridRatio: currentSetting.INTERVAL.ratioInterval / 10,
gridDimen: dotLineGridSetting.INTERVAL.dimension, gridDimen: currentSetting.INTERVAL.dimension,
} }
// HTTP POST // HTTP POST
await post({ url: `/api/canvas-management/canvas-grid-settings`, data: patternData }).then((res) => { await post({ url: `/api/canvas-management/canvas-grid-settings`, data: patternData }).then((res) => {
swalFire({ text: getMessage(res.returnMessage) }) swalFire({ text: getMessage(res.returnMessage) })
setDotLineGridSettingState({ ...currentSetting })
// 1. . closePopup(id)
canvas
?.getObjects()
.filter((obj) => obj.name === 'lineGrid')
.forEach((obj) => canvas?.remove(obj))
canvas
?.getObjects()
.filter((obj) => obj.name === 'dotGrid')
.forEach((obj) => canvas?.remove(obj))
//const horizontalInterval = interval.horizontalInterval
//const verticalInterval = interval.verticalInterval
if (patternData.dotGridDisplay) {
const circle = new fabric.Circle({
radius: 2,
fill: 'red',
strokeWidth: 0.7,
originX: 'center',
originY: 'center',
selectable: false,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
})
const patternSourceCanvas = new fabric.StaticCanvas(null, {
width: patternData.gridHorizon,
height: patternData.gridVertical,
})
patternSourceCanvas.add(circle)
circle.set({
left: patternSourceCanvas.width / 2,
top: patternSourceCanvas.height / 2,
})
patternSourceCanvas.renderAll()
const pattern = new fabric.Pattern({
source: patternSourceCanvas.getElement(),
repeat: 'repeat',
})
const backgroundPolygon = new fabric.Polygon(
[
{ x: 0, y: 0 },
{ x: canvas.width, y: 0 },
{ x: canvas.width, y: canvas.height },
{ x: 0, y: canvas.height },
],
{
fill: pattern,
selectable: false,
name: 'dotGrid',
},
)
canvas.add(backgroundPolygon)
backgroundPolygon.sendToBack()
canvas.renderAll()
}
if (patternData.lineGridDisplay) {
for (let i = 0; i < canvas.height / patternData.gridVertical + 1; i++) {
const horizontalLine = new fabric.Line(
[
0,
i * patternData.gridVertical - patternData.gridVertical / 2,
canvas.width,
i * patternData.gridVertical - patternData.gridVertical / 2,
],
{
stroke: gridColor,
strokeWidth: 1,
selectable: true,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
name: 'lineGrid',
strokeDashArray: [5, 2],
opacity: 0.3,
direction: 'horizontal',
},
)
canvas.add(horizontalLine)
}
for (let i = 0; i < canvas.width / patternData.gridHorizon + 1; i++) {
const verticalLine = new fabric.Line(
[
i * patternData.gridHorizon - patternData.gridHorizon / 2,
0,
i * patternData.gridHorizon - patternData.gridHorizon / 2,
canvas.height,
],
{
stroke: gridColor,
strokeWidth: 1,
selectable: true,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
name: 'lineGrid',
strokeDashArray: [5, 2],
opacity: 0.3,
direction: 'vertical',
},
)
canvas.add(verticalLine)
}
}
canvas.renderAll()
}) })
} catch (error) { } catch (error) {
swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
@ -251,7 +152,7 @@ export default function DotLineGrid(props) {
const handleRadioChange = (e) => { const handleRadioChange = (e) => {
const { value, name, checked, selected } = e.target const { value, name, checked, selected } = e.target
setDotLineGridSettingState((prev) => { setCurrentSetting((prev) => {
return { return {
...prev, ...prev,
INTERVAL: { INTERVAL: {
@ -264,7 +165,7 @@ export default function DotLineGrid(props) {
const changeInput = (value, e) => { const changeInput = (value, e) => {
const { name } = e.target const { name } = e.target
setDotLineGridSettingState((prev) => { setCurrentSetting((prev) => {
return { return {
...prev, ...prev,
INTERVAL: { INTERVAL: {
@ -277,7 +178,7 @@ export default function DotLineGrid(props) {
const changeDimension = (result) => { const changeDimension = (result) => {
const { value } = result const { value } = result
setDotLineGridSettingState((prev) => { setCurrentSetting((prev) => {
return { return {
...prev, ...prev,
INTERVAL: { INTERVAL: {
@ -298,27 +199,34 @@ export default function DotLineGrid(props) {
?.getObjects() ?.getObjects()
.filter((obj) => obj.name === 'dotGrid') .filter((obj) => obj.name === 'dotGrid')
.forEach((obj) => canvas?.remove(obj)) .forEach((obj) => canvas?.remove(obj))
resetDotLineGridSetting() resetDotLineGridSetting()
setSelectOption(SelectOption[0]) setSelectOption(SelectOption[0])
} }
return ( return (
<WithDraggable isShow={true} pos={{ x: 1300, y: -660 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap ssm mount`}> <div className={`modal-pop-wrap ssm mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.canvas.setting.grid.dot.line.setting')}</h1> <h1 className="title">{getMessage('modal.canvas.setting.grid.dot.line.setting')}</h1>
<button className="modal-close" onClick={() => setShowDotLineGridModal(false)}> <button
className="modal-close"
onClick={() => {
setIsShow(false)
closePopup(id)
}}
>
닫기 닫기
</button> </button>
</div> </div>
<div className="modal-body"> <div className="modal-body">
<div className="grid-check-form"> <div className="grid-check-form">
<div className="d-check-box pop"> <div className="d-check-box pop">
<input type="checkbox" id="ch01" value={TYPE.DOT} onChange={handleCheckBoxChange} checked={dotLineGridSetting.DOT} /> <input type="checkbox" id="ch01" value={TYPE.DOT} onChange={handleCheckBoxChange} checked={currentSetting.DOT} />
<label htmlFor="ch01">{getMessage('modal.canvas.setting.grid.dot.line.setting.dot.display')}</label> <label htmlFor="ch01">{getMessage('modal.canvas.setting.grid.dot.line.setting.dot.display')}</label>
</div> </div>
<div className="d-check-box pop"> <div className="d-check-box pop">
<input type="checkbox" id="ch02" value={TYPE.LINE} onChange={handleCheckBoxChange} checked={dotLineGridSetting.LINE} /> <input type="checkbox" id="ch02" value={TYPE.LINE} onChange={handleCheckBoxChange} checked={currentSetting.LINE} />
<label htmlFor="ch02">{getMessage('modal.canvas.setting.grid.dot.line.setting.line.display')}</label> <label htmlFor="ch02">{getMessage('modal.canvas.setting.grid.dot.line.setting.line.display')}</label>
</div> </div>
</div> </div>
@ -331,7 +239,8 @@ export default function DotLineGrid(props) {
id="ra01" id="ra01"
value={1} value={1}
onChange={handleRadioChange} onChange={handleRadioChange}
checked={dotLineGridSetting.INTERVAL.type === 1} checked={(currentSetting.DOT || currentSetting.LINE) && currentSetting.INTERVAL.type === 1}
readOnly={!currentSetting.DOT && !currentSetting.LINE}
/> />
<label htmlFor="ra01"></label> <label htmlFor="ra01"></label>
</div> </div>
@ -342,7 +251,7 @@ export default function DotLineGrid(props) {
type="text" type="text"
className="input-origin" className="input-origin"
name={`horizontalInterval`} name={`horizontalInterval`}
value={dotLineGridSetting.INTERVAL.horizontalInterval} value={currentSetting.INTERVAL.horizontalInterval}
onChange={(e) => onlyNumberInputChange(e, changeInput)} onChange={(e) => onlyNumberInputChange(e, changeInput)}
/> />
</div> </div>
@ -355,7 +264,7 @@ export default function DotLineGrid(props) {
type="text" type="text"
className="input-origin" className="input-origin"
name={`verticalInterval`} name={`verticalInterval`}
value={dotLineGridSetting.INTERVAL.verticalInterval} value={currentSetting.INTERVAL.verticalInterval}
onChange={(e) => onlyNumberInputChange(e, changeInput)} onChange={(e) => onlyNumberInputChange(e, changeInput)}
/> />
</div> </div>
@ -370,7 +279,8 @@ export default function DotLineGrid(props) {
id="ra02" id="ra02"
value={2} value={2}
onChange={handleRadioChange} onChange={handleRadioChange}
checked={dotLineGridSetting.INTERVAL.type === 2} checked={(currentSetting.DOT || currentSetting.LINE) && currentSetting.INTERVAL.type === 2}
readOnly={!currentSetting.DOT && !currentSetting.LINE}
/> />
<label htmlFor="ra02"></label> <label htmlFor="ra02"></label>
</div> </div>
@ -381,7 +291,7 @@ export default function DotLineGrid(props) {
type="text" type="text"
className="input-origin" className="input-origin"
name={`ratioInterval`} name={`ratioInterval`}
value={dotLineGridSetting.INTERVAL.ratioInterval} value={currentSetting.INTERVAL.ratioInterval}
onChange={(e) => onlyNumberInputChange(e, changeInput)} onChange={(e) => onlyNumberInputChange(e, changeInput)}
/> />
</div> </div>

View File

@ -1,39 +0,0 @@
import WithDraggable from '@/components/common/draggable/WithDraggable'
import ColorPicker from '@/components/common/color-picker/ColorPicker'
import { useRecoilState, useSetRecoilState } from 'recoil'
import { gridColorState } from '@/store/gridAtom'
import { useMessage } from '@/hooks/useMessage'
import { useEffect } from 'react'
import { settingModalGridOptionsState } from '@/store/settingAtom'
export default function GridColorSetting(props) {
const { setShowColorPickerModal } = props
const [color, setColor] = useRecoilState(gridColorState)
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
const { getMessage } = useMessage()
useEffect(() => {
return () => {
setSettingModalGridOptions((prev) => {
const newSettingOptions = [...prev]
newSettingOptions[3].selected = false
return [...newSettingOptions]
})
}
}, [])
return (
<WithDraggable isShow={true} pos={{ x: 1300, y: -660 }}>
<div className={`modal-pop-wrap ssm mount`}>
<div className="modal-head">
<h1 className="title">{getMessage('modal.canvas.setting.grid.color.setting')}</h1>
<button className="modal-close" onClick={() => setShowColorPickerModal(false)}>
닫기
</button>
</div>
<div className="modal-body">
<ColorPicker color={color} setColor={setColor} />
</div>
</div>
</WithDraggable>
)
}

View File

@ -1,16 +1,21 @@
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function GridCopy(props) { export default function GridCopy(props) {
const { setShowGridMoveModal, setShowGridCopyModal } = props const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: 380 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm mount`}> <div className={`modal-pop-wrap xm mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.grid.copy')} </h1> <h1 className="title">{getMessage('modal.grid.copy')} </h1>
<button className="modal-close" onClick={() => setShowGridCopyModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -1,16 +1,21 @@
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function GridMove(props) { export default function GridMove(props) {
const { setShowGridMoveModal, setShowGridCopyModal } = props const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: 30 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm mount`}> <div className={`modal-pop-wrap xm mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.grid.move')} </h1> <h1 className="title">{getMessage('modal.grid.move')} </h1>
<button className="modal-close" onClick={() => setShowGridMoveModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -0,0 +1,104 @@
import WithDraggable from '@/components/common/draggable/withDraggable'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
export default function LinePropertySetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap r`}>
<div className="modal-head">
<h1 className="title">各辺属性の変更 </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="guide">
<span className="mb10">属性を変更する辺を選択してください</span>
<span>選択した値 [龍丸]</span>
</div>
<div className="properties-setting-wrap outer">
<div className="setting-tit">設定</div>
<div className="outline-wrap">
<div className="radio-grid-wrap">
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra01" />
<label htmlFor="ra01">軒先</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra02" />
<label htmlFor="ra02">ケラバ</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra03" />
<label htmlFor="ra03">龍丸</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra04" />
<label htmlFor="ra04">ケラバ左</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra05" />
<label htmlFor="ra05">ヨセムネ</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra06" />
<label htmlFor="ra06">ケラバ右</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra07" />
<label htmlFor="ra07">片側の流れ</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra08" />
<label htmlFor="ra08"></label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra09" />
<label htmlFor="ra09">壁取り</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra10" />
<label htmlFor="ra10">Lの捨て渓谷</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra11" />
<label htmlFor="ra11">壁取り()</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra12" />
<label htmlFor="ra12">マンサード</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra13" />
<label htmlFor="ra13">壁取合(流れ)</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra14" />
<label htmlFor="ra14">設定なし</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra15" />
<label htmlFor="ra15">壁取合(流れ左)</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra16" />
<label htmlFor="ra16">壁取り(流れ右)</label>
</div>
</div>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -3,9 +3,11 @@ import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useState } from 'react' import { useState } from 'react'
import FlowLine from '@/components/floor-plan/modal/movement/type/FlowLine' import FlowLine from '@/components/floor-plan/modal/movement/type/FlowLine'
import Updown from '@/components/floor-plan/modal/movement/type/Updown' import Updown from '@/components/floor-plan/modal/movement/type/Updown'
import { usePopup } from '@/hooks/usePopup'
export default function MovementSetting({ setShowMovementModal }) { export default function MovementSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [buttonAct, setButtonAct] = useState(1) const [buttonAct, setButtonAct] = useState(1)
const buttonMenu = [ const buttonMenu = [
{ id: 1, name: getMessage('modal.movement.flow.line.move') }, { id: 1, name: getMessage('modal.movement.flow.line.move') },
@ -13,11 +15,11 @@ export default function MovementSetting({ setShowMovementModal }) {
] ]
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap r`}> <div className={`modal-pop-wrap r`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.roof.cover.movement.shape.updown')}</h1> <h1 className="title">{getMessage('plan.menu.roof.cover.movement.shape.updown')}</h1>
<button className="modal-close" onClick={() => setShowMovementModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -0,0 +1,55 @@
import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { usePopup } from '@/hooks/usePopup'
export default function DormerOffset(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm`}>
<div className="modal-head">
<h1 className="title">도머 오프셋 </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="grid-option-tit">移動する方向を入力してください</div>
<div className="grid-option-wrap">
<div className="grid-option-box">
<div className="move-form">
<p className="mb5">長さ</p>
<div className="input-move-wrap mb5">
<div className="input-move">
<input type="text" className="input-origin" defaultValue={910} />
</div>
<span>mm</span>
</div>
<div className="input-move-wrap">
<div className="input-move">
<input type="text" className="input-origin" defaultValue={910} />
</div>
<span>mm</span>
</div>
</div>
<div className="direction-move-wrap">
<button className="direction up"></button>
<button className="direction down act"></button>
<button className="direction left"></button>
<button className="direction right"></button>
</div>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -1,9 +1,8 @@
'use client' 'use client'
import { useState, useRef, useEffect } from 'react' import { useEffect, useRef, useState } from 'react'
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useEvent } from '@/hooks/useEvent'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import { useObjectBatch } from '@/hooks/object/useObjectBatch' import { useObjectBatch } from '@/hooks/object/useObjectBatch'
@ -13,13 +12,15 @@ import OpenSpace from '@/components/floor-plan/modal/object/type/OpenSpace'
import Shadow from '@/components/floor-plan/modal/object/type/Shadow' import Shadow from '@/components/floor-plan/modal/object/type/Shadow'
import TriangleDormer from '@/components/floor-plan/modal/object/type/TriangleDormer' import TriangleDormer from '@/components/floor-plan/modal/object/type/TriangleDormer'
import PentagonDormer from '@/components/floor-plan/modal/object/type/PentagonDormer' import PentagonDormer from '@/components/floor-plan/modal/object/type/PentagonDormer'
import { usePopup } from '@/hooks/usePopup'
export default function ObjectSetting({ setShowObjectSettingModal }) { export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const [buttonAct, setButtonAct] = useState(1) const [buttonAct, setButtonAct] = useState(1)
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { applyOpeningAndShadow, applyDormers } = useObjectBatch() const { applyOpeningAndShadow, applyDormers } = useObjectBatch()
const { closePopup } = usePopup()
const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
@ -46,19 +47,17 @@ export default function ObjectSetting({ setShowObjectSettingModal }) {
heightRef: useRef(null), heightRef: useRef(null),
pitchRef: useRef(null), pitchRef: useRef(null),
offsetRef: useRef(null), offsetRef: useRef(null),
offsetWidthRef: useRef(null),
directionRef: useRef(null), directionRef: useRef(null),
} }
const applyObject = () => { const applyObject = () => {
// if (surfaceShapePolygons.length === 0) { if (surfaceShapePolygons.length === 0) {
// swalFire({ text: ' ', icon: 'error' }) swalFire({ text: '지붕이 없어요 지붕부터 그리세요', icon: 'error' })
// return return
// } }
//, //,
console.log(surfaceShapePolygons)
if (buttonAct === 1 || buttonAct === 2) { if (buttonAct === 1 || buttonAct === 2) {
applyOpeningAndShadow(objectPlacement, buttonAct, surfaceShapePolygons) applyOpeningAndShadow(objectPlacement, buttonAct, surfaceShapePolygons)
} else { } else {
@ -73,11 +72,11 @@ export default function ObjectSetting({ setShowObjectSettingModal }) {
{ id: 4, name: getMessage('modal.object.setting.type.pentagon.dormer') }, { id: 4, name: getMessage('modal.object.setting.type.pentagon.dormer') },
] ]
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lrr`}> <div className={`modal-pop-wrap lrr`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.placement.surface.object')} </h1> <h1 className="title">{getMessage('plan.menu.placement.surface.object')} </h1>
<button className="modal-close" onClick={() => setShowObjectSettingModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -0,0 +1,45 @@
'use client'
import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { contextPopupPositionState } from '@/store/popupAtom'
import QSelectBox from '@/components/common/select/QSelectBox'
export default function RoofMaterialSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const roofMaterials = [
{ name: '기와1', value: 'material1' },
{ name: '기와2', value: 'material2' },
{ name: '기와3', value: 'material3' },
{ name: '기와4', value: 'material4' },
{ name: '기와5', value: 'material5' },
]
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xxxm`}>
<div className="modal-head">
<h1 className="title">変更 </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="slope-wrap">
<div className="grid-select">
<QSelectBox title={'지붕재 선택'} options={roofMaterials} />
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">ストレージ</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -0,0 +1,71 @@
'use client'
import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage'
import { canvasState } from '@/store/canvasAtom'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useState } from 'react'
export default function SizeSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const [settingTarget, setSettingTarget] = useState(1)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState)
const { closePopup } = usePopup()
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap ssm`}>
<div className="modal-head">
<h1 className="title">サイズ変更 </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="slope-wrap">
<div className="size-option-top">
<div className="size-option-wrap">
<div className="size-option mb5">
<input type="text" className="input-origin mr5" defaultValue={1000} readOnly />
<span className="normal-font">mm</span>
</div>
<div className="size-option">
<input type="text" className="input-origin mr5" defaultValue={1000} />
<span className="normal-font">mm</span>
</div>
</div>
</div>
<div className="size-inner-warp">
<div className="size-option-side">
<div className="size-option-wrap">
<div className="size-option mb5">
<input type="text" className="input-origin mr5" defaultValue={1000} readOnly />
<span className="normal-font">mm</span>
</div>
<div className="size-option">
<input type="text" className="input-origin mr5" defaultValue={1000} />
<span className="normal-font">mm</span>
</div>
</div>
</div>
<div className="size-check-wrap">
<button className={`size-btn ${settingTarget === 1 ? 'act' : ''}`} onClick={() => setSettingTarget(1)}></button>
<button className={`size-btn ${settingTarget === 2 ? 'act' : ''}`} onClick={() => setSettingTarget(2)}></button>
<button className={`size-btn ${settingTarget === 3 ? 'act' : ''}`} onClick={() => setSettingTarget(3)}></button>
<button className={`size-btn ${settingTarget === 4 ? 'act' : ''}`} onClick={() => setSettingTarget(4)}></button>
<div className="size-box"></div>
</div>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">作成</button>
</div>
</div>
</div>
</WithDraggable>
)
}

View File

@ -1,8 +1,17 @@
import Image from 'next/image' import Image from 'next/image'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { forwardRef, useState } from 'react'
export default function PentagonDormer() { const PentagonDormer = forwardRef((props, refs) => {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [direction, setDirection] = useState('down')
refs.directionRef.current = direction
const getDirection = (e) => {
setDirection(e.target.value)
refs.directionRef.current = e.target.value
}
return ( return (
<> <>
<div className="discrimination-box mb10"> <div className="discrimination-box mb10">
@ -18,7 +27,7 @@ export default function PentagonDormer() {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}> <div className="input-grid mr5" style={{ width: '60px' }}>
<input type="text" className="input-origin block" defaultValue={2000} /> <input type="text" className="input-origin block" placeholder={0} ref={refs.heightRef} defaultValue={2000} />
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
@ -29,7 +38,7 @@ export default function PentagonDormer() {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}> <div className="input-grid mr5" style={{ width: '60px' }}>
<input type="text" className="input-origin block" defaultValue={1000} /> <input type="text" className="input-origin block" placeholder={0} ref={refs.offsetRef} />
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
@ -40,18 +49,18 @@ export default function PentagonDormer() {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}> <div className="input-grid mr5" style={{ width: '60px' }}>
<input type="text" className="input-origin block" defaultValue={4000} /> <input type="text" className="input-origin block" placeholder={0} ref={refs.widthRef} defaultValue={2000} />
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
</div> </div>
</div> </div>
<div className="eaves-keraba-item"> <div className="eaves-keraba-item">
<div className="eaves-keraba-th">{getMessage('modal.object.setting.offset.depth')}</div> <div className="eaves-keraba-th">{getMessage('modal.object.setting.offset.width')}</div>
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}> <div className="input-grid mr5" style={{ width: '60px' }}>
<input type="text" className="input-origin block" defaultValue={500} /> <input type="text" className="input-origin block" placeholder={0} ref={refs.offsetWidthRef} />
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
@ -62,7 +71,7 @@ export default function PentagonDormer() {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}> <div className="input-grid mr5" style={{ width: '60px' }}>
<input type="text" className="input-origin block" defaultValue={4} /> <input type="text" className="input-origin block" placeholder={0} ref={refs.pitchRef} defaultValue={4} />
</div> </div>
<span className="thin"></span> <span className="thin"></span>
</div> </div>
@ -80,13 +89,15 @@ export default function PentagonDormer() {
<span className="right">{getMessage('commons.east')}</span> <span className="right">{getMessage('commons.east')}</span>
<span className="bottom">{getMessage('commons.south')}</span> <span className="bottom">{getMessage('commons.south')}</span>
<span className="left">{getMessage('commons.west')}</span> <span className="left">{getMessage('commons.west')}</span>
<button className="plane-btn up"></button> <button className={`plane-btn up ${direction === 'up' ? ' act' : ''}`} value="up" onClick={getDirection}></button>
<button className="plane-btn right"></button> <button className={`plane-btn right ${direction === 'right' ? ' act' : ''}`} value="right" onClick={getDirection}></button>
<button className="plane-btn down act"></button> <button className={`plane-btn down ${direction === 'down' ? ' act' : ''}`} value="down" onClick={getDirection}></button>
<button className="plane-btn left"></button> <button className={`plane-btn left ${direction === 'left' ? ' act' : ''}`} value="left" onClick={getDirection}></button>
</div> </div>
</div> </div>
</div> </div>
</> </>
) )
} })
export default PentagonDormer

View File

@ -5,7 +5,6 @@ import { forwardRef, useState } from 'react'
const TriangleDormer = forwardRef((props, refs) => { const TriangleDormer = forwardRef((props, refs) => {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [direction, setDirection] = useState('down') const [direction, setDirection] = useState('down')
refs.directionRef.current = direction refs.directionRef.current = direction
const getDirection = (e) => { const getDirection = (e) => {

View File

@ -4,21 +4,15 @@ import { usePropertiesSetting } from '@/hooks/roofcover/usePropertiesSetting'
export default function PropertiesSetting(props) { export default function PropertiesSetting(props) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { setShowPropertiesSettingModal } = props const { id, pos = { x: 50, y: 230 } } = props
const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting(id)
const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting(setShowPropertiesSettingModal)
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap ssm`}> <div className={`modal-pop-wrap ssm`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.canvas.setting.wallline.properties.setting')}</h1> <h1 className="title">{getMessage('modal.canvas.setting.wallline.properties.setting')}</h1>
<button <button className="modal-close" onClick={() => closeModal(id)}>
className="modal-close"
onClick={() => {
closeModal(setShowPropertiesSettingModal)
}}
>
닫기 닫기
</button> </button>
</div> </div>
@ -39,13 +33,7 @@ export default function PropertiesSetting(props) {
<button className="btn-frame modal mr5" onClick={handleRollback}> <button className="btn-frame modal mr5" onClick={handleRollback}>
{getMessage('modal.cover.outline.rollback')} {getMessage('modal.cover.outline.rollback')}
</button> </button>
<button <button className="btn-frame modal act" onClick={() => handleFix()}>
className="btn-frame modal act"
onClick={() => {
handleFix()
setShowPropertiesSettingModal(false)
}}
>
{getMessage('modal.cover.outline.finish')} {getMessage('modal.cover.outline.finish')}
</button> </button>
</div> </div>

View File

@ -9,10 +9,15 @@ import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle'
import Angle from '@/components/floor-plan/modal/lineTypes/Angle' import Angle from '@/components/floor-plan/modal/lineTypes/Angle'
import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch' import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch'
import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal' import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal'
import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react'
import { v4 as uuidv4 } from 'uuid'
export default function WallLineSetting(props) { export default function WallLineSetting(props) {
const { setShowOutlineModal, setShowPropertiesSettingModal } = props const { id } = props
const { addPopup, closePopup } = usePopup()
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [propertiesId, setPropertiesId] = useState(uuidv4())
const { const {
length1, length1,
setLength1, setLength1,
@ -39,7 +44,7 @@ export default function WallLineSetting(props) {
outerLineDiagonalLengthRef, outerLineDiagonalLengthRef,
handleRollback, handleRollback,
handleFix, handleFix,
} = useOuterLineWall(setShowOutlineModal) } = useOuterLineWall(id, propertiesId)
const outerLineProps = { const outerLineProps = {
length1, length1,
@ -109,13 +114,11 @@ export default function WallLineSetting(props) {
} }
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={{ x: 50, y: 230 }}>
<div className={`modal-pop-wrap r mount`}> <div className={`modal-pop-wrap r mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.cover.outline.drawing')}</h1> <h1 className="title">{getMessage('modal.cover.outline.drawing')}</h1>
<button className="modal-close" onClick={() => setShowOutlineModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}></button>
닫기
</button>
</div> </div>
<div className="modal-body"> <div className="modal-body">
<div className="modal-btn-wrap"> <div className="modal-btn-wrap">
@ -172,7 +175,9 @@ export default function WallLineSetting(props) {
className="btn-frame modal act" className="btn-frame modal act"
onClick={() => { onClick={() => {
handleFix() handleFix()
setShowPropertiesSettingModal(true) // closePopup(id)
// setShowPropertiesSettingModal(true)
}} }}
> >
{getMessage('modal.cover.outline.fix')} {getMessage('modal.cover.outline.fix')}

View File

@ -5,13 +5,14 @@ import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle'
import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch' import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch'
import Angle from '@/components/floor-plan/modal/lineTypes/Angle' import Angle from '@/components/floor-plan/modal/lineTypes/Angle'
import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal' import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal'
import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall'
import { OUTER_LINE_TYPE } from '@/store/outerLineAtom' import { OUTER_LINE_TYPE } from '@/store/outerLineAtom'
import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall' import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall'
import { usePlacementShapeDrawing } from '@/hooks/surface/usePlacementShapeDrawing' import { usePlacementShapeDrawing } from '@/hooks/surface/usePlacementShapeDrawing'
import { usePopup } from '@/hooks/usePopup'
export default function PlacementShapeDrawing({ setShowPlaceShapeDrawingModal }) { export default function PlacementShapeDrawing({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [buttonAct, setButtonAct] = useState(1) const [buttonAct, setButtonAct] = useState(1)
const types = [ const types = [
{ id: 1, name: getMessage('straight.line'), type: OUTER_LINE_TYPE.OUTER_LINE }, { id: 1, name: getMessage('straight.line'), type: OUTER_LINE_TYPE.OUTER_LINE },
@ -46,7 +47,7 @@ export default function PlacementShapeDrawing({ setShowPlaceShapeDrawingModal })
outerLineDiagonalLengthRef, outerLineDiagonalLengthRef,
handleRollback, handleRollback,
handleFix, handleFix,
} = usePlacementShapeDrawing(setShowPlaceShapeDrawingModal) } = usePlacementShapeDrawing(id)
const outerLineProps = { const outerLineProps = {
length1, length1,
@ -120,11 +121,11 @@ export default function PlacementShapeDrawing({ setShowPlaceShapeDrawingModal })
setType(button.type) setType(button.type)
} }
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap r`}> <div className={`modal-pop-wrap r`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.placement.surface.drawing')}</h1> <h1 className="title">{getMessage('plan.menu.placement.surface.drawing')}</h1>
<button className="modal-close" onClick={() => setShowPlaceShapeDrawingModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -1,24 +1,36 @@
import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide' import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide'
import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide' import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input, Select, SelectItem } from '@nextui-org/react'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { Fragment, useEffect, useState } from 'react' import { Fragment, useEffect, useState } from 'react'
import { canvasSettingState } from '@/store/canvasAtom' import { canvasSettingState } from '@/store/canvasAtom'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useAxios } from '@/hooks/useAxios' import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import { usePopup } from '@/hooks/usePopup'
export default function PlacementShapeSetting({ setShowPlaceShapeModal }) { export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
const [objectNo, setObjectNo] = useState('test123241008001') // const [objectNo, setObjectNo] = useState('test123241008001') //
const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showSizeGuideModal, setShowSizeGuidModal] = useState(false)
const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false)
const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(1) const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(1)
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
const { closePopup } = usePopup()
const [basicSetting, setBasicSettings] = useState({ const [basicSetting, setBasicSettings] = useState({
roofSizeSet: 1, roofSizeSet: 1,
roofAngleSet: 'slope', roofAngleSet: 'slope',
roofs: [{ roofApply: true, roofSeq: 1, roofType: 1, roofWidth: 200, roofHeight: 200, roofHajebichi: 200, roofGap: 0, roofLayout: 'parallel' }], roofs: [
{
roofApply: true,
roofSeq: 1,
roofType: 1,
roofWidth: 200,
roofHeight: 200,
roofHajebichi: 200,
roofGap: 0,
roofLayout: 'parallel',
},
],
}) })
const { getMessage } = useMessage() const { getMessage } = useMessage()
@ -159,11 +171,11 @@ export default function PlacementShapeSetting({ setShowPlaceShapeModal }) {
} }
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap l mount`}> <div className={`modal-pop-wrap l mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.placement.surface.initial.setting')}</h1> <h1 className="title">{getMessage('plan.menu.placement.surface.initial.setting')}</h1>
<button className="modal-close" onClick={() => setShowPlaceShapeModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -1,21 +1,22 @@
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useEffect, useState, useRef } from 'react' import { useEffect, useRef, useState } from 'react'
import Image from 'next/image' import Image from 'next/image'
import PlacementSurface from '@/components/floor-plan/modal/placementSurface/PlacementSurface' import PlacementSurface from '@/components/floor-plan/modal/placementSurface/PlacementSurface'
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
import { POLYGON_TYPE } from '@/common/common' import { POLYGON_TYPE } from '@/common/common'
import { usePopup } from '@/hooks/usePopup'
export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSettingModal }) { export default function PlacementSurfaceSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [selectedType, setSelectedType] = useState() const [selectedType, setSelectedType] = useState()
const [rotate, setRotate] = useState(0) const [rotate, setRotate] = useState(0)
const [xInversion, setXInversion] = useState(false) const [xInversion, setXInversion] = useState(false)
const [yInversion, setYInversion] = useState(false) const [yInversion, setYInversion] = useState(false)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { closePopup } = usePopup()
const { applySurfaceShape } = useSurfaceShapeBatch() const { applySurfaceShape } = useSurfaceShapeBatch()
const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
@ -231,7 +232,7 @@ export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSetting
surfaceRefs.xInversion = xInversion // surfaceRefs.xInversion = xInversion //
surfaceRefs.yInversion = yInversion // surfaceRefs.yInversion = yInversion //
surfaceRefs.rotate = rotate * 90 // surfaceRefs.rotate = rotate * 90 //
applySurfaceShape(surfaceRefs, selectedType, setShowPlacementSurfaceSettingModal) applySurfaceShape(surfaceRefs, selectedType, id)
} }
useEffect(() => { useEffect(() => {
@ -239,11 +240,11 @@ export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSetting
}, []) }, [])
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={{ x: 50, y: 230 }}>
<div className={`modal-pop-wrap l-2`}> <div className={`modal-pop-wrap l-2`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.placement.surface.arrangement')} </h1> <h1 className="title">{getMessage('plan.menu.placement.surface.arrangement')} </h1>
<button className="modal-close" onClick={() => setShowPlacementSurfaceSettingModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -1,20 +1,25 @@
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useState } from 'react'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSetting' import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSetting'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function RoofAllocationSetting({ setShowRoofAllocationSettingModal }) { export default function RoofAllocationSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup()
const { handleSave, onAddRoofMaterial, onDeleteRoofMaterial, values, roofMaterials, selectedRoofMaterial, setSelectedRoofMaterial } = const { handleSave, onAddRoofMaterial, onDeleteRoofMaterial, values, roofMaterials, selectedRoofMaterial, setSelectedRoofMaterial } =
useRoofAllocationSetting(setShowRoofAllocationSettingModal) useRoofAllocationSetting(id)
return ( return (
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap ml`}> <div className={`modal-pop-wrap ml`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1> <h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
<button className="modal-close" onClick={() => setShowRoofAllocationSettingModal(false)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
</div> </div>

Some files were not shown because too many files have changed in this diff Show More