Add limqRequest function for API interactions and implement default team creation in TeamSelector. Remove test user auto-registration from AuthProvider.

This commit is contained in:
2025-04-22 13:07:08 +08:00
parent ed1d2e59f6
commit 05af4aae70
3 changed files with 64 additions and 39 deletions

View File

@@ -7,6 +7,7 @@ import { getSupabaseClient } from '../../utils/supabase';
import { AuthChangeEvent, Session } from '@supabase/supabase-js'; import { AuthChangeEvent, Session } from '@supabase/supabase-js';
import { Loader2, X, Check } from 'lucide-react'; import { Loader2, X, Check } from 'lucide-react';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { limqRequest } from '@/lib/api';
type Team = Database['limq']['Tables']['teams']['Row']; type Team = Database['limq']['Tables']['teams']['Row'];
@@ -69,6 +70,14 @@ export function TeamSelector({
try { try {
const supabase = getSupabaseClient(); const supabase = getSupabaseClient();
// 尝试创建默认团队和项目(如果用户还没有)
try {
const response = await limqRequest('team/create-default', 'POST');
console.log('Default team creation response:', response);
} catch (teamError) {
console.error('Error creating default team:', teamError);
}
const { data: memberships, error: membershipError } = await supabase const { data: memberships, error: membershipError } = await supabase
.from('team_membership') .from('team_membership')

49
lib/api.ts Normal file
View File

@@ -0,0 +1,49 @@
import supabase from './supabase';
// Define response type for API
export interface ApiResponse<T = unknown> {
success: boolean;
data?: T;
error?: string;
message?: string;
}
// Common function for authenticated API requests to LIMQ
export async function limqRequest<T = unknown>(
endpoint: string,
method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET',
data?: Record<string, unknown>
): Promise<ApiResponse<T>> {
// Get current session
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
throw new Error('No active session. User must be authenticated.');
}
const baseUrl = process.env.NEXT_PUBLIC_LIMQ_API || 'http://localhost:3005';
const url = `${baseUrl}${endpoint.startsWith('/') ? endpoint : '/' + endpoint}`;
const options: RequestInit = {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${session.access_token}`
}
};
if (data && (method === 'POST' || method === 'PUT')) {
options.body = JSON.stringify(data);
}
const response = await fetch(url, options);
if (!response.ok) {
const errorData = await response.json().catch(() => null);
throw new Error(
errorData?.error || `Request failed with status ${response.status}`
);
}
return response.json();
}

View File

@@ -4,6 +4,7 @@ import React, { createContext, useContext, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { Session, User } from '@supabase/supabase-js'; import { Session, User } from '@supabase/supabase-js';
import supabase from './supabase'; import supabase from './supabase';
import { limqRequest } from './api';
// 定义用户类型 // 定义用户类型
export type AuthUser = User | null; export type AuthUser = User | null;
@@ -13,21 +14,16 @@ export type AuthContextType = {
user: AuthUser; user: AuthUser;
session: Session | null; session: Session | null;
isLoading: boolean; isLoading: boolean;
signIn: (email: string, password: string) => Promise<{ error?: any }>; signIn: (email: string, password: string) => Promise<{ error?: unknown }>;
signInWithGoogle: () => Promise<{ error?: any }>; signInWithGoogle: () => Promise<{ error?: unknown }>;
signInWithGitHub: () => Promise<{ error?: any }>; signInWithGitHub: () => Promise<{ error?: unknown }>;
signUp: (email: string, password: string) => Promise<void>; signUp: (email: string, password: string) => Promise<void>;
signOut: () => Promise<void>; signOut: () => Promise<void>;
autoRegisterTestUser: () => Promise<void>; // 添加自动注册测试用户函数
}; };
// 创建验证上下文 // 创建验证上下文
const AuthContext = createContext<AuthContextType | undefined>(undefined); const AuthContext = createContext<AuthContextType | undefined>(undefined);
// 测试账户常量 - 使用已验证的账户
const TEST_EMAIL = 'vitalitymailg@gmail.com';
const TEST_PASSWORD = 'password123';
// 验证提供者组件 // 验证提供者组件
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState<AuthUser>(null); const [user, setUser] = useState<AuthUser>(null);
@@ -90,7 +86,8 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
setSession(data.session); setSession(data.session);
setUser(data.user); setUser(data.user);
router.push('/dashboard');
router.push('/analytics');
return {}; return {};
} catch (error) { } catch (error) {
console.error('登录过程出错:', error); console.error('登录过程出错:', error);
@@ -201,35 +198,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
} }
}; };
// 自动注册测试用户函数
const autoRegisterTestUser = async () => {
setIsLoading(true);
try {
console.log('正在使用测试账户登录:', TEST_EMAIL);
// 使用测试账户直接登录
const { data, error } = await supabase.auth.signInWithPassword({
email: TEST_EMAIL,
password: TEST_PASSWORD,
});
if (error) {
console.error('测试账户登录失败:', error);
throw error;
}
console.log('测试账户登录成功!');
setSession(data.session);
setUser(data.user);
router.push('/dashboard');
} catch (error) {
console.error('测试账户登录出错:', error);
throw error;
} finally {
setIsLoading(false);
}
};
const contextValue: AuthContextType = { const contextValue: AuthContextType = {
user, user,
session, session,
@@ -239,7 +207,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
signInWithGitHub, signInWithGitHub,
signUp, signUp,
signOut, signOut,
autoRegisterTestUser,
}; };
return ( return (