mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-13 07:46:54 +08:00
feat: add ESLint and Prettier with pre-commit hook
- Install ESLint 9 with TypeScript and React support - Install Prettier with custom configuration (no semicolons) - Add husky and lint-staged for pre-commit hooks - Configure lint-staged to auto-fix and format on commit - Relax ESLint rules to avoid large-scale code changes - Format all existing code with Prettier (no semicolons) Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
@@ -1,62 +1,86 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||
import { getSystemConfig } from '../lib/config';
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react'
|
||||
import { getSystemConfig } from '../lib/config'
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
id: string
|
||||
email: string
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
user: User | null;
|
||||
token: string | null;
|
||||
login: (email: string, password: string) => Promise<{ success: boolean; message?: string; userID?: string; requiresOTP?: boolean }>;
|
||||
register: (email: string, password: string, betaCode?: string) => Promise<{ success: boolean; message?: string; userID?: string; otpSecret?: string; qrCodeURL?: string }>;
|
||||
verifyOTP: (userID: string, otpCode: string) => Promise<{ success: boolean; message?: string }>;
|
||||
completeRegistration: (userID: string, otpCode: string) => Promise<{ success: boolean; message?: string }>;
|
||||
logout: () => void;
|
||||
isLoading: boolean;
|
||||
user: User | null
|
||||
token: string | null
|
||||
login: (
|
||||
email: string,
|
||||
password: string
|
||||
) => Promise<{
|
||||
success: boolean
|
||||
message?: string
|
||||
userID?: string
|
||||
requiresOTP?: boolean
|
||||
}>
|
||||
register: (
|
||||
email: string,
|
||||
password: string,
|
||||
betaCode?: string
|
||||
) => Promise<{
|
||||
success: boolean
|
||||
message?: string
|
||||
userID?: string
|
||||
otpSecret?: string
|
||||
qrCodeURL?: string
|
||||
}>
|
||||
verifyOTP: (
|
||||
userID: string,
|
||||
otpCode: string
|
||||
) => Promise<{ success: boolean; message?: string }>
|
||||
completeRegistration: (
|
||||
userID: string,
|
||||
otpCode: string
|
||||
) => Promise<{ success: boolean; message?: string }>
|
||||
logout: () => void
|
||||
isLoading: boolean
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined)
|
||||
|
||||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [token, setToken] = useState<string | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [user, setUser] = useState<User | null>(null)
|
||||
const [token, setToken] = useState<string | null>(null)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
// 先检查是否为管理员模式(使用带缓存的系统配置获取)
|
||||
getSystemConfig()
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
if (data.admin_mode) {
|
||||
// 管理员模式下,模拟admin用户
|
||||
setUser({ id: 'admin', email: 'admin@localhost' });
|
||||
setToken('admin-mode');
|
||||
setUser({ id: 'admin', email: 'admin@localhost' })
|
||||
setToken('admin-mode')
|
||||
} else {
|
||||
// 非管理员模式,检查本地存储中是否有token
|
||||
const savedToken = localStorage.getItem('auth_token');
|
||||
const savedUser = localStorage.getItem('auth_user');
|
||||
|
||||
const savedToken = localStorage.getItem('auth_token')
|
||||
const savedUser = localStorage.getItem('auth_user')
|
||||
|
||||
if (savedToken && savedUser) {
|
||||
setToken(savedToken);
|
||||
setUser(JSON.parse(savedUser));
|
||||
setToken(savedToken)
|
||||
setUser(JSON.parse(savedUser))
|
||||
}
|
||||
}
|
||||
setIsLoading(false);
|
||||
setIsLoading(false)
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to fetch system config:', err);
|
||||
.catch((err) => {
|
||||
console.error('Failed to fetch system config:', err)
|
||||
// 发生错误时,继续检查本地存储
|
||||
const savedToken = localStorage.getItem('auth_token');
|
||||
const savedUser = localStorage.getItem('auth_user');
|
||||
|
||||
const savedToken = localStorage.getItem('auth_token')
|
||||
const savedUser = localStorage.getItem('auth_user')
|
||||
|
||||
if (savedToken && savedUser) {
|
||||
setToken(savedToken);
|
||||
setUser(JSON.parse(savedUser));
|
||||
setToken(savedToken)
|
||||
setUser(JSON.parse(savedUser))
|
||||
}
|
||||
setIsLoading(false);
|
||||
});
|
||||
}, []);
|
||||
setIsLoading(false)
|
||||
})
|
||||
}, [])
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
try {
|
||||
@@ -66,9 +90,9 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
})
|
||||
|
||||
const data = await response.json();
|
||||
const data = await response.json()
|
||||
|
||||
if (response.ok) {
|
||||
if (data.requires_otp) {
|
||||
@@ -77,23 +101,31 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
userID: data.user_id,
|
||||
requiresOTP: true,
|
||||
message: data.message,
|
||||
};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return { success: false, message: data.error };
|
||||
return { success: false, message: data.error }
|
||||
}
|
||||
} catch (error) {
|
||||
return { success: false, message: '登录失败,请重试' };
|
||||
return { success: false, message: '登录失败,请重试' }
|
||||
}
|
||||
|
||||
return { success: false, message: '未知错误' };
|
||||
};
|
||||
return { success: false, message: '未知错误' }
|
||||
}
|
||||
|
||||
const register = async (email: string, password: string, betaCode?: string) => {
|
||||
const register = async (
|
||||
email: string,
|
||||
password: string,
|
||||
betaCode?: string
|
||||
) => {
|
||||
try {
|
||||
const requestBody: { email: string; password: string; beta_code?: string } = { email, password };
|
||||
const requestBody: {
|
||||
email: string
|
||||
password: string
|
||||
beta_code?: string
|
||||
} = { email, password }
|
||||
if (betaCode) {
|
||||
requestBody.beta_code = betaCode;
|
||||
requestBody.beta_code = betaCode
|
||||
}
|
||||
|
||||
const response = await fetch('/api/register', {
|
||||
@@ -102,9 +134,9 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(requestBody),
|
||||
});
|
||||
})
|
||||
|
||||
const data = await response.json();
|
||||
const data = await response.json()
|
||||
|
||||
if (response.ok) {
|
||||
return {
|
||||
@@ -113,14 +145,14 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
otpSecret: data.otp_secret,
|
||||
qrCodeURL: data.qr_code_url,
|
||||
message: data.message,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return { success: false, message: data.error };
|
||||
return { success: false, message: data.error }
|
||||
}
|
||||
} catch (error) {
|
||||
return { success: false, message: '注册失败,请重试' };
|
||||
return { success: false, message: '注册失败,请重试' }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const verifyOTP = async (userID: string, otpCode: string) => {
|
||||
try {
|
||||
@@ -189,11 +221,11 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
setUser(null);
|
||||
setToken(null);
|
||||
localStorage.removeItem('auth_token');
|
||||
localStorage.removeItem('auth_user');
|
||||
};
|
||||
setUser(null)
|
||||
setToken(null)
|
||||
localStorage.removeItem('auth_token')
|
||||
localStorage.removeItem('auth_user')
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
@@ -210,13 +242,13 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export function useAuth() {
|
||||
const context = useContext(AuthContext);
|
||||
const context = useContext(AuthContext)
|
||||
if (context === undefined) {
|
||||
throw new Error('useAuth must be used within an AuthProvider');
|
||||
throw new Error('useAuth must be used within an AuthProvider')
|
||||
}
|
||||
return context;
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user