diff --git a/web/app/components/signin/__tests__/countdown.spec.tsx b/web/app/components/signin/__tests__/countdown.spec.tsx index abd89686f17..2679cdb553b 100644 --- a/web/app/components/signin/__tests__/countdown.spec.tsx +++ b/web/app/components/signin/__tests__/countdown.spec.tsx @@ -1,4 +1,6 @@ -import { act, fireEvent, render, screen } from '@testing-library/react' +import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' +import { hydrateRoot } from 'react-dom/client' +import { renderToString } from 'react-dom/server' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import Countdown from '../countdown' import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '../storage' @@ -46,6 +48,26 @@ describe('Countdown', () => { // State Management Tests describe('State Management', () => { + it('should render stored countdown time after hydrating server markup', async () => { + vi.useRealTimers() + const savedTime = 30000 + localStorage.setItem(COUNT_DOWN_KEY, String(savedTime)) + const container = document.createElement('div') + container.innerHTML = renderToString() + const root = hydrateRoot(container, ) + + try { + await waitFor(() => { + expect(container).toHaveTextContent('30') + }) + } + finally { + act(() => { + root.unmount() + }) + } + }) + it('should initialize leftTime from localStorage if available', () => { const savedTime = 45000 localStorage.setItem(COUNT_DOWN_KEY, String(savedTime)) diff --git a/web/app/components/signin/countdown.tsx b/web/app/components/signin/countdown.tsx index 54c22262d7e..1d5ea4ae46f 100644 --- a/web/app/components/signin/countdown.tsx +++ b/web/app/components/signin/countdown.tsx @@ -1,6 +1,7 @@ 'use client' import { useCountDown } from 'ahooks' -import { useEffect, useState } from 'react' +import { useIsClient } from 'foxact/use-is-client' +import { Suspense, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { COUNT_DOWN_TIME_MS, useCountdownLeftTimeValue, useSetCountdownLeftTime } from './storage' @@ -9,6 +10,29 @@ type CountdownProps = { } export default function Countdown({ onResend }: CountdownProps) { + const isClient = useIsClient() + + if (!isClient) + return + + return ( + }> + + + ) +} + +function CountdownFallback() { + const { t } = useTranslation() + + return ( +

+ {t('checkCode.didNotReceiveCode', { ns: 'login' })} +

+ ) +} + +function CountdownContent({ onResend }: CountdownProps) { const { t } = useTranslation() const storedLeftTime = useCountdownLeftTimeValue() const setStoredLeftTime = useSetCountdownLeftTime()