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:
@@ -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
49
lib/api.ts
Normal 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();
|
||||||
|
}
|
||||||
45
lib/auth.tsx
45
lib/auth.tsx
@@ -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 (
|
||||||
|
|||||||
Reference in New Issue
Block a user