Your Name e4959d584f feat: 完善代理商端业务逻辑与前后端框架
主要更新:
- 更新代理商端文档,明确项目由品牌方分配流程
- 新增Brief配置详情页(已配置)设计稿
- 完善工作台紧急待办中品牌新任务功能
- 整理Pencil设计文件中代理商端页面顺序
- 新增后端FastAPI框架及核心API
- 新增前端Next.js页面和组件库
- 添加.gitignore排除构建和缓存文件

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 19:27:31 +08:00

119 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { createContext, useContext, useState, useEffect, ReactNode } from 'react'
import { User, UserRole, LoginCredentials, AuthContextType } from '@/types/auth'
const AuthContext = createContext<AuthContextType | undefined>(undefined)
// 模拟用户数据(后续替换为真实 API
const MOCK_USERS: Record<string, User & { password: string }> = {
'creator@demo.com': {
id: 'user-001',
name: '达人小美',
email: 'creator@demo.com',
role: 'creator',
tenantId: 'tenant-001',
tenantName: '美妆品牌A',
password: 'demo123',
},
'agency@demo.com': {
id: 'user-002',
name: '张经理',
email: 'agency@demo.com',
role: 'agency',
tenantId: 'tenant-001',
tenantName: '美妆品牌A',
password: 'demo123',
},
'brand@demo.com': {
id: 'user-003',
name: '李总监',
email: 'brand@demo.com',
role: 'brand',
tenantId: 'tenant-001',
tenantName: '美妆品牌A',
password: 'demo123',
},
}
const STORAGE_KEY = 'miaosi_auth'
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null)
const [isLoading, setIsLoading] = useState(true)
const [mounted, setMounted] = useState(false)
// 初始化时从 localStorage 恢复登录状态
useEffect(() => {
setMounted(true)
if (typeof window !== 'undefined') {
const stored = localStorage.getItem(STORAGE_KEY)
if (stored) {
try {
const parsed = JSON.parse(stored)
setUser(parsed)
} catch {
localStorage.removeItem(STORAGE_KEY)
}
}
}
setIsLoading(false)
}, [])
const login = async (credentials: LoginCredentials): Promise<{ success: boolean; error?: string }> => {
// 模拟 API 延迟
await new Promise((resolve) => setTimeout(resolve, 500))
const mockUser = MOCK_USERS[credentials.email]
if (!mockUser) {
return { success: false, error: '用户不存在' }
}
if (mockUser.password !== credentials.password) {
return { success: false, error: '密码错误' }
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { password, ...userWithoutPassword } = mockUser
setUser(userWithoutPassword)
localStorage.setItem(STORAGE_KEY, JSON.stringify(userWithoutPassword))
return { success: true }
}
const logout = () => {
setUser(null)
localStorage.removeItem(STORAGE_KEY)
}
const switchRole = (role: UserRole) => {
if (user) {
const updated = { ...user, role }
setUser(updated)
localStorage.setItem(STORAGE_KEY, JSON.stringify(updated))
}
}
return (
<AuthContext.Provider
value={{
user,
isAuthenticated: !!user,
isLoading,
login,
logout,
switchRole,
}}
>
{children}
</AuthContext.Provider>
)
}
export function useAuth() {
const context = useContext(AuthContext)
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider')
}
return context
}