整合資料庫、完成登入註冊忘記密碼功能

This commit is contained in:
2025-09-09 12:00:22 +08:00
parent af88c0f037
commit 32b19e9a0f
85 changed files with 11672 additions and 2350 deletions

View File

@@ -9,11 +9,18 @@ interface User {
avatar?: string
department: string
role: "user" | "developer" | "admin"
joinDate: string
join_date: string
favoriteApps: string[]
recentApps: string[]
totalLikes: number
totalViews: number
total_likes: number
total_views: number
is_active: boolean
last_login?: string
phone?: string
location?: string
bio?: string
created_at: string
updated_at: string
}
interface AppLike {
@@ -39,6 +46,7 @@ interface AuthContextType {
canSubmitApp: () => boolean
canAccessAdmin: () => boolean
isLoading: boolean
isInitialized: boolean
// New like functionality
toggleLike: (appId: string) => Promise<boolean>
hasLikedToday: (appId: string) => boolean
@@ -65,32 +73,8 @@ const appLikesCounter: Record<string, number> = {}
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null)
const [isLoading, setIsLoading] = useState(true)
// 初始化時檢查現有的認證狀態
useEffect(() => {
const initializeAuth = async () => {
try {
const savedUser = localStorage.getItem("user")
const token = localStorage.getItem("token")
if (savedUser && token) {
const userData = JSON.parse(savedUser)
setUser(userData)
console.log('從 localStorage 恢復用戶狀態:', userData)
}
} catch (error) {
console.error('初始化認證狀態失敗:', error)
// 清除無效的認證資料
localStorage.removeItem("user")
localStorage.removeItem("token")
} finally {
setIsLoading(false)
}
}
initializeAuth()
}, [])
const [isLoading, setIsLoading] = useState(false)
const [isInitialized, setIsInitialized] = useState(false)
// View count state with localStorage persistence
const [appViews, setAppViews] = useState<Record<string, number>>(() => {
@@ -137,12 +121,15 @@ export function AuthProvider({ children }: { children: ReactNode }) {
})
useEffect(() => {
// Check for stored user session
const storedUser = localStorage.getItem("user")
if (storedUser) {
setUser(JSON.parse(storedUser))
// Check for stored user session only on client side
if (typeof window !== 'undefined') {
const storedUser = localStorage.getItem("user")
if (storedUser) {
setUser(JSON.parse(storedUser))
}
}
setIsLoading(false)
setIsInitialized(true)
}, [])
// Save likes to localStorage when they change
@@ -167,14 +154,18 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const data = await response.json()
if (response.ok && data.user) {
setUser(data.user)
localStorage.setItem("user", JSON.stringify(data.user))
localStorage.setItem("token", data.token)
if (data.success && data.user) {
// 添加前端需要的額外字段
const userWithExtras = {
...data.user,
favoriteApps: [],
recentApps: []
}
setUser(userWithExtras)
localStorage.setItem("user", JSON.stringify(userWithExtras))
setIsLoading(false)
return true
} else {
console.error('登入失敗:', data.error)
setIsLoading(false)
return false
}
@@ -199,13 +190,18 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const data = await response.json()
if (response.ok && data.user) {
setUser(data.user)
localStorage.setItem("user", JSON.stringify(data.user))
if (data.success && data.user) {
// 添加前端需要的額外字段
const userWithExtras = {
...data.user,
favoriteApps: [],
recentApps: []
}
setUser(userWithExtras)
localStorage.setItem("user", JSON.stringify(userWithExtras))
setIsLoading(false)
return true
} else {
console.error('註冊失敗:', data.error)
setIsLoading(false)
return false
}
@@ -219,7 +215,6 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const logout = () => {
setUser(null)
localStorage.removeItem("user")
localStorage.removeItem("token")
}
const updateProfile = async (userData: Partial<User>): Promise<boolean> => {
@@ -227,21 +222,40 @@ export function AuthProvider({ children }: { children: ReactNode }) {
setIsLoading(true)
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 1000))
try {
const response = await fetch('/api/auth/profile', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
userId: user.id,
...userData
}),
})
const updatedUser = { ...user, ...userData }
setUser(updatedUser)
localStorage.setItem("user", JSON.stringify(updatedUser))
const data = await response.json()
// Update in mock data
const userIndex = mockUsers.findIndex((u) => u.id === user.id)
if (userIndex !== -1) {
mockUsers[userIndex] = updatedUser
if (data.success && data.user) {
// 保持前端需要的額外字段
const userWithExtras = {
...data.user,
favoriteApps: user.favoriteApps,
recentApps: user.recentApps
}
setUser(userWithExtras)
localStorage.setItem("user", JSON.stringify(userWithExtras))
setIsLoading(false)
return true
} else {
setIsLoading(false)
return false
}
} catch (error) {
console.error('更新資料錯誤:', error)
setIsLoading(false)
return false
}
setIsLoading(false)
return true
}
const toggleFavorite = async (appId: string): Promise<boolean> => {
@@ -436,6 +450,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
canSubmitApp,
canAccessAdmin,
isLoading,
isInitialized,
// New like functionality
toggleLike,
hasLikedTodayOld,