From 7fb0cf6fba25a3a638fd7877e6eace11229cdee0 Mon Sep 17 00:00:00 2001 From: artwork21c Date: Tue, 30 Dec 2025 19:15:56 +0900 Subject: [PATCH] =?UTF-8?q?coreui=20=EC=86=8C=EC=8A=A4=EB=A5=BC=20ts=20?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 9 ++++- src/{App.js => App.tsx} | 15 +++++---- src/{_nav.js => _nav.tsx} | 0 src/assets/brand/{logo.js => logo.ts} | 0 src/assets/brand/{sygnet.js => sygnet.ts} | 0 .../{AppBreadcrumb.js => AppBreadcrumb.tsx} | 0 .../{AppContent.js => AppContent.tsx} | 2 -- .../{AppFooter.js => AppFooter.tsx} | 0 .../{AppHeader.js => AppHeader.tsx} | 5 +-- .../{AppSidebar.js => AppSidebar.tsx} | 8 +++-- .../{AppSidebarNav.js => AppSidebarNav.tsx} | 0 .../{DocsComponents.js => DocsComponents.tsx} | 0 .../{DocsExample.js => DocsExample.tsx} | 0 .../{DocsIcons.js => DocsIcons.tsx} | 0 src/components/{DocsLink.js => DocsLink.tsx} | 0 ...eaderDropdown.js => AppHeaderDropdown.tsx} | 0 src/components/header/{index.js => index.tsx} | 0 src/components/{index.js => index.ts} | 0 src/images.d.ts | 19 +++++++++++ src/{index.js => index.tsx} | 2 +- .../{DefaultLayout.js => DefaultLayout.tsx} | 0 src/{routes.js => routes.ts} | 0 src/store.js | 18 ---------- src/store.tsx | 33 +++++++++++++++++++ src/styles.d.ts | 4 +++ .../dashboard/{Dashboard.js => Dashboard.tsx} | 0 .../dashboard/{MainChart.js => MainChart.tsx} | 0 src/views/pages/login/{Login.js => Login.tsx} | 0 .../pages/page404/{Page404.js => Page404.tsx} | 0 .../pages/page500/{Page500.js => Page500.tsx} | 0 .../register/{Register.js => Register.tsx} | 0 .../theme/colors/{Colors.js => Colors.tsx} | 0 .../{Typography.js => Typography.tsx} | 0 tsconfig.json | 31 +++++++++++++++++ vite.config.mjs | 7 +--- 35 files changed, 113 insertions(+), 40 deletions(-) rename src/{App.js => App.tsx} (72%) rename src/{_nav.js => _nav.tsx} (100%) rename src/assets/brand/{logo.js => logo.ts} (100%) rename src/assets/brand/{sygnet.js => sygnet.ts} (100%) rename src/components/{AppBreadcrumb.js => AppBreadcrumb.tsx} (100%) rename src/components/{AppContent.js => AppContent.tsx} (91%) rename src/components/{AppFooter.js => AppFooter.tsx} (100%) rename src/components/{AppHeader.js => AppHeader.tsx} (96%) rename src/components/{AppSidebar.js => AppSidebar.tsx} (84%) rename src/components/{AppSidebarNav.js => AppSidebarNav.tsx} (100%) rename src/components/{DocsComponents.js => DocsComponents.tsx} (100%) rename src/components/{DocsExample.js => DocsExample.tsx} (100%) rename src/components/{DocsIcons.js => DocsIcons.tsx} (100%) rename src/components/{DocsLink.js => DocsLink.tsx} (100%) rename src/components/header/{AppHeaderDropdown.js => AppHeaderDropdown.tsx} (100%) rename src/components/header/{index.js => index.tsx} (100%) rename src/components/{index.js => index.ts} (100%) create mode 100644 src/images.d.ts rename src/{index.js => index.tsx} (81%) rename src/layout/{DefaultLayout.js => DefaultLayout.tsx} (100%) rename src/{routes.js => routes.ts} (100%) delete mode 100644 src/store.js create mode 100644 src/store.tsx create mode 100644 src/styles.d.ts rename src/views/dashboard/{Dashboard.js => Dashboard.tsx} (100%) rename src/views/dashboard/{MainChart.js => MainChart.tsx} (100%) rename src/views/pages/login/{Login.js => Login.tsx} (100%) rename src/views/pages/page404/{Page404.js => Page404.tsx} (100%) rename src/views/pages/page500/{Page500.js => Page500.tsx} (100%) rename src/views/pages/register/{Register.js => Register.tsx} (100%) rename src/views/theme/colors/{Colors.js => Colors.tsx} (100%) rename src/views/theme/typography/{Typography.js => Typography.tsx} (100%) create mode 100644 tsconfig.json diff --git a/package.json b/package.json index fccb0ae..0c47ad7 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "type": "module", "name": "@coreui/coreui-free-react-admin-template", "version": "5.5.0", "description": "CoreUI Free React Admin Template", @@ -27,6 +28,11 @@ "@coreui/react-chartjs": "^3.0.0", "@coreui/utils": "^2.0.2", "@popperjs/core": "^2.11.8", + "@types/jest": "^30.0.0", + "@types/node": "^25.0.3", + "@types/prop-types": "^15.7.15", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "chart.js": "^4.5.1", "classnames": "^2.5.1", "core-js": "^3.47.0", @@ -36,7 +42,8 @@ "react-redux": "^9.2.0", "react-router-dom": "^7.11.0", "redux": "5.0.1", - "simplebar-react": "^3.3.2" + "simplebar-react": "^3.3.2", + "typescript": "^5.9.3" }, "devDependencies": { "@vitejs/plugin-react": "^5.1.2", diff --git a/src/App.js b/src/App.tsx similarity index 72% rename from src/App.js rename to src/App.tsx index f5b2239..93554bf 100644 --- a/src/App.js +++ b/src/App.tsx @@ -1,6 +1,7 @@ import React, { Suspense, useEffect } from 'react' import { HashRouter, Route, Routes } from 'react-router-dom' import { useSelector } from 'react-redux' +import { RootState } from './store' import { CSpinner, useColorModes } from '@coreui/react' import './scss/style.scss' @@ -19,11 +20,11 @@ const Page500 = React.lazy(() => import('./views/pages/page500/Page500')) const App = () => { const { isColorModeSet, setColorMode } = useColorModes('coreui-free-react-admin-template-theme') - const storedTheme = useSelector((state) => state.theme) + const storedTheme = useSelector((state: RootState) => state.theme) useEffect(() => { const urlParams = new URLSearchParams(window.location.href.split('?')[1]) - const theme = urlParams.get('theme') && urlParams.get('theme').match(/^[A-Za-z0-9\s]+/)[0] + const theme = urlParams.get('theme')?.match(/^[A-Za-z0-9\s]+/)?.[0] if (theme) { setColorMode(theme) } @@ -45,11 +46,11 @@ const App = () => { } > - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> diff --git a/src/_nav.js b/src/_nav.tsx similarity index 100% rename from src/_nav.js rename to src/_nav.tsx diff --git a/src/assets/brand/logo.js b/src/assets/brand/logo.ts similarity index 100% rename from src/assets/brand/logo.js rename to src/assets/brand/logo.ts diff --git a/src/assets/brand/sygnet.js b/src/assets/brand/sygnet.ts similarity index 100% rename from src/assets/brand/sygnet.js rename to src/assets/brand/sygnet.ts diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.tsx similarity index 100% rename from src/components/AppBreadcrumb.js rename to src/components/AppBreadcrumb.tsx diff --git a/src/components/AppContent.js b/src/components/AppContent.tsx similarity index 91% rename from src/components/AppContent.js rename to src/components/AppContent.tsx index b9a39ef..ef4424e 100644 --- a/src/components/AppContent.js +++ b/src/components/AppContent.tsx @@ -16,8 +16,6 @@ const AppContent = () => { } /> ) diff --git a/src/components/AppFooter.js b/src/components/AppFooter.tsx similarity index 100% rename from src/components/AppFooter.js rename to src/components/AppFooter.tsx diff --git a/src/components/AppHeader.js b/src/components/AppHeader.tsx similarity index 96% rename from src/components/AppHeader.js rename to src/components/AppHeader.tsx index 4db98af..40db829 100644 --- a/src/components/AppHeader.js +++ b/src/components/AppHeader.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useRef } from 'react' import { NavLink } from 'react-router-dom' import { useSelector, useDispatch } from 'react-redux' +import { RootState } from '../store' import { CContainer, CDropdown, @@ -29,11 +30,11 @@ import { AppBreadcrumb } from './index' import { AppHeaderDropdown } from './header/index' const AppHeader = () => { - const headerRef = useRef() + const headerRef = useRef(null) const { colorMode, setColorMode } = useColorModes('coreui-free-react-admin-template-theme') const dispatch = useDispatch() - const sidebarShow = useSelector((state) => state.sidebarShow) + const sidebarShow = useSelector((state: RootState) => state.sidebarShow) useEffect(() => { const handleScroll = () => { diff --git a/src/components/AppSidebar.js b/src/components/AppSidebar.tsx similarity index 84% rename from src/components/AppSidebar.js rename to src/components/AppSidebar.tsx index 021cb52..d75d4a9 100644 --- a/src/components/AppSidebar.js +++ b/src/components/AppSidebar.tsx @@ -1,5 +1,7 @@ import React from 'react' +import { NavLink } from 'react-router-dom' import { useSelector, useDispatch } from 'react-redux' +import { RootState } from '../store' import { CCloseButton, @@ -21,8 +23,8 @@ import navigation from '../_nav' const AppSidebar = () => { const dispatch = useDispatch() - const unfoldable = useSelector((state) => state.sidebarUnfoldable) - const sidebarShow = useSelector((state) => state.sidebarShow) + const unfoldable = useSelector((state: RootState) => state.sidebarUnfoldable) + const sidebarShow = useSelector((state: RootState) => state.sidebarShow) return ( { }} > - + diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.tsx similarity index 100% rename from src/components/AppSidebarNav.js rename to src/components/AppSidebarNav.tsx diff --git a/src/components/DocsComponents.js b/src/components/DocsComponents.tsx similarity index 100% rename from src/components/DocsComponents.js rename to src/components/DocsComponents.tsx diff --git a/src/components/DocsExample.js b/src/components/DocsExample.tsx similarity index 100% rename from src/components/DocsExample.js rename to src/components/DocsExample.tsx diff --git a/src/components/DocsIcons.js b/src/components/DocsIcons.tsx similarity index 100% rename from src/components/DocsIcons.js rename to src/components/DocsIcons.tsx diff --git a/src/components/DocsLink.js b/src/components/DocsLink.tsx similarity index 100% rename from src/components/DocsLink.js rename to src/components/DocsLink.tsx diff --git a/src/components/header/AppHeaderDropdown.js b/src/components/header/AppHeaderDropdown.tsx similarity index 100% rename from src/components/header/AppHeaderDropdown.js rename to src/components/header/AppHeaderDropdown.tsx diff --git a/src/components/header/index.js b/src/components/header/index.tsx similarity index 100% rename from src/components/header/index.js rename to src/components/header/index.tsx diff --git a/src/components/index.js b/src/components/index.ts similarity index 100% rename from src/components/index.js rename to src/components/index.ts diff --git a/src/images.d.ts b/src/images.d.ts new file mode 100644 index 0000000..9b87a51 --- /dev/null +++ b/src/images.d.ts @@ -0,0 +1,19 @@ +declare module '*.webp' { + const src: string; + export default src; +} + +declare module '*.png' { + const src: string; + export default src; +} + +declare module '*.jpg' { + const src: string; + export default src; +} + +declare module '*.svg' { + const src: string; + export default src; +} \ No newline at end of file diff --git a/src/index.js b/src/index.tsx similarity index 81% rename from src/index.js rename to src/index.tsx index 11d6e86..441af3a 100644 --- a/src/index.js +++ b/src/index.tsx @@ -6,7 +6,7 @@ import 'core-js' import App from './App' import store from './store' -createRoot(document.getElementById('root')).render( +createRoot(document.getElementById('root')!).render( , diff --git a/src/layout/DefaultLayout.js b/src/layout/DefaultLayout.tsx similarity index 100% rename from src/layout/DefaultLayout.js rename to src/layout/DefaultLayout.tsx diff --git a/src/routes.js b/src/routes.ts similarity index 100% rename from src/routes.js rename to src/routes.ts diff --git a/src/store.js b/src/store.js deleted file mode 100644 index 8ad30da..0000000 --- a/src/store.js +++ /dev/null @@ -1,18 +0,0 @@ -import { legacy_createStore as createStore } from 'redux' - -const initialState = { - sidebarShow: true, - theme: 'light', -} - -const changeState = (state = initialState, { type, ...rest }) => { - switch (type) { - case 'set': - return { ...state, ...rest } - default: - return state - } -} - -const store = createStore(changeState) -export default store diff --git a/src/store.tsx b/src/store.tsx new file mode 100644 index 0000000..5edafef --- /dev/null +++ b/src/store.tsx @@ -0,0 +1,33 @@ +import { legacy_createStore as createStore } from 'redux' + +// 상태(State) 타입 정의 +interface AppState { + sidebarShow: boolean + sidebarUnfoldable: boolean + theme: string +} + +const initialState: AppState = { + sidebarShow: true, + sidebarUnfoldable: false, + theme: 'light', +} + +// 액션(Action) 타입 정의 +interface Action { + type: string + [key: string]: any +} + +const changeState = (state = initialState, { type, ...rest }: Action): AppState => { + switch (type) { + case 'set': + return { ...state, ...rest } + default: + return state + } +} + +const store = createStore(changeState) +export type RootState = ReturnType +export default store diff --git a/src/styles.d.ts b/src/styles.d.ts new file mode 100644 index 0000000..7cbc819 --- /dev/null +++ b/src/styles.d.ts @@ -0,0 +1,4 @@ +declare module '*.scss' { + const content: { [className: string]: string }; + export default content; +} \ No newline at end of file diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.tsx similarity index 100% rename from src/views/dashboard/Dashboard.js rename to src/views/dashboard/Dashboard.tsx diff --git a/src/views/dashboard/MainChart.js b/src/views/dashboard/MainChart.tsx similarity index 100% rename from src/views/dashboard/MainChart.js rename to src/views/dashboard/MainChart.tsx diff --git a/src/views/pages/login/Login.js b/src/views/pages/login/Login.tsx similarity index 100% rename from src/views/pages/login/Login.js rename to src/views/pages/login/Login.tsx diff --git a/src/views/pages/page404/Page404.js b/src/views/pages/page404/Page404.tsx similarity index 100% rename from src/views/pages/page404/Page404.js rename to src/views/pages/page404/Page404.tsx diff --git a/src/views/pages/page500/Page500.js b/src/views/pages/page500/Page500.tsx similarity index 100% rename from src/views/pages/page500/Page500.js rename to src/views/pages/page500/Page500.tsx diff --git a/src/views/pages/register/Register.js b/src/views/pages/register/Register.tsx similarity index 100% rename from src/views/pages/register/Register.js rename to src/views/pages/register/Register.tsx diff --git a/src/views/theme/colors/Colors.js b/src/views/theme/colors/Colors.tsx similarity index 100% rename from src/views/theme/colors/Colors.js rename to src/views/theme/colors/Colors.tsx diff --git a/src/views/theme/typography/Typography.js b/src/views/theme/typography/Typography.tsx similarity index 100% rename from src/views/theme/typography/Typography.js rename to src/views/theme/typography/Typography.tsx diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c349a5e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "target": "ES5", + "strict": true, + "allowJs": true, + "esModuleInterop": true, + "jsx": "react-jsx", + // Stricter Typechecking Options + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + // Style Options + // "noImplicitReturns": true, + // "noImplicitOverride": true, + // "noUnusedLocals": true, + // "noUnusedParameters": true, + // "noFallthroughCasesInSwitch": true, + // "noPropertyAccessFromIndexSignature": true, + // Recommended Options + "verbatimModuleSyntax": false, + "isolatedModules": true, + "noUncheckedSideEffectImports": true, + "moduleDetection": "force", + "skipLibCheck": true, + }, + "include": [ + "src", + "src/images.d.ts", + "src/styles.d.ts" + ] +} \ No newline at end of file diff --git a/vite.config.mjs b/vite.config.mjs index dc050f7..7766fd3 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -16,11 +16,6 @@ export default defineConfig(() => { ], }, }, - esbuild: { - loader: 'jsx', - include: /src\/.*\.jsx?$/, - exclude: [], - }, optimizeDeps: { force: true, esbuildOptions: { @@ -33,7 +28,7 @@ export default defineConfig(() => { resolve: { alias: [ { - find: 'src/', + find: 'src', replacement: `${path.resolve(__dirname, 'src')}/`, }, ],