99 lines
2.6 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { AppProps } from 'next/app';
import { Toaster } from 'react-hot-toast';
import { supabase } from '../lib/supabase';
import { User } from '@supabase/supabase-js';
import '../styles/globals.css';
export default function App({ Component, pageProps }: AppProps) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const router = useRouter();
useEffect(() => {
// 检查是否为演示模式
const isDemoMode = !process.env.NEXT_PUBLIC_SUPABASE_URL ||
process.env.NEXT_PUBLIC_SUPABASE_URL === 'https://demo.supabase.co' ||
process.env.NEXT_PUBLIC_SUPABASE_URL === '';
const checkUser = async () => {
try {
if (isDemoMode) {
// 演示模式下不检查用户认证
setUser(null);
setLoading(false);
return;
}
const { data: { user } } = await supabase.auth.getUser();
setUser(user);
} catch (error) {
console.error('Auth check error:', error);
setUser(null);
} finally {
setLoading(false);
}
};
checkUser();
if (!isDemoMode) {
// 只在非演示模式下监听认证状态变化
const { data: { subscription } } = supabase.auth.onAuthStateChange(
async (event: any, session: any) => {
setUser(session?.user ?? null);
if (event === 'SIGNED_OUT' || !session?.user) {
router.push('/auth/login');
} else if (event === 'SIGNED_IN' && session?.user) {
router.push('/dashboard');
}
}
);
return () => {
subscription.unsubscribe();
};
}
}, [router]);
// 显示加载状态
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<div className="loading-spinner"></div>
</div>
);
}
return (
<>
<Component {...pageProps} user={user} />
<Toaster
position="top-right"
toastOptions={{
duration: 4000,
style: {
background: '#363636',
color: '#fff',
},
success: {
duration: 3000,
iconTheme: {
primary: '#10b981',
secondary: '#fff',
},
},
error: {
duration: 5000,
iconTheme: {
primary: '#ef4444',
secondary: '#fff',
},
},
}}
/>
</>
);
}