diff --git a/package.json b/package.json index f338fbe4..c92c5d80 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "react-icons": "^5.3.0", "react-loading-skeleton": "^3.5.0", "react-responsive-modal": "^6.4.2", + "react-spinners": "^0.14.1", "recoil": "^0.7.7", "sweetalert2": "^11.14.1", "sweetalert2-react-content": "^5.0.7", diff --git a/src/app/QcastProvider.js b/src/app/QcastProvider.js index bde4f380..3dfb02e9 100644 --- a/src/app/QcastProvider.js +++ b/src/app/QcastProvider.js @@ -7,14 +7,18 @@ import { usePlan } from '@/hooks/usePlan' import ServerError from './error' import '@/styles/common.scss' +import GlobalSpinner from '@/components/common/spinner/GlobalSpinner' export const QcastContext = createContext({ qcastState: {}, setQcastState: () => {}, + isGlobalLoading: true, + setIsGlobalLoading: () => {}, }) export const QcastProvider = ({ children }) => { const [planSave, setPlanSave] = useState(false) + const [isGlobalLoading, setIsGlobalLoading] = useState(true) const { currentCanvasPlan, modifiedPlans, checkUnsavedCanvasPlan } = usePlan() const { commonCode, findCommonCode } = useCommonCode() @@ -43,7 +47,12 @@ export const QcastProvider = ({ children }) => { return ( <> - + {isGlobalLoading && ( +
+ +
+ )} + }>{children} diff --git a/src/app/layout.js b/src/app/layout.js index 684dfb7f..fbe6c39a 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -62,16 +62,16 @@ export default async function RootLayout({ children }) { {headerPathname === '/login' || headerPathname === '/join' ? ( {children} ) : ( -
-
-
- - + +
+
+
+ {children} - +
+
-
-
+ )} diff --git a/src/components/common/spinner/GlobalSpinner.jsx b/src/components/common/spinner/GlobalSpinner.jsx new file mode 100644 index 00000000..c643cc30 --- /dev/null +++ b/src/components/common/spinner/GlobalSpinner.jsx @@ -0,0 +1,7 @@ +'use client' + +import { HashLoader } from 'react-spinners' + +export default function GlobalSpinner() { + return +} diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 017bc1d1..2674936c 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -1,5 +1,5 @@ 'use client' -import { Fragment, useCallback, useEffect, useState } from 'react' +import { Fragment, useCallback, useContext, useEffect, useState } from 'react' import Link from 'next/link' import { usePathname } from 'next/navigation' @@ -17,6 +17,7 @@ import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { stuffSearchState } from '@/store/stuffAtom' +import { QcastContext } from '@/app/QcastProvider' export const ToggleonMouse = (e, act, target) => { const listWrap = e.target.closest(target) @@ -47,6 +48,8 @@ export default function Header(props) { // } const [selected, setSelected] = useState('') + const { isGlobalLoading } = useContext(QcastContext) + const dimmedState = useRecoilValue(dimmedStore) const isDimmed = dimmedState ? 'opacity-50 bg-black' : '' @@ -164,54 +167,56 @@ export default function Header(props) { } return ( - !(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && ( -
-
-
-

- -

- -
-
-
- { - setUserInfoModal(true) - }} - > - - - {userInfoModal && } + <> + {!isGlobalLoading && !(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && ( +
+
+
+

+ +

+
-
- -
-
- -
-
- +
+
+ { + setUserInfoModal(true) + }} + > + + + {userInfoModal && } +
+
+ +
+
+ +
+
+ +
-
-
- ) +
+ )} + ) } diff --git a/src/hooks/main/useMainContentsController.js b/src/hooks/main/useMainContentsController.js index 0d2b0436..01f75658 100644 --- a/src/hooks/main/useMainContentsController.js +++ b/src/hooks/main/useMainContentsController.js @@ -1,6 +1,6 @@ 'use client' -import { useContext } from 'react' +import { useContext, useEffect } from 'react' import { useAxios } from '../useAxios' import { SessionContext } from '@/app/SessionProvider' import { QcastContext } from '@/app/QcastProvider' @@ -8,7 +8,11 @@ import { QcastContext } from '@/app/QcastProvider' export const useMainContentsController = () => { const { session } = useContext(SessionContext) const { promiseGet } = useAxios() - const { setQcastState } = useContext(QcastContext) + const { setQcastState, setIsGlobalLoading } = useContext(QcastContext) + + useEffect(() => { + setIsGlobalLoading(true) + }, []) /** * main search area @@ -46,6 +50,7 @@ export const useMainContentsController = () => { businessCharger: res.data.businessCharger, businessChargerMail: res.data.businessChargerMail, }) + setIsGlobalLoading(false) } else { // setSaleStoreId('') // setSaleStoreName('') diff --git a/yarn.lock b/yarn.lock index 81129787..7bcccdcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5663,7 +5663,7 @@ react-datepicker@^7.3.0: prop-types "^15.7.2" react-onclickoutside "^6.13.0" -"react-dom@^15.5.x || ^16.x || ^17.x || ^18.x", "react-dom@^16.3.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react-dom@^16.9.0 || ^17 || ^18", react-dom@^18, react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 16.3.0", react-dom@>=16.6.0, react-dom@>=16.8.0, react-dom@>=18: +"react-dom@^15.5.x || ^16.x || ^17.x || ^18.x", "react-dom@^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.3.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react-dom@^16.9.0 || ^17 || ^18", react-dom@^18, react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 16.3.0", react-dom@>=16.6.0, react-dom@>=16.8.0, react-dom@>=18: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -5747,6 +5747,11 @@ react-select@^5.8.1: react-transition-group "^4.3.0" use-isomorphic-layout-effect "^1.1.2" +react-spinners@^0.14.1: + version "0.14.1" + resolved "https://registry.npmjs.org/react-spinners/-/react-spinners-0.14.1.tgz" + integrity sha512-2Izq+qgQ08HTofCVEdcAQCXFEYfqTDdfeDQJeo/HHQiQJD4imOicNLhkfN2eh1NYEWVOX4D9ok2lhuDB0z3Aag== + react-style-singleton@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz" @@ -5775,7 +5780,7 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" -react@*, "react@^15.5.x || ^16.x || ^17.x || ^18.x", "react@^16.3.0 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react@^16.9.0 || ^17 || ^18", react@^18, react@^18.0.0, react@^18.2.0, react@^18.3.1, "react@>= 16.3.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16.13.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=18: +react@*, "react@^15.5.x || ^16.x || ^17.x || ^18.x", "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.3.0 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react@^16.9.0 || ^17 || ^18", react@^18, react@^18.0.0, react@^18.2.0, react@^18.3.1, "react@>= 16.3.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16.13.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=18: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==