feat: Add globalSpinner
- 글로벌 스피너 추가 - 글로벌 스피너 on/off 기능 추가
This commit is contained in:
parent
4233958df2
commit
24dca05f75
@ -32,6 +32,7 @@
|
|||||||
"react-icons": "^5.3.0",
|
"react-icons": "^5.3.0",
|
||||||
"react-loading-skeleton": "^3.5.0",
|
"react-loading-skeleton": "^3.5.0",
|
||||||
"react-responsive-modal": "^6.4.2",
|
"react-responsive-modal": "^6.4.2",
|
||||||
|
"react-spinners": "^0.14.1",
|
||||||
"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",
|
||||||
|
|||||||
@ -7,14 +7,18 @@ import { usePlan } from '@/hooks/usePlan'
|
|||||||
import ServerError from './error'
|
import ServerError from './error'
|
||||||
|
|
||||||
import '@/styles/common.scss'
|
import '@/styles/common.scss'
|
||||||
|
import GlobalSpinner from '@/components/common/spinner/GlobalSpinner'
|
||||||
|
|
||||||
export const QcastContext = createContext({
|
export const QcastContext = createContext({
|
||||||
qcastState: {},
|
qcastState: {},
|
||||||
setQcastState: () => {},
|
setQcastState: () => {},
|
||||||
|
isGlobalLoading: true,
|
||||||
|
setIsGlobalLoading: () => {},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const QcastProvider = ({ children }) => {
|
export const QcastProvider = ({ children }) => {
|
||||||
const [planSave, setPlanSave] = useState(false)
|
const [planSave, setPlanSave] = useState(false)
|
||||||
|
const [isGlobalLoading, setIsGlobalLoading] = useState(true)
|
||||||
const { currentCanvasPlan, modifiedPlans, checkUnsavedCanvasPlan } = usePlan()
|
const { currentCanvasPlan, modifiedPlans, checkUnsavedCanvasPlan } = usePlan()
|
||||||
const { commonCode, findCommonCode } = useCommonCode()
|
const { commonCode, findCommonCode } = useCommonCode()
|
||||||
|
|
||||||
@ -43,7 +47,12 @@ export const QcastProvider = ({ children }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<QcastContext.Provider value={{ qcastState, setQcastState }}>
|
{isGlobalLoading && (
|
||||||
|
<div className="fixed inset-0 bg-white z-50 flex items-center justify-center">
|
||||||
|
<GlobalSpinner />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<QcastContext.Provider value={{ qcastState, setQcastState, isGlobalLoading, setIsGlobalLoading }}>
|
||||||
<ErrorBoundary fallback={<ServerError />}>{children}</ErrorBoundary>
|
<ErrorBoundary fallback={<ServerError />}>{children}</ErrorBoundary>
|
||||||
</QcastContext.Provider>
|
</QcastContext.Provider>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -62,16 +62,16 @@ export default async function RootLayout({ children }) {
|
|||||||
{headerPathname === '/login' || headerPathname === '/join' ? (
|
{headerPathname === '/login' || headerPathname === '/join' ? (
|
||||||
<QcastProvider>{children}</QcastProvider>
|
<QcastProvider>{children}</QcastProvider>
|
||||||
) : (
|
) : (
|
||||||
|
<QcastProvider>
|
||||||
<div className="wrap">
|
<div className="wrap">
|
||||||
<Header userSession={sessionProps} />
|
<Header userSession={sessionProps} />
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<Dimmed />
|
<Dimmed />
|
||||||
<QcastProvider>
|
|
||||||
<SessionProvider useSession={sessionProps}>{children}</SessionProvider>
|
<SessionProvider useSession={sessionProps}>{children}</SessionProvider>
|
||||||
</QcastProvider>
|
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
</QcastProvider>
|
||||||
)}
|
)}
|
||||||
<QModal />
|
<QModal />
|
||||||
<PopupManager />
|
<PopupManager />
|
||||||
|
|||||||
7
src/components/common/spinner/GlobalSpinner.jsx
Normal file
7
src/components/common/spinner/GlobalSpinner.jsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { HashLoader } from 'react-spinners'
|
||||||
|
|
||||||
|
export default function GlobalSpinner() {
|
||||||
|
return <HashLoader />
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { Fragment, useCallback, useEffect, useState } from 'react'
|
import { Fragment, useCallback, useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { usePathname } from 'next/navigation'
|
import { usePathname } from 'next/navigation'
|
||||||
@ -17,6 +17,7 @@ import { useAxios } from '@/hooks/useAxios'
|
|||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
import { stuffSearchState } from '@/store/stuffAtom'
|
import { stuffSearchState } from '@/store/stuffAtom'
|
||||||
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
|
||||||
export const ToggleonMouse = (e, act, target) => {
|
export const ToggleonMouse = (e, act, target) => {
|
||||||
const listWrap = e.target.closest(target)
|
const listWrap = e.target.closest(target)
|
||||||
@ -47,6 +48,8 @@ export default function Header(props) {
|
|||||||
// }
|
// }
|
||||||
const [selected, setSelected] = useState('')
|
const [selected, setSelected] = useState('')
|
||||||
|
|
||||||
|
const { isGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
const dimmedState = useRecoilValue(dimmedStore)
|
const dimmedState = useRecoilValue(dimmedStore)
|
||||||
const isDimmed = dimmedState ? 'opacity-50 bg-black' : ''
|
const isDimmed = dimmedState ? 'opacity-50 bg-black' : ''
|
||||||
|
|
||||||
@ -164,7 +167,8 @@ export default function Header(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && (
|
<>
|
||||||
|
{!isGlobalLoading && !(pathName.includes('login') || pathName.includes('join') || sessionState.pwdInitYn === 'N') && (
|
||||||
<header className={isDimmed}>
|
<header className={isDimmed}>
|
||||||
<div className="header-inner">
|
<div className="header-inner">
|
||||||
<div className="header-right">
|
<div className="header-right">
|
||||||
@ -212,6 +216,7 @@ export default function Header(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
)
|
)}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useContext } from 'react'
|
import { useContext, useEffect } from 'react'
|
||||||
import { useAxios } from '../useAxios'
|
import { useAxios } from '../useAxios'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
@ -8,7 +8,11 @@ import { QcastContext } from '@/app/QcastProvider'
|
|||||||
export const useMainContentsController = () => {
|
export const useMainContentsController = () => {
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
const { promiseGet } = useAxios()
|
const { promiseGet } = useAxios()
|
||||||
const { setQcastState } = useContext(QcastContext)
|
const { setQcastState, setIsGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsGlobalLoading(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main search area
|
* main search area
|
||||||
@ -46,6 +50,7 @@ export const useMainContentsController = () => {
|
|||||||
businessCharger: res.data.businessCharger,
|
businessCharger: res.data.businessCharger,
|
||||||
businessChargerMail: res.data.businessChargerMail,
|
businessChargerMail: res.data.businessChargerMail,
|
||||||
})
|
})
|
||||||
|
setIsGlobalLoading(false)
|
||||||
} else {
|
} else {
|
||||||
// setSaleStoreId('')
|
// setSaleStoreId('')
|
||||||
// setSaleStoreName('')
|
// setSaleStoreName('')
|
||||||
|
|||||||
@ -5663,7 +5663,7 @@ react-datepicker@^7.3.0:
|
|||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
react-onclickoutside "^6.13.0"
|
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"
|
version "18.3.1"
|
||||||
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
||||||
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
|
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
|
||||||
@ -5747,6 +5747,11 @@ react-select@^5.8.1:
|
|||||||
react-transition-group "^4.3.0"
|
react-transition-group "^4.3.0"
|
||||||
use-isomorphic-layout-effect "^1.1.2"
|
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:
|
react-style-singleton@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz"
|
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"
|
loose-envify "^1.4.0"
|
||||||
prop-types "^15.6.2"
|
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"
|
version "18.3.1"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
|
||||||
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
|
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user