refactor(frontend): 공통 모듈 분리 + 탭 단위 패키지 구조 전환 #21
205
frontend/package-lock.json
generated
205
frontend/package-lock.json
generated
@ -19,7 +19,6 @@
|
||||
"emoji-mart": "^5.6.0",
|
||||
"leaflet": "^1.9.4",
|
||||
"lucide-react": "^0.564.0",
|
||||
"ol": "^10.8.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-leaflet": "^5.0.0",
|
||||
@ -1148,12 +1147,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@petamoriken/float16": {
|
||||
"version": "3.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.3.tgz",
|
||||
"integrity": "sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@react-leaflet/core": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz",
|
||||
@ -1650,12 +1643,6 @@
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/rbush": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-4.0.0.tgz",
|
||||
"integrity": "sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
||||
@ -1966,16 +1953,6 @@
|
||||
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@zarrita/storage": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@zarrita/storage/-/storage-0.1.4.tgz",
|
||||
"integrity": "sha512-qURfJAQcQGRfDQ4J9HaCjGaj3jlJKc66bnRk6G/IeLUsM7WKyG7Bzsuf1EZurSXyc0I4LVcu6HaeQQ4d3kZ16g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"reference-spec-reader": "^0.2.0",
|
||||
"unzipit": "1.4.3"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
@ -2483,12 +2460,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/earcut": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz",
|
||||
"integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.286",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
|
||||
@ -2897,12 +2868,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fflate": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
||||
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/file-entry-cache": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||
@ -3051,25 +3016,6 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/geotiff": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-3.0.3.tgz",
|
||||
"integrity": "sha512-yRoDQDYxWYiB421p0cbxJvdy79OlQW+rxDI9GDbIUeWCAh6YAZ0vlTKF448EAiEuuUpBsNaegd2flavF0p+kvw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@petamoriken/float16": "^3.4.7",
|
||||
"lerc": "^3.0.0",
|
||||
"pako": "^2.0.4",
|
||||
"parse-headers": "^2.0.2",
|
||||
"quick-lru": "^6.1.1",
|
||||
"web-worker": "^1.5.0",
|
||||
"xml-utils": "^1.10.2",
|
||||
"zstddec": "^0.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.19"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
@ -3410,12 +3356,6 @@
|
||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/lerc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz",
|
||||
"integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/levn": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||
@ -3633,15 +3573,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/numcodecs": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/numcodecs/-/numcodecs-0.3.2.tgz",
|
||||
"integrity": "sha512-6YSPnmZgg0P87jnNhi3s+FVLOcIn3y+1CTIgUulA3IdASzK9fJM87sUFkpyA+be9GibGRaST2wCgkD+6U+fWKw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fflate": "^0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@ -3662,24 +3593,6 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/ol": {
|
||||
"version": "10.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ol/-/ol-10.8.0.tgz",
|
||||
"integrity": "sha512-kLk7jIlJvKyhVMAjORTXKjzlM6YIByZ1H/d0DBx3oq8nSPCG6/gbLr5RxukzPgwbhnAqh+xHNCmrvmFKhVMvoQ==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@types/rbush": "4.0.0",
|
||||
"earcut": "^3.0.0",
|
||||
"geotiff": "^3.0.2",
|
||||
"pbf": "4.0.1",
|
||||
"rbush": "^4.0.0",
|
||||
"zarrita": "^0.6.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/openlayers"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||
@ -3730,12 +3643,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/pako": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
|
||||
"license": "(MIT AND Zlib)"
|
||||
},
|
||||
"node_modules/parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
@ -3749,12 +3656,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-headers": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.6.tgz",
|
||||
"integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@ -3782,18 +3683,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pbf": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz",
|
||||
"integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"resolve-protobuf-schema": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"pbf": "bin/pbf"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@ -4007,12 +3896,6 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/protocol-buffers-schema": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
|
||||
"integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
@ -4050,33 +3933,6 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/quick-lru": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
|
||||
"integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/quickselect": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
|
||||
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/rbush": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz",
|
||||
"integrity": "sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"quickselect": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "19.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
|
||||
@ -4158,12 +4014,6 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/reference-spec-reader": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/reference-spec-reader/-/reference-spec-reader-0.2.0.tgz",
|
||||
"integrity": "sha512-q0mfCi5yZSSHXpCyxjgQeaORq3tvDsxDyzaadA/5+AbAUwRyRuuTh0aRQuE/vAOt/qzzxidJ5iDeu1cLHaNBlQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.11",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
|
||||
@ -4195,15 +4045,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-protobuf-schema": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
|
||||
"integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"protocol-buffers-schema": "^3.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
|
||||
@ -4598,18 +4439,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unzipit": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/unzipit/-/unzipit-1.4.3.tgz",
|
||||
"integrity": "sha512-gsq2PdJIWWGhx5kcdWStvNWit9FVdTewm4SEG7gFskWs+XCVaULt9+BwuoBtJiRE8eo3L1IPAOrbByNLtLtIlg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uzip-module": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
||||
@ -4658,12 +4487,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/uzip-module": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/uzip-module/-/uzip-module-1.0.3.tgz",
|
||||
"integrity": "sha512-AMqwWZaknLM77G+VPYNZLEruMGWGzyigPK3/Whg99B3S6vGHuqsyl5ZrOv1UUF3paGK1U6PM0cnayioaryg/fA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
|
||||
@ -4739,12 +4562,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/web-worker": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz",
|
||||
"integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@ -4792,12 +4609,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xml-utils": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.10.2.tgz",
|
||||
"integrity": "sha512-RqM+2o1RYs6T8+3DzDSoTRAUfrvaejbVHcp3+thnAtDKo8LskR+HomLajEy5UjTz24rpka7AxVBRR3g2wTUkJA==",
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/xmlhttprequest-ssl": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
|
||||
@ -4826,16 +4637,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zarrita": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/zarrita/-/zarrita-0.6.1.tgz",
|
||||
"integrity": "sha512-YOMTW8FT55Rz+vadTIZeOFZ/F2h4svKizyldvPtMYSxPgSNcRkOzkxCsWpIWlWzB1I/LmISmi0bEekOhLlI+Zw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@zarrita/storage": "^0.1.4",
|
||||
"numcodecs": "^0.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
|
||||
@ -4859,12 +4660,6 @@
|
||||
"zod": "^3.25.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/zstddec": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.2.0.tgz",
|
||||
"integrity": "sha512-oyPnDa1X5c13+Y7mA/FDMNJrn4S8UNBe0KCqtDmor40Re7ALrPN6npFwyYVRRh+PqozZQdeg23QtbcamZnG5rA==",
|
||||
"license": "MIT AND BSD-3-Clause"
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "5.0.11",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz",
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
"emoji-mart": "^5.6.0",
|
||||
"leaflet": "^1.9.4",
|
||||
"lucide-react": "^0.564.0",
|
||||
"ol": "^10.8.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-leaflet": "^5.0.0",
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { GoogleOAuthProvider } from '@react-oauth/google'
|
||||
import { MainLayout } from './components/layout/MainLayout'
|
||||
import { LoginPage } from './components/auth/LoginPage'
|
||||
import { registerMainTabSwitcher } from './hooks/useSubMenu'
|
||||
import { useAuthStore } from './store/authStore'
|
||||
import { useMenuStore } from './store/menuStore'
|
||||
import type { MainTab } from '@common/types/navigation'
|
||||
import { MainLayout } from '@common/components/layout/MainLayout'
|
||||
import { LoginPage } from '@common/components/auth/LoginPage'
|
||||
import { registerMainTabSwitcher } from '@common/hooks/useSubMenu'
|
||||
import { useAuthStore } from '@common/store/authStore'
|
||||
import { useMenuStore } from '@common/store/menuStore'
|
||||
import { OilSpillView } from './components/views/OilSpillView'
|
||||
import { ReportsView } from './components/views/ReportsView'
|
||||
import { HNSView } from './components/views/HNSView'
|
||||
@ -17,8 +18,6 @@ import { AdminView } from './components/views/AdminView'
|
||||
import { PreScatView } from './components/views/PreScatView'
|
||||
import { RescueView } from './components/views/RescueView'
|
||||
|
||||
export type MainTab = 'prediction' | 'hns' | 'rescue' | 'reports' | 'aerial' | 'assets' | 'scat' | 'incidents' | 'board' | 'weather' | 'admin'
|
||||
|
||||
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID || ''
|
||||
|
||||
function App() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useRef, useEffect } from 'react'
|
||||
import type { Layer } from '../../data/layerDatabase'
|
||||
import type { Layer } from '../../../data/layerDatabase'
|
||||
|
||||
const PRESET_COLORS = [
|
||||
'#ef4444','#f97316','#eab308','#22c55e','#06b6d4',
|
||||
@ -1,5 +1,5 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import type { MainTab } from '../../App'
|
||||
import type { MainTab } from '../../types/navigation'
|
||||
import { TopBar } from './TopBar'
|
||||
import { SubMenuBar } from './SubMenuBar'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { MainTab } from '../../App'
|
||||
import type { MainTab } from '../../types/navigation'
|
||||
import { useSubMenu } from '../../hooks/useSubMenu'
|
||||
|
||||
interface SubMenuBarProps {
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useRef, useEffect, useMemo } from 'react'
|
||||
import type { MainTab } from '../../App'
|
||||
import type { MainTab } from '../../types/navigation'
|
||||
import { useAuthStore } from '../../store/authStore'
|
||||
import { useMenuStore } from '../../store/menuStore'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { fetchAllLayers, fetchLayerTree, fetchWMSLayers } from '../services/api'
|
||||
import type { Layer } from '../data/layerDatabase'
|
||||
import type { Layer } from '../../data/layerDatabase'
|
||||
|
||||
// 모든 레이어 조회 훅
|
||||
export function useLayers() {
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import type { MainTab } from '../App'
|
||||
import type { MainTab } from '../types/navigation'
|
||||
|
||||
interface SubMenuItem {
|
||||
id: string
|
||||
1
frontend/src/common/types/navigation.ts
Normal file
1
frontend/src/common/types/navigation.ts
Normal file
@ -0,0 +1 @@
|
||||
export type MainTab = 'prediction' | 'hns' | 'rescue' | 'reports' | 'aerial' | 'assets' | 'scat' | 'incidents' | 'board' | 'weather' | 'admin';
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { sanitizeHtml } from '../../utils/sanitize'
|
||||
import { sanitizeHtml } from '@common/utils/sanitize'
|
||||
|
||||
const panels = [
|
||||
{ id: 0, icon: '🌐', label: '개요' },
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useRef, useEffect } from 'react'
|
||||
import type { BacktrackPhase, BacktrackVessel, BacktrackConditions } from '../../types/backtrack'
|
||||
import type { BacktrackPhase, BacktrackVessel, BacktrackConditions } from '@common/types/backtrack'
|
||||
|
||||
interface BacktrackModalProps {
|
||||
isOpen: boolean
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { useState, useRef, useMemo } from 'react'
|
||||
import { sanitizeHtml } from '../../utils/sanitize'
|
||||
import { sanitizeHtml } from '@common/utils/sanitize'
|
||||
import { HNS_SEARCH_DB, type HNSSearchSubstance } from '../../data/hnsSubstanceSearchData'
|
||||
|
||||
/* ═══ HNS 물질 데이터베이스 ═══ */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useRef } from 'react'
|
||||
import { sanitizeHtml } from '../../utils/sanitize'
|
||||
import { sanitizeHtml } from '@common/utils/sanitize'
|
||||
|
||||
const theoryTabs = [
|
||||
{ icon: '🔬', name: '시스템 개요' },
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useRef } from 'react'
|
||||
import { sanitizeHtml } from '../../utils/sanitize'
|
||||
import { sanitizeHtml } from '@common/utils/sanitize'
|
||||
|
||||
const theoryTabs: { id: number; icon: string; name: string; nameColor?: string }[] = [
|
||||
{ id: 0, icon: '🌊', name: '시스템 개요' },
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { sanitizeHtml } from '../../utils/sanitize'
|
||||
import { sanitizeHtml } from '@common/utils/sanitize'
|
||||
|
||||
export function RescueTheoryView() {
|
||||
const contentHtml = `
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { sanitizeInput } from '../../utils/sanitize'
|
||||
import { sanitizeInput } from '@common/utils/sanitize'
|
||||
|
||||
interface BoardPost {
|
||||
id?: number
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { ComboBox } from '../ui/ComboBox'
|
||||
import { ComboBox } from '@common/components/ui/ComboBox'
|
||||
|
||||
interface HNSLeftPanelProps {
|
||||
activeSubTab: 'analysis' | 'list'
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import { useState, useMemo } from 'react'
|
||||
import { LayerTree } from '../layer/LayerTree'
|
||||
import { useLayerTree } from '../../hooks/useLayers'
|
||||
import { LayerTree } from '@common/components/layer/LayerTree'
|
||||
import { useLayerTree } from '@common/hooks/useLayers'
|
||||
import { layerData } from '../../data/layerData'
|
||||
import type { LayerNode } from '../../data/layerData'
|
||||
import type { Layer } from '../../data/layerDatabase'
|
||||
import { decimalToDMS } from '../../utils/coordinates'
|
||||
import { ComboBox } from '../ui/ComboBox'
|
||||
import { decimalToDMS } from '@common/utils/coordinates'
|
||||
import { ComboBox } from '@common/components/ui/ComboBox'
|
||||
import { ALL_MODELS } from '../views/OilSpillView'
|
||||
import type { PredictionModel } from '../views/OilSpillView'
|
||||
import type { BoomLine, BoomLineCoord, AlgorithmSettings, ContainmentResult } from '../../types/boomLine'
|
||||
import { generateAIBoomLines, runContainmentAnalysis, computePolylineLength, computeBearing } from '../../utils/geo'
|
||||
import type { BoomLine, BoomLineCoord, AlgorithmSettings, ContainmentResult } from '@common/types/boomLine'
|
||||
import { generateAIBoomLines, runContainmentAnalysis, computePolylineLength, computeBearing } from '@common/utils/geo'
|
||||
import type { Analysis } from '../analysis/AnalysisListTable'
|
||||
|
||||
interface LeftPanelProps {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { ReplayShip, CollisionEvent } from '../../types/backtrack'
|
||||
import type { ReplayShip, CollisionEvent } from '@common/types/backtrack'
|
||||
|
||||
interface BacktrackReplayBarProps {
|
||||
isPlaying: boolean
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react'
|
||||
import { Polyline, CircleMarker, Circle, Marker, Popup } from 'react-leaflet'
|
||||
import L from 'leaflet'
|
||||
import type { ReplayShip, CollisionEvent, ReplayPathPoint } from '../../types/backtrack'
|
||||
import type { ReplayShip, CollisionEvent, ReplayPathPoint } from '@common/types/backtrack'
|
||||
|
||||
interface BacktrackReplayOverlayProps {
|
||||
replayShips: ReplayShip[]
|
||||
|
||||
@ -3,10 +3,10 @@ import { MapContainer, TileLayer, Marker, Popup, useMap, useMapEvents, CircleMar
|
||||
import 'leaflet/dist/leaflet.css'
|
||||
import L from 'leaflet'
|
||||
import { layerDatabase } from '../../data/layerDatabase'
|
||||
import { decimalToDMS } from '../../utils/coordinates'
|
||||
import { decimalToDMS } from '@common/utils/coordinates'
|
||||
import type { PredictionModel } from '../views/OilSpillView'
|
||||
import type { BoomLine, BoomLineCoord } from '../../types/boomLine'
|
||||
import type { ReplayShip, CollisionEvent } from '../../types/backtrack'
|
||||
import type { BoomLine, BoomLineCoord } from '@common/types/boomLine'
|
||||
import type { ReplayShip, CollisionEvent } from '@common/types/backtrack'
|
||||
import { BacktrackReplayOverlay } from './BacktrackReplayOverlay'
|
||||
|
||||
// Fix Leaflet default icon issue
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
||||
import { useSubMenu } from '../../hooks/useSubMenu'
|
||||
import { useSubMenu } from '@common/hooks/useSubMenu'
|
||||
import data from '@emoji-mart/data'
|
||||
import EmojiPicker from '@emoji-mart/react'
|
||||
import {
|
||||
@ -43,8 +43,8 @@ import {
|
||||
type RegistrationSettings,
|
||||
type OAuthSettings,
|
||||
type MenuConfigItem,
|
||||
} from '../../services/authApi'
|
||||
import { useMenuStore } from '../../store/menuStore'
|
||||
} from '@common/services/authApi'
|
||||
import { useMenuStore } from '@common/store/menuStore'
|
||||
|
||||
const DEFAULT_ROLE_COLORS: Record<string, string> = {
|
||||
ADMIN: 'var(--red)',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useRef, useEffect } from 'react'
|
||||
import { useSubMenu } from '../../hooks/useSubMenu'
|
||||
import { useSubMenu } from '@common/hooks/useSubMenu'
|
||||
import { AerialTheoryView } from '../analysis/AerialTheoryView'
|
||||
|
||||
type AerialTab = 'media' | 'analysis' | 'realtime' | 'sensor'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { useSubMenu } from '../../hooks/useSubMenu'
|
||||
import { useSubMenu } from '@common/hooks/useSubMenu'
|
||||
import { BoardWriteForm } from '../board/BoardWriteForm'
|
||||
import { BoardDetailView } from '../board/BoardDetailView'
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { HNSTheoryView } from '../analysis/HNSTheoryView'
|
||||
import { HNSSubstanceView } from '../analysis/HNSSubstanceView'
|
||||
import { HNSScenarioView } from '../analysis/HNSScenarioView'
|
||||
import { HNSRecalcModal } from '../analysis/HNSRecalcModal'
|
||||
import { useSubMenu, navigateToTab, setReportGenCategory } from '../../hooks/useSubMenu'
|
||||
import { useSubMenu, navigateToTab, setReportGenCategory } from '@common/hooks/useSubMenu'
|
||||
|
||||
/* ─── HNS 매뉴얼 뷰어 컴포넌트 ─── */
|
||||
function HNSManualViewer() {
|
||||
|
||||
@ -8,10 +8,10 @@ import { BoomDeploymentTheoryView } from '../analysis/BoomDeploymentTheoryView'
|
||||
import { BacktrackModal } from '../analysis/BacktrackModal'
|
||||
import { RecalcModal } from '../analysis/RecalcModal'
|
||||
import { BacktrackReplayBar } from '../map/BacktrackReplayBar'
|
||||
import { useSubMenu, navigateToTab, setReportGenCategory } from '../../hooks/useSubMenu'
|
||||
import type { BoomLine, AlgorithmSettings, ContainmentResult, BoomLineCoord } from '../../types/boomLine'
|
||||
import type { BacktrackPhase, BacktrackVessel } from '../../types/backtrack'
|
||||
import { TOTAL_REPLAY_FRAMES } from '../../types/backtrack'
|
||||
import { useSubMenu, navigateToTab, setReportGenCategory } from '@common/hooks/useSubMenu'
|
||||
import type { BoomLine, AlgorithmSettings, ContainmentResult, BoomLineCoord } from '@common/types/boomLine'
|
||||
import type { BacktrackPhase, BacktrackVessel } from '@common/types/backtrack'
|
||||
import { TOTAL_REPLAY_FRAMES } from '@common/types/backtrack'
|
||||
import { MOCK_CONDITIONS, MOCK_VESSELS, MOCK_REPLAY_SHIPS, MOCK_COLLISION } from '../../data/backtrackMockData'
|
||||
|
||||
export type PredictionModel = 'KOSPS' | 'POSEIDON' | 'OpenDrift'
|
||||
|
||||
@ -9,8 +9,8 @@ import {
|
||||
type ReportType,
|
||||
type Jurisdiction,
|
||||
} from '../reports/OilSpillReportTemplate'
|
||||
import { sanitizeHtml } from '../../utils/sanitize'
|
||||
import { useSubMenu, consumeReportGenCategory } from '../../hooks/useSubMenu'
|
||||
import { sanitizeHtml } from '@common/utils/sanitize'
|
||||
import { useSubMenu, consumeReportGenCategory } from '@common/hooks/useSubMenu'
|
||||
|
||||
// ─── Report Export Helpers ──────────────────────────────
|
||||
function generateReportHTML(
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useSubMenu } from '../../hooks/useSubMenu'
|
||||
import { useSubMenu } from '@common/hooks/useSubMenu'
|
||||
import { RescueTheoryView } from '../analysis/RescueTheoryView'
|
||||
import { RescueScenarioView } from '../analysis/RescueScenarioView'
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { BacktrackConditions, BacktrackVessel, ReplayShip, CollisionEvent } from '../types/backtrack'
|
||||
import type { BacktrackConditions, BacktrackVessel, ReplayShip, CollisionEvent } from '@common/types/backtrack'
|
||||
|
||||
export const MOCK_CONDITIONS: BacktrackConditions = {
|
||||
estimatedSpillTime: '02-10 06:30',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// 레이어 데이터베이스 - API에서 가져옴
|
||||
import { fetchAllLayers } from '../services/api'
|
||||
import { fetchAllLayers } from '@common/services/api'
|
||||
|
||||
export interface Layer {
|
||||
id: string
|
||||
|
||||
@ -22,7 +22,14 @@
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
"noUncheckedSideEffectImports": true,
|
||||
|
||||
/* Path aliases */
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@common/*": ["src/common/*"],
|
||||
"@tabs/*": ["src/tabs/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import path from 'path'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@common': path.resolve(__dirname, 'src/common'),
|
||||
'@tabs': path.resolve(__dirname, 'src/tabs'),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user