Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

authenticated-layout.tsx 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. 'use client'
  2. import AppUnavailable from '@/app/components/base/app-unavailable'
  3. import Loading from '@/app/components/base/loading'
  4. import { removeAccessToken } from '@/app/components/share/utils'
  5. import { useWebAppStore } from '@/context/web-app-context'
  6. import { useGetUserCanAccessApp } from '@/service/access-control'
  7. import { useGetWebAppInfo, useGetWebAppMeta, useGetWebAppParams } from '@/service/use-share'
  8. import { usePathname, useRouter, useSearchParams } from 'next/navigation'
  9. import React, { useCallback, useEffect } from 'react'
  10. import { useTranslation } from 'react-i18next'
  11. const AuthenticatedLayout = ({ children }: { children: React.ReactNode }) => {
  12. const { t } = useTranslation()
  13. const updateAppInfo = useWebAppStore(s => s.updateAppInfo)
  14. const updateAppParams = useWebAppStore(s => s.updateAppParams)
  15. const updateWebAppMeta = useWebAppStore(s => s.updateWebAppMeta)
  16. const updateUserCanAccessApp = useWebAppStore(s => s.updateUserCanAccessApp)
  17. const { isFetching: isFetchingAppParams, data: appParams, error: appParamsError } = useGetWebAppParams()
  18. const { isFetching: isFetchingAppInfo, data: appInfo, error: appInfoError } = useGetWebAppInfo()
  19. const { isFetching: isFetchingAppMeta, data: appMeta, error: appMetaError } = useGetWebAppMeta()
  20. const { data: userCanAccessApp, error: useCanAccessAppError } = useGetUserCanAccessApp({ appId: appInfo?.app_id, isInstalledApp: false })
  21. useEffect(() => {
  22. if (appInfo)
  23. updateAppInfo(appInfo)
  24. if (appParams)
  25. updateAppParams(appParams)
  26. if (appMeta)
  27. updateWebAppMeta(appMeta)
  28. updateUserCanAccessApp(Boolean(userCanAccessApp && userCanAccessApp?.result))
  29. }, [appInfo, appMeta, appParams, updateAppInfo, updateAppParams, updateUserCanAccessApp, updateWebAppMeta, userCanAccessApp])
  30. const router = useRouter()
  31. const pathname = usePathname()
  32. const searchParams = useSearchParams()
  33. const getSigninUrl = useCallback(() => {
  34. const params = new URLSearchParams(searchParams)
  35. params.delete('message')
  36. params.set('redirect_url', pathname)
  37. return `/webapp-signin?${params.toString()}`
  38. }, [searchParams, pathname])
  39. const backToHome = useCallback(() => {
  40. removeAccessToken()
  41. const url = getSigninUrl()
  42. router.replace(url)
  43. }, [getSigninUrl, router])
  44. if (appInfoError) {
  45. return <div className='flex h-full items-center justify-center'>
  46. <AppUnavailable unknownReason={appInfoError.message} />
  47. </div>
  48. }
  49. if (appParamsError) {
  50. return <div className='flex h-full items-center justify-center'>
  51. <AppUnavailable unknownReason={appParamsError.message} />
  52. </div>
  53. }
  54. if (appMetaError) {
  55. return <div className='flex h-full items-center justify-center'>
  56. <AppUnavailable unknownReason={appMetaError.message} />
  57. </div>
  58. }
  59. if (useCanAccessAppError) {
  60. return <div className='flex h-full items-center justify-center'>
  61. <AppUnavailable unknownReason={useCanAccessAppError.message} />
  62. </div>
  63. }
  64. if (userCanAccessApp && !userCanAccessApp.result) {
  65. return <div className='flex h-full flex-col items-center justify-center gap-y-2'>
  66. <AppUnavailable className='h-auto w-auto' code={403} unknownReason='no permission.' />
  67. <span className='system-sm-regular cursor-pointer text-text-tertiary' onClick={backToHome}>{t('common.userProfile.logout')}</span>
  68. </div>
  69. }
  70. if (isFetchingAppInfo || isFetchingAppParams || isFetchingAppMeta) {
  71. return <div className='flex h-full items-center justify-center'>
  72. <Loading />
  73. </div>
  74. }
  75. return <>{children}</>
  76. }
  77. export default React.memo(AuthenticatedLayout)