From 91438ead53af898493c95185180469b96ac21a17 Mon Sep 17 00:00:00 2001 From: Jillian Xu Date: Fri, 27 Dec 2024 23:28:31 -0500 Subject: [PATCH 1/7] Update user login welcome page and added /login post request --- backend/handlers/users.go | 77 ++++++++++++++++ backend/main.go | 3 + frontend/src/components/NavBar.tsx | 104 ++++++++++++++-------- frontend/src/pages/About.tsx | 130 ++++++++++++++++++++++++--- frontend/src/pages/Home.tsx | 136 +++++++++++++++++++++++++---- 5 files changed, 384 insertions(+), 66 deletions(-) diff --git a/backend/handlers/users.go b/backend/handlers/users.go index 175148a..b1e4277 100644 --- a/backend/handlers/users.go +++ b/backend/handlers/users.go @@ -1,7 +1,9 @@ package handlers import ( + "bytes" "context" + "encoding/json" "errors" "fmt" "log" @@ -336,3 +338,78 @@ func (handler *RouteHandler) GetUserTournaments(c *gin.Context) { c.JSON(http.StatusOK, tournaments) } + +type LoginRequest struct { + Email string `json:"email"` + Password string `json:"password"` +} + +type FirebaseSignInResponse struct { + IdToken string `json:"idToken"` + RefreshToken string `json:"refreshToken"` + ExpiresIn string `json:"expiresIn"` + // ... other fields you might want, e.g. localId, etc. +} + +func (handler *RouteHandler) LoginUser(c *gin.Context) { + fmt.Println("peepeee") + + var ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + fmt.Println("LALALAA:") + + var loginReq LoginRequest + if err := c.ShouldBindJSON(&loginReq); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) + return + } + + payload, err := json.Marshal(map[string]string{ + "email": loginReq.Email, + "password": loginReq.Password, + "returnSecureToken": "true", + }) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to marshal payload"}) + return + } + + apiKey := "REPLACE_THIS_API_KEY" // REPLAAACE AAAAA + firebaseURL := fmt.Sprintf("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=%s", apiKey) + + req, err := http.NewRequestWithContext(ctx, "POST", firebaseURL, bytes.NewBuffer(payload)) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Error creating Firebase request"}) + return + } + req.Header.Set("Content-Type", "application/json") + + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Error calling Firebase Auth API"}) + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email or password"}) + return + } + + var fbResp FirebaseSignInResponse + if err := json.NewDecoder(resp.Body).Decode(&fbResp); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Error decoding Firebase response"}) + return + } + + fmt.Println("Bearer Token:") + + c.JSON(http.StatusOK, gin.H{ + "message": "Login successful", + "token": fbResp.IdToken, // Bearer token + "refreshToken": fbResp.RefreshToken, // optional + "expiresIn": fbResp.ExpiresIn, // optional + }) + +} diff --git a/backend/main.go b/backend/main.go index 25c9d51..3387d2f 100644 --- a/backend/main.go +++ b/backend/main.go @@ -98,5 +98,8 @@ func main() { // stripe configuration protectedRoutes.POST("/payment-intent", paymentHandler.CreatePaymentIntent) + // Add the login endpoint + publicRoutes.POST("/login", userHandler.LoginUser) + router.Run("localhost:" + port) } diff --git a/frontend/src/components/NavBar.tsx b/frontend/src/components/NavBar.tsx index aed4267..fcfa23b 100644 --- a/frontend/src/components/NavBar.tsx +++ b/frontend/src/components/NavBar.tsx @@ -5,62 +5,90 @@ import UserDropdown from "./UserDropdown"; import useAuth from "@/hooks/useAuth"; import { Button } from "@/shadcn-components/ui/button"; - - const NavBar = () => { - const navigate = useNavigate(); const { currentUser } = useAuth(); const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); - + + const displayName = + currentUser?.displayName || currentUser?.email || "User"; return ( - - - - ) -} + ); +}; -export default NavBar +export default NavBar; diff --git a/frontend/src/pages/About.tsx b/frontend/src/pages/About.tsx index 5304e80..9a4cad0 100644 --- a/frontend/src/pages/About.tsx +++ b/frontend/src/pages/About.tsx @@ -1,21 +1,127 @@ +import React from 'react'; +const About: React.FC = () => { + return ( +
+ {/* Hero / Header section */} +
+
+
+

About Debate Dino

+

We sure love debating!

+
+
-const About = () => { - - return ( -
-
-

About Debate Dino

-

We sure love debating!

-
+ {/* Main content */} +
+ {/* Intro paragraph */} +
+

Who We Are

+

+ At Debate Dino, our mission is to be a dinosaur. +

- ) + {/* Mission / Vision section */} +
+
+

Our Mission

+

+ Our mission is to bring debaters of all backgrounds together to + learn, compete, and have fun. We believe that debate fosters + critical thinking, empathy, and effective communication—skills + that empower people to make positive changes in their lives + and communities. +

+
+
+

Our Vision

+

+ We envision a world where thoughtful discussion is accessible + to everyone—no matter their location, experience, or skill + level. From friendly online forums to prestigious, in-person + tournaments, we aim to create an inclusive environment where + participants can explore new perspectives and grow together. +

+
+
-} + {/* Fun Fact / Stats / Highlight section (optional) */} +
+

Why “Dino”?

+

+ Dinosaurs spark curiosity, imagination, and a sense of wonder + about the past—and that’s what we want for debates: a place + that ignites curiosity, respectful exploration, and excitement + for the next new idea. Plus, who doesn’t love a friendly T-Rex + as a mascot? +

+
+ {/* Team / Values / “Timeline” section (optional) */} +
+

Our Journey

+
    +
  • +
    + 2021 + + Debate Dino was hatched + +
    +

    + Began as a small group of enthusiastic debaters on campus. +

    +
  • +
  • +
    + 2022 + + First official tournament + +
    +

    + We welcomed debaters from around the globe in our first big + online event. +

    +
  • +
  • +
    + 2023+ + + Expanding our footprint + +
    +

    + Partnering with more institutions and clubs to bring debate + to new audiences. +

    +
  • +
+
+ {/* Call to Action */} +
+

+ Ready to Join the Discussion? +

+

+ Sign up for our next tournament or explore our forums to jump + into a debate that sparks your interest. +

+ +
+
+
+ ); +}; export default About; - - diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index b571eaa..018974c 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -1,31 +1,135 @@ +import React, { useEffect, useState } from 'react'; +import useAuth from '@/hooks/useAuth'; +import axios from '@/lib/axios'; - -const Home = () => { +const GuestHome: React.FC = () => { return ( - -
-
+
+
-

Debate Dino

Start debating today!

- - + +
-
- Debate Tournaments + Debate Tournaments
-
- - - - ) +
+ ); +}; + +interface User { + uid: string; + email?: string; + displayName?: string; + // etc. } -export default Home +const SignedInHome: React.FC<{ user: User }> = ({ user }) => { + return ( +
+ {/* Hero / Welcome section */} +
+
+
+

+ Welcome back, {user.displayName || 'Debater'}! +

+

Ready to jump into your next debate?

+ +
+
+ + {/* Example recommended section */} +
+

Recommended Debates

+
+
+

AI & Ethics

+

+ Upcoming debate on AI usage in daily life. +

+ +
+
+

Renewable Energy

+

Debate of the week!

+ +
+
+

Global Economy

+

Suggested for you

+ +
+
+
+
+ ); +}; + +const Home: React.FC = () => { + const { currentUser: fbUser } = useAuth(); + const [signedInUser, setSignedInUser] = useState(null); + + useEffect(() => { + async function checkUser() { + if (!fbUser) { + console.error("User is not signed in, can't do user-specific stuff."); + setSignedInUser(null); + return; + } + + try { + const token = await fbUser.getIdToken(); + console.log('User Token:', token); + + setSignedInUser({ + uid: fbUser.uid, + email: fbUser.email || '', + displayName: fbUser.displayName || '', + }); + } catch (err) { + console.error('Error retrieving token:', err); + setSignedInUser(null); + } + } + + checkUser(); + }, [fbUser]); + + if (!signedInUser) { + return ; + } + + return ; +}; + +export default Home; From a767835d8df49d45ad817e843f760a0ef842f6e7 Mon Sep 17 00:00:00 2001 From: Jillian Xu Date: Sun, 29 Dec 2024 23:32:05 -0500 Subject: [PATCH 2/7] Remove changes for /login post request --- backend/handlers/users.go | 79 +-------------------------------------- backend/main.go | 5 +-- 2 files changed, 2 insertions(+), 82 deletions(-) diff --git a/backend/handlers/users.go b/backend/handlers/users.go index b1e4277..ecb917e 100644 --- a/backend/handlers/users.go +++ b/backend/handlers/users.go @@ -1,9 +1,7 @@ package handlers import ( - "bytes" "context" - "encoding/json" "errors" "fmt" "log" @@ -337,79 +335,4 @@ func (handler *RouteHandler) GetUserTournaments(c *gin.Context) { } c.JSON(http.StatusOK, tournaments) -} - -type LoginRequest struct { - Email string `json:"email"` - Password string `json:"password"` -} - -type FirebaseSignInResponse struct { - IdToken string `json:"idToken"` - RefreshToken string `json:"refreshToken"` - ExpiresIn string `json:"expiresIn"` - // ... other fields you might want, e.g. localId, etc. -} - -func (handler *RouteHandler) LoginUser(c *gin.Context) { - fmt.Println("peepeee") - - var ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - fmt.Println("LALALAA:") - - var loginReq LoginRequest - if err := c.ShouldBindJSON(&loginReq); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) - return - } - - payload, err := json.Marshal(map[string]string{ - "email": loginReq.Email, - "password": loginReq.Password, - "returnSecureToken": "true", - }) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to marshal payload"}) - return - } - - apiKey := "REPLACE_THIS_API_KEY" // REPLAAACE AAAAA - firebaseURL := fmt.Sprintf("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=%s", apiKey) - - req, err := http.NewRequestWithContext(ctx, "POST", firebaseURL, bytes.NewBuffer(payload)) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error creating Firebase request"}) - return - } - req.Header.Set("Content-Type", "application/json") - - client := http.Client{} - resp, err := client.Do(req) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error calling Firebase Auth API"}) - return - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email or password"}) - return - } - - var fbResp FirebaseSignInResponse - if err := json.NewDecoder(resp.Body).Decode(&fbResp); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error decoding Firebase response"}) - return - } - - fmt.Println("Bearer Token:") - - c.JSON(http.StatusOK, gin.H{ - "message": "Login successful", - "token": fbResp.IdToken, // Bearer token - "refreshToken": fbResp.RefreshToken, // optional - "expiresIn": fbResp.ExpiresIn, // optional - }) - -} +} \ No newline at end of file diff --git a/backend/main.go b/backend/main.go index 3387d2f..196dcd0 100644 --- a/backend/main.go +++ b/backend/main.go @@ -98,8 +98,5 @@ func main() { // stripe configuration protectedRoutes.POST("/payment-intent", paymentHandler.CreatePaymentIntent) - // Add the login endpoint - publicRoutes.POST("/login", userHandler.LoginUser) - router.Run("localhost:" + port) -} +} \ No newline at end of file From 92d60d4e204e85fbbd9d9669d268419dc6f762dc Mon Sep 17 00:00:00 2001 From: Jillian Xu Date: Sun, 29 Dec 2024 23:43:00 -0500 Subject: [PATCH 3/7] Revert "Remove changes for /login post request" This reverts commit a767835d8df49d45ad817e843f760a0ef842f6e7. --- backend/handlers/users.go | 79 ++++++++++++++++++++++++++++++++++++++- backend/main.go | 5 ++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/backend/handlers/users.go b/backend/handlers/users.go index ecb917e..b1e4277 100644 --- a/backend/handlers/users.go +++ b/backend/handlers/users.go @@ -1,7 +1,9 @@ package handlers import ( + "bytes" "context" + "encoding/json" "errors" "fmt" "log" @@ -335,4 +337,79 @@ func (handler *RouteHandler) GetUserTournaments(c *gin.Context) { } c.JSON(http.StatusOK, tournaments) -} \ No newline at end of file +} + +type LoginRequest struct { + Email string `json:"email"` + Password string `json:"password"` +} + +type FirebaseSignInResponse struct { + IdToken string `json:"idToken"` + RefreshToken string `json:"refreshToken"` + ExpiresIn string `json:"expiresIn"` + // ... other fields you might want, e.g. localId, etc. +} + +func (handler *RouteHandler) LoginUser(c *gin.Context) { + fmt.Println("peepeee") + + var ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + fmt.Println("LALALAA:") + + var loginReq LoginRequest + if err := c.ShouldBindJSON(&loginReq); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) + return + } + + payload, err := json.Marshal(map[string]string{ + "email": loginReq.Email, + "password": loginReq.Password, + "returnSecureToken": "true", + }) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to marshal payload"}) + return + } + + apiKey := "REPLACE_THIS_API_KEY" // REPLAAACE AAAAA + firebaseURL := fmt.Sprintf("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=%s", apiKey) + + req, err := http.NewRequestWithContext(ctx, "POST", firebaseURL, bytes.NewBuffer(payload)) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Error creating Firebase request"}) + return + } + req.Header.Set("Content-Type", "application/json") + + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Error calling Firebase Auth API"}) + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email or password"}) + return + } + + var fbResp FirebaseSignInResponse + if err := json.NewDecoder(resp.Body).Decode(&fbResp); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Error decoding Firebase response"}) + return + } + + fmt.Println("Bearer Token:") + + c.JSON(http.StatusOK, gin.H{ + "message": "Login successful", + "token": fbResp.IdToken, // Bearer token + "refreshToken": fbResp.RefreshToken, // optional + "expiresIn": fbResp.ExpiresIn, // optional + }) + +} diff --git a/backend/main.go b/backend/main.go index 196dcd0..3387d2f 100644 --- a/backend/main.go +++ b/backend/main.go @@ -98,5 +98,8 @@ func main() { // stripe configuration protectedRoutes.POST("/payment-intent", paymentHandler.CreatePaymentIntent) + // Add the login endpoint + publicRoutes.POST("/login", userHandler.LoginUser) + router.Run("localhost:" + port) -} \ No newline at end of file +} From 44bcf0819cfc87eee1423741ad8f14e4e8179764 Mon Sep 17 00:00:00 2001 From: Jillian Xu Date: Sun, 29 Dec 2024 23:43:30 -0500 Subject: [PATCH 4/7] Update curly bracket --- backend/handlers/users.go | 79 +-------------------------------------- backend/main.go | 5 +-- 2 files changed, 2 insertions(+), 82 deletions(-) diff --git a/backend/handlers/users.go b/backend/handlers/users.go index b1e4277..ecb917e 100644 --- a/backend/handlers/users.go +++ b/backend/handlers/users.go @@ -1,9 +1,7 @@ package handlers import ( - "bytes" "context" - "encoding/json" "errors" "fmt" "log" @@ -337,79 +335,4 @@ func (handler *RouteHandler) GetUserTournaments(c *gin.Context) { } c.JSON(http.StatusOK, tournaments) -} - -type LoginRequest struct { - Email string `json:"email"` - Password string `json:"password"` -} - -type FirebaseSignInResponse struct { - IdToken string `json:"idToken"` - RefreshToken string `json:"refreshToken"` - ExpiresIn string `json:"expiresIn"` - // ... other fields you might want, e.g. localId, etc. -} - -func (handler *RouteHandler) LoginUser(c *gin.Context) { - fmt.Println("peepeee") - - var ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - fmt.Println("LALALAA:") - - var loginReq LoginRequest - if err := c.ShouldBindJSON(&loginReq); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) - return - } - - payload, err := json.Marshal(map[string]string{ - "email": loginReq.Email, - "password": loginReq.Password, - "returnSecureToken": "true", - }) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to marshal payload"}) - return - } - - apiKey := "REPLACE_THIS_API_KEY" // REPLAAACE AAAAA - firebaseURL := fmt.Sprintf("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=%s", apiKey) - - req, err := http.NewRequestWithContext(ctx, "POST", firebaseURL, bytes.NewBuffer(payload)) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error creating Firebase request"}) - return - } - req.Header.Set("Content-Type", "application/json") - - client := http.Client{} - resp, err := client.Do(req) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error calling Firebase Auth API"}) - return - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email or password"}) - return - } - - var fbResp FirebaseSignInResponse - if err := json.NewDecoder(resp.Body).Decode(&fbResp); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error decoding Firebase response"}) - return - } - - fmt.Println("Bearer Token:") - - c.JSON(http.StatusOK, gin.H{ - "message": "Login successful", - "token": fbResp.IdToken, // Bearer token - "refreshToken": fbResp.RefreshToken, // optional - "expiresIn": fbResp.ExpiresIn, // optional - }) - -} +} \ No newline at end of file diff --git a/backend/main.go b/backend/main.go index 3387d2f..196dcd0 100644 --- a/backend/main.go +++ b/backend/main.go @@ -98,8 +98,5 @@ func main() { // stripe configuration protectedRoutes.POST("/payment-intent", paymentHandler.CreatePaymentIntent) - // Add the login endpoint - publicRoutes.POST("/login", userHandler.LoginUser) - router.Run("localhost:" + port) -} +} \ No newline at end of file From 9e2992998aa8a48332aca42716f040fb597a6c3e Mon Sep 17 00:00:00 2001 From: Jillian Xu Date: Sun, 29 Dec 2024 23:45:09 -0500 Subject: [PATCH 5/7] Add new line --- backend/handlers/users.go | 2 +- backend/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/handlers/users.go b/backend/handlers/users.go index ecb917e..175148a 100644 --- a/backend/handlers/users.go +++ b/backend/handlers/users.go @@ -335,4 +335,4 @@ func (handler *RouteHandler) GetUserTournaments(c *gin.Context) { } c.JSON(http.StatusOK, tournaments) -} \ No newline at end of file +} diff --git a/backend/main.go b/backend/main.go index 196dcd0..25c9d51 100644 --- a/backend/main.go +++ b/backend/main.go @@ -99,4 +99,4 @@ func main() { protectedRoutes.POST("/payment-intent", paymentHandler.CreatePaymentIntent) router.Run("localhost:" + port) -} \ No newline at end of file +} From a26acebd70aba3a72db031a28aab88492dcae344 Mon Sep 17 00:00:00 2001 From: Jillian Xu Date: Sun, 29 Dec 2024 23:48:23 -0500 Subject: [PATCH 6/7] Remove React.FC --- frontend/src/pages/About.tsx | 4 +--- frontend/src/pages/Home.tsx | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/About.tsx b/frontend/src/pages/About.tsx index 9a4cad0..e6ecf0f 100644 --- a/frontend/src/pages/About.tsx +++ b/frontend/src/pages/About.tsx @@ -1,6 +1,4 @@ -import React from 'react'; - -const About: React.FC = () => { +const About = () => { return (
{/* Hero / Header section */} diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index 018974c..cbcd2f1 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -1,8 +1,7 @@ import React, { useEffect, useState } from 'react'; import useAuth from '@/hooks/useAuth'; -import axios from '@/lib/axios'; -const GuestHome: React.FC = () => { +const GuestHome = () => { return (
@@ -95,7 +94,7 @@ const SignedInHome: React.FC<{ user: User }> = ({ user }) => { ); }; -const Home: React.FC = () => { +const Home = () => { const { currentUser: fbUser } = useAuth(); const [signedInUser, setSignedInUser] = useState(null); From e3da0044a106a2c32a759d12ef9e35c073a79fdb Mon Sep 17 00:00:00 2001 From: Jillian Xu Date: Sun, 29 Dec 2024 23:52:21 -0500 Subject: [PATCH 7/7] Update user call to remove React.FC --- frontend/src/pages/Home.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index cbcd2f1..6e9bf20 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import useAuth from '@/hooks/useAuth'; const GuestHome = () => { @@ -38,15 +38,15 @@ interface User { // etc. } -const SignedInHome: React.FC<{ user: User }> = ({ user }) => { +// Define the prop type separately or inline +function SignedInHome({ user }: { user: User }) { return (
{/* Hero / Welcome section */}
@@ -92,9 +92,9 @@ const SignedInHome: React.FC<{ user: User }> = ({ user }) => {
); -}; +} -const Home = () => { +function Home() { const { currentUser: fbUser } = useAuth(); const [signedInUser, setSignedInUser] = useState(null); @@ -129,6 +129,6 @@ const Home = () => { } return ; -}; +} export default Home;