mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 10:27:49 +00:00
fix: auto-reload on stale chunk errors after deploy
When a new build changes chunk hashes, users with cached index.html get "Failed to fetch dynamically imported module" errors. Now: - lazyWithRetry() wraps all lazy imports with auto-reload on failure - ErrorBoundary catches chunk errors and auto-reloads once - 30s guard in sessionStorage prevents reload loops
This commit is contained in:
211
src/App.tsx
211
src/App.tsx
@@ -1,6 +1,25 @@
|
|||||||
import { lazy, Suspense } from 'react';
|
import { lazy, Suspense, type ComponentType } from 'react';
|
||||||
import { Routes, Route, Navigate, useLocation, useParams } from 'react-router';
|
import { Routes, Route, Navigate, useLocation, useParams } from 'react-router';
|
||||||
import { useAuthStore } from './store/auth';
|
import { useAuthStore } from './store/auth';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around React.lazy that auto-reloads the page when a chunk fails to load
|
||||||
|
* (e.g. after a new deploy with different chunk hashes).
|
||||||
|
*/
|
||||||
|
function lazyWithRetry<T extends ComponentType<unknown>>(factory: () => Promise<{ default: T }>) {
|
||||||
|
return lazy(() =>
|
||||||
|
factory().catch(() => {
|
||||||
|
const key = 'chunk_reload_ts';
|
||||||
|
const last = Number(sessionStorage.getItem(key) || '0');
|
||||||
|
if (Date.now() - last > 30_000) {
|
||||||
|
sessionStorage.setItem(key, String(Date.now()));
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
// Re-throw so ErrorBoundary catches it if reload guard prevents loop
|
||||||
|
return factory();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
import { useBlockingStore } from './store/blocking';
|
import { useBlockingStore } from './store/blocking';
|
||||||
import Layout from './components/layout/Layout';
|
import Layout from './components/layout/Layout';
|
||||||
import PageLoader from './components/common/PageLoader';
|
import PageLoader from './components/common/PageLoader';
|
||||||
@@ -26,103 +45,107 @@ import OAuthCallback from './pages/OAuthCallback';
|
|||||||
import Dashboard from './pages/Dashboard';
|
import Dashboard from './pages/Dashboard';
|
||||||
|
|
||||||
// User pages - lazy load
|
// User pages - lazy load
|
||||||
const Subscriptions = lazy(() => import('./pages/Subscriptions'));
|
const Subscriptions = lazyWithRetry(() => import('./pages/Subscriptions'));
|
||||||
const Subscription = lazy(() => import('./pages/Subscription'));
|
const Subscription = lazyWithRetry(() => import('./pages/Subscription'));
|
||||||
const SubscriptionPurchase = lazy(() => import('./pages/SubscriptionPurchase'));
|
const SubscriptionPurchase = lazyWithRetry(() => import('./pages/SubscriptionPurchase'));
|
||||||
const Balance = lazy(() => import('./pages/Balance'));
|
const Balance = lazyWithRetry(() => import('./pages/Balance'));
|
||||||
const SavedCards = lazy(() => import('./pages/SavedCards'));
|
const SavedCards = lazyWithRetry(() => import('./pages/SavedCards'));
|
||||||
const Referral = lazy(() => import('./pages/Referral'));
|
const Referral = lazyWithRetry(() => import('./pages/Referral'));
|
||||||
const Support = lazy(() => import('./pages/Support'));
|
const Support = lazyWithRetry(() => import('./pages/Support'));
|
||||||
const Profile = lazy(() => import('./pages/Profile'));
|
const Profile = lazyWithRetry(() => import('./pages/Profile'));
|
||||||
const Contests = lazy(() => import('./pages/Contests'));
|
const Contests = lazyWithRetry(() => import('./pages/Contests'));
|
||||||
const Polls = lazy(() => import('./pages/Polls'));
|
const Polls = lazyWithRetry(() => import('./pages/Polls'));
|
||||||
const Info = lazy(() => import('./pages/Info'));
|
const Info = lazyWithRetry(() => import('./pages/Info'));
|
||||||
const Wheel = lazy(() => import('./pages/Wheel'));
|
const Wheel = lazyWithRetry(() => import('./pages/Wheel'));
|
||||||
const GiftSubscription = lazy(() => import('./pages/GiftSubscription'));
|
const GiftSubscription = lazyWithRetry(() => import('./pages/GiftSubscription'));
|
||||||
const GiftResult = lazy(() => import('./pages/GiftResult'));
|
const GiftResult = lazyWithRetry(() => import('./pages/GiftResult'));
|
||||||
const Connection = lazy(() => import('./pages/Connection'));
|
const Connection = lazyWithRetry(() => import('./pages/Connection'));
|
||||||
const ConnectionQR = lazy(() => import('./pages/ConnectionQR'));
|
const ConnectionQR = lazyWithRetry(() => import('./pages/ConnectionQR'));
|
||||||
const QuickPurchase = lazy(() => import('./pages/QuickPurchase'));
|
const QuickPurchase = lazyWithRetry(() => import('./pages/QuickPurchase'));
|
||||||
const PurchaseSuccess = lazy(() => import('./pages/PurchaseSuccess'));
|
const PurchaseSuccess = lazyWithRetry(() => import('./pages/PurchaseSuccess'));
|
||||||
const RenewSubscription = lazy(() => import('./pages/RenewSubscription'));
|
const RenewSubscription = lazyWithRetry(() => import('./pages/RenewSubscription'));
|
||||||
const AutoLogin = lazy(() => import('./pages/AutoLogin'));
|
const AutoLogin = lazyWithRetry(() => import('./pages/AutoLogin'));
|
||||||
const TopUpMethodSelect = lazy(() => import('./pages/TopUpMethodSelect'));
|
const TopUpMethodSelect = lazyWithRetry(() => import('./pages/TopUpMethodSelect'));
|
||||||
const TopUpAmount = lazy(() => import('./pages/TopUpAmount'));
|
const TopUpAmount = lazyWithRetry(() => import('./pages/TopUpAmount'));
|
||||||
const TopUpResult = lazy(() => import('./pages/TopUpResult'));
|
const TopUpResult = lazyWithRetry(() => import('./pages/TopUpResult'));
|
||||||
const ConnectedAccounts = lazy(() => import('./pages/ConnectedAccounts'));
|
const ConnectedAccounts = lazyWithRetry(() => import('./pages/ConnectedAccounts'));
|
||||||
const LinkTelegramCallback = lazy(() => import('./pages/LinkTelegramCallback'));
|
const LinkTelegramCallback = lazyWithRetry(() => import('./pages/LinkTelegramCallback'));
|
||||||
const MergeAccounts = lazy(() => import('./pages/MergeAccounts'));
|
const MergeAccounts = lazyWithRetry(() => import('./pages/MergeAccounts'));
|
||||||
|
|
||||||
// Admin pages - lazy load (only for admins)
|
// Admin pages - lazy load (only for admins)
|
||||||
const AdminPanel = lazy(() => import('./pages/AdminPanel'));
|
const AdminPanel = lazyWithRetry(() => import('./pages/AdminPanel'));
|
||||||
const AdminTickets = lazy(() => import('./pages/AdminTickets'));
|
const AdminTickets = lazyWithRetry(() => import('./pages/AdminTickets'));
|
||||||
const AdminTicketSettings = lazy(() => import('./pages/AdminTicketSettings'));
|
const AdminTicketSettings = lazyWithRetry(() => import('./pages/AdminTicketSettings'));
|
||||||
const AdminSettings = lazy(() => import('./pages/AdminSettings'));
|
const AdminSettings = lazyWithRetry(() => import('./pages/AdminSettings'));
|
||||||
const AdminApps = lazy(() => import('./pages/AdminApps'));
|
const AdminApps = lazyWithRetry(() => import('./pages/AdminApps'));
|
||||||
const AdminWheel = lazy(() => import('./pages/AdminWheel'));
|
const AdminWheel = lazyWithRetry(() => import('./pages/AdminWheel'));
|
||||||
const AdminTariffs = lazy(() => import('./pages/AdminTariffs'));
|
const AdminTariffs = lazyWithRetry(() => import('./pages/AdminTariffs'));
|
||||||
const AdminTariffCreate = lazy(() => import('./pages/AdminTariffCreate'));
|
const AdminTariffCreate = lazyWithRetry(() => import('./pages/AdminTariffCreate'));
|
||||||
const AdminServers = lazy(() => import('./pages/AdminServers'));
|
const AdminServers = lazyWithRetry(() => import('./pages/AdminServers'));
|
||||||
const AdminServerEdit = lazy(() => import('./pages/AdminServerEdit'));
|
const AdminServerEdit = lazyWithRetry(() => import('./pages/AdminServerEdit'));
|
||||||
const AdminDashboard = lazy(() => import('./pages/AdminDashboard'));
|
const AdminDashboard = lazyWithRetry(() => import('./pages/AdminDashboard'));
|
||||||
const AdminBanSystem = lazy(() => import('./pages/AdminBanSystem'));
|
const AdminBanSystem = lazyWithRetry(() => import('./pages/AdminBanSystem'));
|
||||||
const AdminBroadcasts = lazy(() => import('./pages/AdminBroadcasts'));
|
const AdminBroadcasts = lazyWithRetry(() => import('./pages/AdminBroadcasts'));
|
||||||
const AdminBroadcastCreate = lazy(() => import('./pages/AdminBroadcastCreate'));
|
const AdminBroadcastCreate = lazyWithRetry(() => import('./pages/AdminBroadcastCreate'));
|
||||||
const AdminPromocodes = lazy(() => import('./pages/AdminPromocodes'));
|
const AdminPromocodes = lazyWithRetry(() => import('./pages/AdminPromocodes'));
|
||||||
const AdminPromocodeCreate = lazy(() => import('./pages/AdminPromocodeCreate'));
|
const AdminPromocodeCreate = lazyWithRetry(() => import('./pages/AdminPromocodeCreate'));
|
||||||
const AdminPromocodeStats = lazy(() => import('./pages/AdminPromocodeStats'));
|
const AdminPromocodeStats = lazyWithRetry(() => import('./pages/AdminPromocodeStats'));
|
||||||
const AdminPromoGroups = lazy(() => import('./pages/AdminPromoGroups'));
|
const AdminPromoGroups = lazyWithRetry(() => import('./pages/AdminPromoGroups'));
|
||||||
const AdminPromoGroupCreate = lazy(() => import('./pages/AdminPromoGroupCreate'));
|
const AdminPromoGroupCreate = lazyWithRetry(() => import('./pages/AdminPromoGroupCreate'));
|
||||||
const AdminCampaigns = lazy(() => import('./pages/AdminCampaigns'));
|
const AdminCampaigns = lazyWithRetry(() => import('./pages/AdminCampaigns'));
|
||||||
const AdminCampaignCreate = lazy(() => import('./pages/AdminCampaignCreate'));
|
const AdminCampaignCreate = lazyWithRetry(() => import('./pages/AdminCampaignCreate'));
|
||||||
const AdminCampaignStats = lazy(() => import('./pages/AdminCampaignStats'));
|
const AdminCampaignStats = lazyWithRetry(() => import('./pages/AdminCampaignStats'));
|
||||||
const AdminCampaignEdit = lazy(() => import('./pages/AdminCampaignEdit'));
|
const AdminCampaignEdit = lazyWithRetry(() => import('./pages/AdminCampaignEdit'));
|
||||||
const AdminPartners = lazy(() => import('./pages/AdminPartners'));
|
const AdminPartners = lazyWithRetry(() => import('./pages/AdminPartners'));
|
||||||
const AdminPartnerSettings = lazy(() => import('./pages/AdminPartnerSettings'));
|
const AdminPartnerSettings = lazyWithRetry(() => import('./pages/AdminPartnerSettings'));
|
||||||
const AdminPartnerDetail = lazy(() => import('./pages/AdminPartnerDetail'));
|
const AdminPartnerDetail = lazyWithRetry(() => import('./pages/AdminPartnerDetail'));
|
||||||
const AdminApplicationReview = lazy(() => import('./pages/AdminApplicationReview'));
|
const AdminApplicationReview = lazyWithRetry(() => import('./pages/AdminApplicationReview'));
|
||||||
const AdminPartnerCommission = lazy(() => import('./pages/AdminPartnerCommission'));
|
const AdminPartnerCommission = lazyWithRetry(() => import('./pages/AdminPartnerCommission'));
|
||||||
const AdminPartnerRevoke = lazy(() => import('./pages/AdminPartnerRevoke'));
|
const AdminPartnerRevoke = lazyWithRetry(() => import('./pages/AdminPartnerRevoke'));
|
||||||
const AdminPartnerCampaignAssign = lazy(() => import('./pages/AdminPartnerCampaignAssign'));
|
const AdminPartnerCampaignAssign = lazyWithRetry(
|
||||||
const AdminWithdrawals = lazy(() => import('./pages/AdminWithdrawals'));
|
() => import('./pages/AdminPartnerCampaignAssign'),
|
||||||
const AdminWithdrawalDetail = lazy(() => import('./pages/AdminWithdrawalDetail'));
|
);
|
||||||
const AdminWithdrawalReject = lazy(() => import('./pages/AdminWithdrawalReject'));
|
const AdminWithdrawals = lazyWithRetry(() => import('./pages/AdminWithdrawals'));
|
||||||
const ReferralPartnerApply = lazy(() => import('./pages/ReferralPartnerApply'));
|
const AdminWithdrawalDetail = lazyWithRetry(() => import('./pages/AdminWithdrawalDetail'));
|
||||||
const ReferralWithdrawalRequest = lazy(() => import('./pages/ReferralWithdrawalRequest'));
|
const AdminWithdrawalReject = lazyWithRetry(() => import('./pages/AdminWithdrawalReject'));
|
||||||
const AdminUsers = lazy(() => import('./pages/AdminUsers'));
|
const ReferralPartnerApply = lazyWithRetry(() => import('./pages/ReferralPartnerApply'));
|
||||||
const AdminPayments = lazy(() => import('./pages/AdminPayments'));
|
const ReferralWithdrawalRequest = lazyWithRetry(() => import('./pages/ReferralWithdrawalRequest'));
|
||||||
const AdminPaymentMethods = lazy(() => import('./pages/AdminPaymentMethods'));
|
const AdminUsers = lazyWithRetry(() => import('./pages/AdminUsers'));
|
||||||
const AdminPaymentMethodEdit = lazy(() => import('./pages/AdminPaymentMethodEdit'));
|
const AdminPayments = lazyWithRetry(() => import('./pages/AdminPayments'));
|
||||||
const AdminPromoOffers = lazy(() => import('./pages/AdminPromoOffers'));
|
const AdminPaymentMethods = lazyWithRetry(() => import('./pages/AdminPaymentMethods'));
|
||||||
const AdminPromoOfferTemplateEdit = lazy(() => import('./pages/AdminPromoOfferTemplateEdit'));
|
const AdminPaymentMethodEdit = lazyWithRetry(() => import('./pages/AdminPaymentMethodEdit'));
|
||||||
const AdminPromoOfferSend = lazy(() => import('./pages/AdminPromoOfferSend'));
|
const AdminPromoOffers = lazyWithRetry(() => import('./pages/AdminPromoOffers'));
|
||||||
const AdminRemnawave = lazy(() => import('./pages/AdminRemnawave'));
|
const AdminPromoOfferTemplateEdit = lazyWithRetry(
|
||||||
const AdminRemnawaveSquadDetail = lazy(() => import('./pages/AdminRemnawaveSquadDetail'));
|
() => import('./pages/AdminPromoOfferTemplateEdit'),
|
||||||
const AdminEmailTemplates = lazy(() => import('./pages/AdminEmailTemplates'));
|
);
|
||||||
const AdminTrafficUsage = lazy(() => import('./pages/AdminTrafficUsage'));
|
const AdminPromoOfferSend = lazyWithRetry(() => import('./pages/AdminPromoOfferSend'));
|
||||||
const AdminSalesStats = lazy(() => import('./pages/AdminSalesStats'));
|
const AdminRemnawave = lazyWithRetry(() => import('./pages/AdminRemnawave'));
|
||||||
const AdminUpdates = lazy(() => import('./pages/AdminUpdates'));
|
const AdminRemnawaveSquadDetail = lazyWithRetry(() => import('./pages/AdminRemnawaveSquadDetail'));
|
||||||
const AdminUserDetail = lazy(() => import('./pages/AdminUserDetail'));
|
const AdminEmailTemplates = lazyWithRetry(() => import('./pages/AdminEmailTemplates'));
|
||||||
const AdminBroadcastDetail = lazy(() => import('./pages/AdminBroadcastDetail'));
|
const AdminTrafficUsage = lazyWithRetry(() => import('./pages/AdminTrafficUsage'));
|
||||||
const AdminPinnedMessages = lazy(() => import('./pages/AdminPinnedMessages'));
|
const AdminSalesStats = lazyWithRetry(() => import('./pages/AdminSalesStats'));
|
||||||
const AdminPinnedMessageCreate = lazy(() => import('./pages/AdminPinnedMessageCreate'));
|
const AdminUpdates = lazyWithRetry(() => import('./pages/AdminUpdates'));
|
||||||
const AdminChannelSubscriptions = lazy(() => import('./pages/AdminChannelSubscriptions'));
|
const AdminUserDetail = lazyWithRetry(() => import('./pages/AdminUserDetail'));
|
||||||
const AdminEmailTemplatePreview = lazy(() => import('./pages/AdminEmailTemplatePreview'));
|
const AdminBroadcastDetail = lazyWithRetry(() => import('./pages/AdminBroadcastDetail'));
|
||||||
const AdminRoles = lazy(() => import('./pages/AdminRoles'));
|
const AdminPinnedMessages = lazyWithRetry(() => import('./pages/AdminPinnedMessages'));
|
||||||
const AdminRoleEdit = lazy(() => import('./pages/AdminRoleEdit'));
|
const AdminPinnedMessageCreate = lazyWithRetry(() => import('./pages/AdminPinnedMessageCreate'));
|
||||||
const AdminRoleAssign = lazy(() => import('./pages/AdminRoleAssign'));
|
const AdminChannelSubscriptions = lazyWithRetry(() => import('./pages/AdminChannelSubscriptions'));
|
||||||
const AdminPolicies = lazy(() => import('./pages/AdminPolicies'));
|
const AdminEmailTemplatePreview = lazyWithRetry(() => import('./pages/AdminEmailTemplatePreview'));
|
||||||
const AdminPolicyEdit = lazy(() => import('./pages/AdminPolicyEdit'));
|
const AdminRoles = lazyWithRetry(() => import('./pages/AdminRoles'));
|
||||||
const AdminAuditLog = lazy(() => import('./pages/AdminAuditLog'));
|
const AdminRoleEdit = lazyWithRetry(() => import('./pages/AdminRoleEdit'));
|
||||||
const AdminLandings = lazy(() => import('./pages/AdminLandings'));
|
const AdminRoleAssign = lazyWithRetry(() => import('./pages/AdminRoleAssign'));
|
||||||
const AdminLandingEditor = lazy(() => import('./pages/AdminLandingEditor'));
|
const AdminPolicies = lazyWithRetry(() => import('./pages/AdminPolicies'));
|
||||||
const AdminLandingStats = lazy(() => import('./pages/AdminLandingStats'));
|
const AdminPolicyEdit = lazyWithRetry(() => import('./pages/AdminPolicyEdit'));
|
||||||
const AdminReferralNetwork = lazy(() => import('./pages/ReferralNetwork'));
|
const AdminAuditLog = lazyWithRetry(() => import('./pages/AdminAuditLog'));
|
||||||
|
const AdminLandings = lazyWithRetry(() => import('./pages/AdminLandings'));
|
||||||
|
const AdminLandingEditor = lazyWithRetry(() => import('./pages/AdminLandingEditor'));
|
||||||
|
const AdminLandingStats = lazyWithRetry(() => import('./pages/AdminLandingStats'));
|
||||||
|
const AdminReferralNetwork = lazyWithRetry(() => import('./pages/ReferralNetwork'));
|
||||||
|
|
||||||
// News pages
|
// News pages
|
||||||
const NewsArticlePage = lazy(() => import('./pages/NewsArticle'));
|
const NewsArticlePage = lazyWithRetry(() => import('./pages/NewsArticle'));
|
||||||
const AdminNews = lazy(() => import('./pages/AdminNews'));
|
const AdminNews = lazyWithRetry(() => import('./pages/AdminNews'));
|
||||||
const AdminNewsCreate = lazy(() => import('./pages/AdminNewsCreate'));
|
const AdminNewsCreate = lazyWithRetry(() => import('./pages/AdminNewsCreate'));
|
||||||
|
|
||||||
function ProtectedRoute({
|
function ProtectedRoute({
|
||||||
children,
|
children,
|
||||||
|
|||||||
@@ -11,6 +11,18 @@ interface ErrorBoundaryState {
|
|||||||
error: Error | null;
|
error: Error | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isChunkLoadError(error: Error): boolean {
|
||||||
|
const msg = error.message || '';
|
||||||
|
return (
|
||||||
|
msg.includes('dynamically imported module') ||
|
||||||
|
msg.includes('Importing a module script failed') ||
|
||||||
|
msg.includes('Failed to fetch dynamically imported module') ||
|
||||||
|
msg.includes('Loading chunk') ||
|
||||||
|
msg.includes('ChunkLoadError') ||
|
||||||
|
error.name === 'ChunkLoadError'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
||||||
constructor(props: ErrorBoundaryProps) {
|
constructor(props: ErrorBoundaryProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -23,6 +35,19 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
|
|||||||
|
|
||||||
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||||
console.error('[ErrorBoundary]', error, errorInfo);
|
console.error('[ErrorBoundary]', error, errorInfo);
|
||||||
|
|
||||||
|
// Auto-reload on chunk load failures (stale deploy)
|
||||||
|
if (isChunkLoadError(error)) {
|
||||||
|
const reloadKey = 'chunk_reload_ts';
|
||||||
|
const lastReload = Number(sessionStorage.getItem(reloadKey) || '0');
|
||||||
|
const now = Date.now();
|
||||||
|
// Prevent reload loop — only auto-reload once per 30 seconds
|
||||||
|
if (now - lastReload > 30_000) {
|
||||||
|
sessionStorage.setItem(reloadKey, String(now));
|
||||||
|
window.location.reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleReset = () => {
|
handleReset = () => {
|
||||||
@@ -36,6 +61,7 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { level = 'page' } = this.props;
|
const { level = 'page' } = this.props;
|
||||||
|
const isChunk = this.state.error ? isChunkLoadError(this.state.error) : false;
|
||||||
|
|
||||||
if (level === 'app') {
|
if (level === 'app') {
|
||||||
return (
|
return (
|
||||||
@@ -78,13 +104,15 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
|
|||||||
<div className="mb-4 text-4xl">⚠️</div>
|
<div className="mb-4 text-4xl">⚠️</div>
|
||||||
<h1 className="mb-2 text-xl font-bold text-dark-50">Something went wrong</h1>
|
<h1 className="mb-2 text-xl font-bold text-dark-50">Something went wrong</h1>
|
||||||
<p className="mb-6 text-sm text-dark-400">
|
<p className="mb-6 text-sm text-dark-400">
|
||||||
{this.state.error?.message || 'An unexpected error occurred'}
|
{isChunk
|
||||||
|
? 'App was updated. Reloading...'
|
||||||
|
: this.state.error?.message || 'An unexpected error occurred'}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
onClick={this.handleReset}
|
onClick={() => window.location.reload()}
|
||||||
className="rounded-xl bg-accent-500 px-6 py-3 font-medium text-white transition-colors hover:bg-accent-600"
|
className="rounded-xl bg-accent-500 px-6 py-3 font-medium text-white transition-colors hover:bg-accent-600"
|
||||||
>
|
>
|
||||||
Try again
|
{isChunk ? 'Reload' : 'Try again'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user