From e7498a9f8b2c5e31aa05289263219b84ac904f58 Mon Sep 17 00:00:00 2001 From: Logan Cusano Date: Sun, 13 Jul 2025 19:53:36 -0400 Subject: [PATCH] Fix modules --- app/auth/login/page.tsx | 24 +++++++---- app/main/admin/page.tsx | 17 +++++--- app/main/layout.tsx | 16 ++++++-- app/main/page.tsx | 25 ++++++++---- lib/auth.tsx | 88 ++++++++++++++++++++--------------------- 5 files changed, 101 insertions(+), 69 deletions(-) diff --git a/app/auth/login/page.tsx b/app/auth/login/page.tsx index 2cdc3a8..5a6cd1a 100644 --- a/app/auth/login/page.tsx +++ b/app/auth/login/page.tsx @@ -1,12 +1,20 @@ +'use client'; + +import { useState, FormEvent } from 'react'; +import { useAuth } from '@/lib/auth'; +import { API_URL } from '@/lib/api'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Input } from '@/components/ui/input'; + const LoginPage = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const auth = useAuth(); - // In a real app, you'd use Next.js's useRouter const [isLoggedIn, setIsLoggedIn] = useState(false); - const handleSubmit = async (e) => { + const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setError(''); try { @@ -27,17 +35,15 @@ const LoginPage = () => { const { id_token, uid } = await response.json(); - // A real app would fetch user details here, but we'll mock it - const userDetails = { uid, email, role: 'user' }; // Assume 'user' for now + const userDetails = { uid, email, role: 'user' }; auth.login(id_token, userDetails); - setIsLoggedIn(true); // Simulate redirect - } catch (err) { + setIsLoggedIn(true); + } catch (err: any) { setError(err.message); } }; if (isLoggedIn || auth.isAuthenticated) { - // In a real app, this would be a redirect to '/' return

Redirecting...

