"use client" import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from "react" interface User { id: string name: string email: string avatar?: string department: string role: "user" | "developer" | "admin" join_date: string favoriteApps: string[] recentApps: string[] 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 { appId: string userId: string likedAt: string } interface AuthContextType { user: User | null login: (email: string, password: string) => Promise register: (userData: RegisterData) => Promise logout: () => void updateProfile: (userData: Partial) => Promise toggleFavorite: (appId: string) => Promise isFavorite: (appId: string) => boolean addToRecentApps: (appId: string) => void getAppLikes: (appId: string) => number incrementViewCount: (appId: string) => void getViewCount: (appId: string) => number updateAppRating: (appId: string, rating: number) => void getAppRating: (appId: string) => number canSubmitApp: () => boolean canAccessAdmin: () => boolean isLoading: boolean isInitialized: boolean // New like functionality toggleLike: (appId: string) => Promise isLiked: (appId: string) => boolean hasLikedToday: (appId: string) => boolean getAppLikesInPeriod: (appId: string, startDate: string, endDate: string) => number getUserLikeHistory: () => Array<{ appId: string; date: string }> getLikeCount: (appId: string) => number likeApp: (appId: string) => Promise } interface RegisterData { name: string email: string password: string department: string role?: string } const AuthContext = createContext(undefined) // Mock users data with new role system const mockUsers: User[] = [] // Global app likes counter - in a real app this would be in a database const appLikesCounter: Record = {} export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null) const [isLoading, setIsLoading] = useState(false) const [isInitialized, setIsInitialized] = useState(false) // View count state with localStorage persistence const [appViews, setAppViews] = useState>(() => { if (typeof window !== "undefined") { const saved = localStorage.getItem("appViews") return saved ? JSON.parse(saved) : {} } return {} }) // App ratings state with localStorage persistence const [appRatings, setAppRatings] = useState>(() => { if (typeof window !== "undefined") { const saved = localStorage.getItem("appRatings") return saved ? JSON.parse(saved) : {} } return {} }) // App statistics state (from database) const [appStats, setAppStats] = useState>({}) // User interaction states (from database) - 不使用 localStorage,總是從資料庫載入 const [userLikes, setUserLikes] = useState>({}) const [userFavorites, setUserFavorites] = useState>({}) const [appLikes, setAppLikes] = useState>(() => { if (typeof window !== "undefined") { const saved = localStorage.getItem("appLikes") return saved ? JSON.parse(saved) : {} } return {} }) // New like system state with localStorage persistence const [userLikesOld, setUserLikesOld] = useState>>(() => { if (typeof window !== "undefined") { const saved = localStorage.getItem("userLikes") return saved ? JSON.parse(saved) : {} } return {} }) // App likes with date tracking const [appLikesOld, setAppLikesOld] = useState>>(() => { if (typeof window !== "undefined") { const saved = localStorage.getItem("appLikesOld") return saved ? JSON.parse(saved) : {} } return {} }) useEffect(() => { // Check for stored user session only on client side if (typeof window !== 'undefined') { const storedUser = localStorage.getItem("user") if (storedUser) { const userData = JSON.parse(storedUser) setUser(userData) // 立即載入用戶的互動狀態,不使用 localStorage fetchUserInteractions(userData.id) } } setIsLoading(false) setIsInitialized(true) }, []) // 當用戶登入時載入互動狀態 useEffect(() => { if (user) { fetchUserInteractions(user.id) } }, [user]) // Save old likes to localStorage when they change (保留舊系統的 localStorage) useEffect(() => { if (typeof window !== "undefined") { localStorage.setItem("appLikesOld", JSON.stringify(appLikesOld)) } }, [appLikesOld]) const login = async (email: string, password: string): Promise => { setIsLoading(true) try { const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password }), }) const data = await response.json() if (data.success && data.user) { // 添加前端需要的額外字段 const userWithExtras = { ...data.user, favoriteApps: [], recentApps: [] } setUser(userWithExtras) localStorage.setItem("user", JSON.stringify(userWithExtras)) // 載入用戶的互動狀態 await fetchUserInteractions(data.user.id) setIsLoading(false) return true } else { setIsLoading(false) return false } } catch (error) { console.error('登入錯誤:', error) setIsLoading(false) return false } } const register = async (userData: RegisterData): Promise => { setIsLoading(true) try { const response = await fetch('/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(userData), }) const data = await response.json() if (data.success && data.user) { // 添加前端需要的額外字段 const userWithExtras = { ...data.user, favoriteApps: [], 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 } } const logout = () => { setUser(null) localStorage.removeItem("user") } const updateProfile = async (userData: Partial): Promise => { if (!user) return false setIsLoading(true) try { const response = await fetch('/api/auth/profile', { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: user.id, ...userData }), }) const data = await response.json() 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 } } const toggleFavorite = async (appId: string): Promise => { if (!user) return false try { const isFavorited = userFavorites[user.id]?.includes(appId) || false if (isFavorited) { // 移除收藏 const response = await fetch(`/api/apps/${appId}/favorite?userId=${user.id}`, { method: 'DELETE' }) if (response.ok) { const data = await response.json() if (data.success) { // 更新本地狀態 setUserFavorites(prev => ({ ...prev, [user.id]: (prev[user.id] || []).filter(id => id !== appId) })) // 更新用戶的 favoriteApps const updatedFavorites = user.favoriteApps.filter((id) => id !== appId) await updateProfile({ favoriteApps: updatedFavorites, }) return false } } } else { // 添加收藏 const response = await fetch(`/api/apps/${appId}/favorite`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: user.id }) }) if (response.ok) { const data = await response.json() if (data.success) { // 更新本地狀態 setUserFavorites(prev => ({ ...prev, [user.id]: [...(prev[user.id] || []), appId] })) // 更新用戶的 favoriteApps const updatedFavorites = [...user.favoriteApps, appId] await updateProfile({ favoriteApps: updatedFavorites, }) return true } } else if (response.status === 409) { // 已經收藏過,更新本地狀態 setUserFavorites(prev => ({ ...prev, [user.id]: [...(prev[user.id] || []), appId] })) return true } } } catch (error) { console.error('切換收藏狀態錯誤:', error) } return false } const isFavorite = useCallback((appId: string): boolean => { if (!user) return false const userFavs = userFavorites[user.id] || [] return userFavs.includes(appId) }, [user, userFavorites]) const isLiked = useCallback((appId: string): boolean => { if (!user) return false const userLikedApps = userLikes[user.id] || [] return userLikedApps.includes(appId) }, [user, userLikes]) const addToRecentApps = (appId: string): void => { if (!user) return const updatedRecent = [appId, ...user.recentApps.filter((id) => id !== appId)].slice(0, 10) updateProfile({ recentApps: updatedRecent, }) } const getAppLikes = (appId: string): number => { return appStats[appId]?.likesCount || 0 } // 從資料庫獲取應用統計數據 const fetchAppStats = async (appId: string) => { try { const response = await fetch(`/api/apps/${appId}/interactions`) if (response.ok) { const data = await response.json() if (data.success) { setAppStats(prev => ({ ...prev, [appId]: data.data })) } } } catch (error) { console.error('獲取應用統計數據錯誤:', error) } } // 從資料庫獲取用戶的按讚和收藏狀態 const fetchUserInteractions = async (userId: string) => { try { const response = await fetch(`/api/user/interactions?userId=${userId}`) if (response.ok) { const data = await response.json() if (data.success) { setUserLikes(prev => ({ ...prev, [userId]: data.data.likes })) setUserFavorites(prev => ({ ...prev, [userId]: data.data.favorites })) } } } catch (error) { console.error('獲取用戶互動狀態錯誤:', error) } } // New like functionality const toggleLike = async (appId: string): Promise => { if (!user) return false try { const response = await fetch(`/api/apps/${appId}/interactions`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'like', userId: user.id }) }) if (response.ok) { const data = await response.json() if (data.success) { // 更新應用統計數據 setAppStats(prev => ({ ...prev, [appId]: data.data })) // 使用 API 返回的按讚狀態更新本地狀態 const newLikedState = data.data.userLiked setUserLikes(prev => ({ ...prev, [user.id]: newLikedState ? [...(prev[user.id] || []), appId] : (prev[user.id] || []).filter(id => id !== appId) })) return newLikedState } } } catch (error) { console.error('切換按讚狀態錯誤:', error) } return false } const hasLikedTodayOld = (appId: string): boolean => { if (!user) return false const today = new Date().toISOString().split("T")[0] const userLikeHistory = userLikesOld[user.id] || [] return userLikeHistory.some((like) => like.appId === appId && like.date === today) } const getAppLikesInPeriod = (appId: string, startDate: string, endDate: string): number => { const appLikeHistory = appLikesOld[appId] || [] return appLikeHistory.filter((like) => { return like.date >= startDate && like.date <= endDate }).length } const getUserLikeHistory = (): Array<{ appId: string; date: string }> => { if (!user) return [] return userLikesOld[user.id] || [] } // View count functionality const incrementViewCount = async (appId: string): Promise => { if (!user) return try { const response = await fetch(`/api/apps/${appId}/interactions`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'view', userId: user.id }) }) if (response.ok) { const data = await response.json() if (data.success) { setAppStats(prev => ({ ...prev, [appId]: data.data })) } } } catch (error) { console.error('增加觀看次數錯誤:', error) } } const getViewCount = (appId: string): number => { return appStats[appId]?.viewsCount || 0 } // Rating functionality const updateAppRating = (appId: string, rating: number): void => { setAppRatings((prev) => { const newRatings = { ...prev, [appId]: rating } if (typeof window !== "undefined") { localStorage.setItem("appRatings", JSON.stringify(newRatings)) } return newRatings }) } const getAppRating = (appId: string): number => { return appStats[appId]?.rating || 0 } const getLikeCount = (appId: string): number => { return appLikes[appId]?.length || 0 } const hasLikedToday = (appId: string): boolean => { if (!user) return false const today = new Date().toISOString().split("T")[0] return appLikes[appId]?.some((like) => like.userId === user.id && like.likedAt.startsWith(today)) || false } const likeApp = async (appId: string): Promise => { if (!user) return false const today = new Date().toISOString().split("T")[0] // Check if user already liked today if (hasLikedToday(appId)) return false const newLike: AppLike = { appId, userId: user.id, likedAt: new Date().toISOString(), } setAppLikes((prev) => { const updatedLikes = { ...prev } if (!updatedLikes[appId]) { updatedLikes[appId] = [] } updatedLikes[appId] = [...updatedLikes[appId], newLike] if (typeof window !== "undefined") { localStorage.setItem("appLikes", JSON.stringify(updatedLikes)) } return updatedLikes }) return true } // Permission check functions const canSubmitApp = (): boolean => { return user?.role === "developer" } const canAccessAdmin = (): boolean => { return user?.role === "admin" } return ( {children} ) } export function useAuth() { const context = useContext(AuthContext) if (context === undefined) { throw new Error("useAuth must be used within an AuthProvider") } return context }