From 159cac6460fb2a42456c6f9a44cbcdb03b938823 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Wed, 3 Sep 2025 21:45:38 -0700 Subject: implement admin dashboard frontend and handle game creation --- frontend/src/pages/Admin.tsx | 205 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 frontend/src/pages/Admin.tsx (limited to 'frontend/src/pages') diff --git a/frontend/src/pages/Admin.tsx b/frontend/src/pages/Admin.tsx new file mode 100644 index 0000000..f494fc2 --- /dev/null +++ b/frontend/src/pages/Admin.tsx @@ -0,0 +1,205 @@ +import { useNavigate } from "react-router"; +import { NavBar } from "../components/NavBar"; +import { useAuth } from "../contexts/AuthContext"; +import SessionExpiredPopup from "../components/SessionExpiredPopup"; +import { useState } from "react"; + + +const Admin = () => { + const { user, isLoading, logout } = useAuth(); + const [showAddGame, setShowAddGame] = useState(false); + const [formData, setFormData] = useState({ + gameInternalName: '', + gameFormattedName: '', + gameDescription: '' + }); + const [isSubmitting, setIsSubmitting] = useState(false); + const navigate = useNavigate(); + + const handleLogout = async () => { + try { + await logout(); + navigate("/"); + } catch (error) { + console.error("Logout failed:", error); + alert("Network error during logout. Please try again."); + } + }; + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData(prev => ({ + ...prev, + [name]: value + })); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!formData.gameInternalName || !formData.gameFormattedName || !formData.gameDescription) { + alert('Please fill in all fields'); + return; + } + + setIsSubmitting(true); + + try { + const response = await fetch(import.meta.env.VITE_API_URL + '/admin/createGame', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + credentials: 'include', + body: JSON.stringify(formData), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.error || 'Failed to create game'); + } + + alert('Game created successfully!'); + setFormData({ + gameInternalName: '', + gameFormattedName: '', + gameDescription: '' + }); + setShowAddGame(false); + + } catch (error) { + console.error('Failed to create game:', error); + alert(error instanceof Error ? error.message : 'Failed to create game'); + } finally { + setIsSubmitting(false); + } + }; + + if (isLoading) { + return ( +
+
+
+

Loading Admin dashboard...

+
+
+ ); + } + + if (!user) { + return ; + } + if(!user.isAdmin && user.id != 1){ + console.log(user.id == 1) + return
+
+
+

You are not authorized to access this page.

+
+
; + } + + return ( +
+ + + {/* Main Content */} +
+ {/* Header */} +
+

Admin Page

+

+ Welcome Mirage Webmaster! Here are a variety of settings and tools you can use to customize the experience +

+
+ {/* Add New Game Section */} +
+
+ + {showAddGame && ( +
+

+ This form allows you to add a new game to Mirage. By default, Mirage will attempt to derive a method of showing the game's score on its own. + You may override this behavior by writing your own custom score display logic. +

+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ )} +
+
+
+
+ ); +}; + +export default Admin; -- cgit v1.2.3