; } @@ -64,4 +70,6 @@ const LoginPage = () => { ); - }; \ No newline at end of file + }; + + export default LoginPage; \ No newline at end of file diff --git a/app/main/admin/page.tsx b/app/main/admin/page.tsx index 2a510a2..d002f5c 100644 --- a/app/main/admin/page.tsx +++ b/app/main/admin/page.tsx @@ -1,3 +1,11 @@ +'use client'; + +import { useState } from 'react'; +import { useAuth } from '@/lib/auth'; +import { apiRequest } from '@/lib/api'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; + const AdminPage = () => { const [message, setMessage] = useState(''); const [error, setError] = useState(''); @@ -9,12 +17,11 @@ const AdminPage = () => { try { const data = await apiRequest('/videos/scan', { method: 'POST', token: auth.token }); setMessage(data.message); - } catch (err) { + } catch (err: any) { setError(err.message); } }; - // In a real app, you'd fetch users and votes here const users = [{email: 'admin@example.com', role: 'admin'}, {email: 'user@example.com', role: 'user'}]; const votes = [{video_id: 'xyz', decision: 'approve', reason: 'Good clip'}]; @@ -38,7 +45,6 @@ const AdminPage = () => { Users - {/* User list would be rendered here */}

User list functionality would go here.

@@ -46,10 +52,11 @@ const AdminPage = () => { Votes - {/* Vote list would be rendered here */}

Vote list functionality would go here.

); -}; \ No newline at end of file +}; + +export default AdminPage; \ No newline at end of file diff --git a/app/main/layout.tsx b/app/main/layout.tsx index d506ae5..76eb0c2 100644 --- a/app/main/layout.tsx +++ b/app/main/layout.tsx @@ -1,8 +1,14 @@ -const MainLayout = ({ children }) => { +'use client'; + +import React from 'react'; +import { useAuth } from '@/lib/auth'; +import LoginPage from '@/app/auth/login/page'; +import { Button } from '@/components/ui/button'; + +const MainLayout = ({ children }: { children: React.ReactNode }) => { const auth = useAuth(); if (!auth.isAuthenticated) { - // This would be a redirect in a real Next.js app return ; } @@ -13,7 +19,7 @@ const MainLayout = ({ children }) => {

Video Voter

{auth.user?.role === 'admin' && ( - Admin + Admin )}
@@ -24,4 +30,6 @@ const MainLayout = ({ children }) => { ); -}; \ No newline at end of file +}; + +export default MainLayout; \ No newline at end of file diff --git a/app/main/page.tsx b/app/main/page.tsx index 4aa7095..7f625a9 100644 --- a/app/main/page.tsx +++ b/app/main/page.tsx @@ -1,5 +1,14 @@ +'use client'; + +import { useState } from 'react'; +import { useAuth } from '@/lib/auth'; +import { apiRequest, API_URL } from '@/lib/api'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Textarea } from '@/components/ui/textarea'; + const VotingPage = () => { - const [video, setVideo] = useState(null); + const [video, setVideo] = useState(null); const [reason, setReason] = useState(''); const [message, setMessage] = useState(''); const [error, setError] = useState(''); @@ -12,17 +21,17 @@ const VotingPage = () => { try { const data = await apiRequest('/videos/vote-next', { token: auth.token }); setVideo(data); - } catch (err) { + } catch (err: any) { setError(err.message); } }; - const submitVote = async (decision) => { + const submitVote = async (decision: string) => { if (!video) return; setError(''); setMessage(''); try { - const body = { decision, reason, recommended_game: '' }; // Add recommended_game if needed + const body = { decision, reason, recommended_game: '' }; await apiRequest(`/videos/${video.id}/vote`, { method: 'POST', body, @@ -31,7 +40,7 @@ const VotingPage = () => { setMessage(`Vote '${decision}' submitted successfully!`); setVideo(null); setReason(''); - } catch (err) { + } catch (err: any) { setError(err.message); } }; @@ -60,8 +69,6 @@ const VotingPage = () => { className="w-full rounded-lg bg-black" controls src={`${API_URL}/videos/${video.id}/stream?token=${auth.token}`} - // The token in query param is a simple way for this demo. - // In a real app, you might handle auth differently for media. > Your browser does not support the video tag. @@ -84,4 +91,6 @@ const VotingPage = () => { ); -}; \ No newline at end of file +}; + +export default VotingPage; \ No newline at end of file diff --git a/lib/auth.tsx b/lib/auth.tsx index c5fc552..61c24f7 100644 --- a/lib/auth.tsx +++ b/lib/auth.tsx @@ -1,45 +1,45 @@ -import React, { createContext, useContext, useState, useEffect } from 'react'; - - const AuthContext = createContext(null); - - export const AuthProvider = ({ children }) => { - const [token, setToken] = useState(null); - const [user, setUser] = useState(null); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const storedToken = localStorage.getItem('authToken'); - const storedUser = localStorage.getItem('authUser'); - if (storedToken && storedUser) { - setToken(storedToken); - setUser(JSON.parse(storedUser)); - } - setLoading(false); - }, []); - - const login = (newToken, newUser) => { - setToken(newToken); - setUser(newUser); - localStorage.setItem('authToken', newToken); - localStorage.setItem('authUser', JSON.stringify(newUser)); - }; - - const logout = () => { - setToken(null); - setUser(null); - localStorage.removeItem('authToken'); - localStorage.removeItem('authUser'); - }; - - const value = { token, user, login, logout, isAuthenticated: !!token }; - - return ( - - {!loading && children} - - ); +import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; + +const AuthContext = createContext(null); + +export const AuthProvider = ({ children }: { children: ReactNode }) => { + const [token, setToken] = useState(null); + const [user, setUser] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const storedToken = localStorage.getItem('authToken'); + const storedUser = localStorage.getItem('authUser'); + if (storedToken && storedUser) { + setToken(storedToken); + setUser(JSON.parse(storedUser)); + } + setLoading(false); + }, []); + + const login = (newToken: string, newUser: any) => { + setToken(newToken); + setUser(newUser); + localStorage.setItem('authToken', newToken); + localStorage.setItem('authUser', JSON.stringify(newUser)); }; - - export const useAuth = () => { - return useContext(AuthContext); - }; \ No newline at end of file + + const logout = () => { + setToken(null); + setUser(null); + localStorage.removeItem('authToken'); + localStorage.removeItem('authUser'); + }; + + const value = { token, user, login, logout, isAuthenticated: !!token }; + + return ( + + {!loading && children} + + ); +}; + +export const useAuth = () => { + return useContext(AuthContext); +}; \ No newline at end of file