-
Notifications
You must be signed in to change notification settings - Fork 2
Add leaderboard-frontend app with UI components #708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: aryan/swarm-leadership-page-mvp
Are you sure you want to change the base?
Add leaderboard-frontend app with UI components #708
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
cf4829f to
8070a0f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new leaderboard frontend application with UI components for managing user profiles, guilds, games, and wallet connections.
- Introduces React components for guild and game creation, display, and management.
- Implements user profile handling with wallet connection integration.
- Updates routing, API clients, and documentation to support the new application.
Reviewed Changes
Copilot reviewed 26 out of 30 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| apps/leaderboard-frontend/src/components/guild/GuildCreateBox.tsx | Component for creating a new guild |
| apps/leaderboard-frontend/src/components/guild/GuildCard.tsx | Renders guild details with manage button |
| apps/leaderboard-frontend/src/components/games/ScoreList.tsx | Displays a list of game scores |
| apps/leaderboard-frontend/src/components/games/ScoreForm.tsx | Form for submitting game scores |
| apps/leaderboard-frontend/src/components/games/GameDetails.tsx | Displays game details and score submission |
| apps/leaderboard-frontend/src/components/games/GameCreateBox.tsx | Component for creating a new game |
| apps/leaderboard-frontend/src/components/games/GameCard.tsx | Renders game details with manage button |
| apps/leaderboard-frontend/src/components/WalletConnect.tsx | Integrates wallet connection via HappyWallet |
| apps/leaderboard-frontend/src/components/ProfilePage.tsx | Manages user profile display and editing |
| apps/leaderboard-frontend/src/components/HomeLogoButton.tsx | Button linking to home via logo image |
| apps/leaderboard-frontend/src/components/GuildsPage.tsx | Main page for guild management and creation |
| apps/leaderboard-frontend/src/components/GamesPage.tsx | Main page for game management and creation |
| apps/leaderboard-frontend/src/clients.ts | Exports API clients via HappyTech core functions |
| apps/leaderboard-frontend/src/App.tsx | Application routing and layout |
| apps/leaderboard-frontend/index.html | HTML entry point for the app |
| apps/leaderboard-frontend/README.md | Documentation and quickstart instructions |
Files not reviewed (4)
- Makefile: Language not supported
- apps/leaderboard-frontend/Makefile: Language not supported
- apps/leaderboard-frontend/biome.jsonc: Language not supported
- apps/leaderboard-frontend/package.json: Language not supported
Comments suppressed due to low confidence (1)
apps/leaderboard-frontend/src/components/GuildsPage.tsx:81
- Similarly, converting profile.id to a number when creating a guild may lead to type inconsistencies with the expected string type. Verify the backend expectations and adjust the conversion or type definitions accordingly.
creator_id: Number(profile.id),
| useEffect(() => { | ||
| if (!profile?.id) return | ||
| setLoading(true) | ||
| fetch(`/api/guilds?creator_id=${Number(profile.id)}`) |
Copilot
AI
Apr 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conversion of profile.id to a number might be inconsistent with its type (string) declared in UserProfile. Consider using profile.id directly or update the type definitions so that the API consumer and provider agree on the data type.
| fetch(`/api/guilds?creator_id=${Number(profile.id)}`) | |
| fetch(`/api/guilds?creator_id=${profile.id}`) |
8be4300 to
d8b3ca3
Compare
Deploying happychain with
|
| Latest commit: |
91dcf96
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://005da51e.happychain.pages.dev |
| Branch Preview URL: | https://aryan-swarm-leaderboard-fron.happychain.pages.dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new leaderboard frontend app with a set of React components for managing user profiles, games, guilds, scores, and leaderboards. Key changes include the creation of new UI components (e.g. ScoreList, ScoreForm, GameDetails), page containers (e.g. GamesPage, GuildsPage, ProfilePage), and integration with the HappyWallet provider for authentication.
Reviewed Changes
Copilot reviewed 29 out of 33 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| apps/leaderboard-frontend/src/components/games/ScoreList.tsx | New component for listing scores |
| apps/leaderboard-frontend/src/components/games/ScoreForm.tsx | New form for submitting scores |
| apps/leaderboard-frontend/src/components/games/MyScoresCard.tsx | New component displaying the user’s game scores |
| apps/leaderboard-frontend/src/components/games/GameDetails.tsx | Displays game details and incorporates score submission/listing |
| apps/leaderboard-frontend/src/components/games/GameCreateBox.tsx | Component for creating new games |
| apps/leaderboard-frontend/src/components/games/GameCard.tsx | New card component representing a game |
| apps/leaderboard-frontend/src/components/WalletConnect.tsx | Minimal wallet connect component |
| apps/leaderboard-frontend/src/components/ProfilePage.tsx | Profile management with create/edit functionality |
| apps/leaderboard-frontend/src/components/Leaderboards.tsx | Displays global and guild leaderboards |
| apps/leaderboard-frontend/src/components/HomeLogoButton.tsx | Logo button linking back to home |
| apps/leaderboard-frontend/src/components/GuildsPage.tsx | Guild management page |
| apps/leaderboard-frontend/src/components/GamesPage.tsx | Main games listing and management page |
| apps/leaderboard-frontend/src/clients.ts | API client creation |
| apps/leaderboard-frontend/src/App.tsx | Main router and layout for the app |
| apps/leaderboard-frontend/index.html | HTML entry point |
| apps/leaderboard-frontend/README.md | Documentation update for app setup |
Files not reviewed (4)
- Makefile: Language not supported
- apps/leaderboard-frontend/Makefile: Language not supported
- apps/leaderboard-frontend/biome.jsonc: Language not supported
- apps/leaderboard-frontend/package.json: Language not supported
| const [error, _setError] = useState<string | null>(null) | ||
|
|
||
| useEffect(() => { | ||
| setLoading(true) | ||
| fetch(`/api/games/${game.id}/scores`) | ||
| .then((res) => (res.ok ? res.json() : null)) |
Copilot
AI
Apr 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error state is never updated because the setter is unused (_setError); consider renaming it to setError and using it to update the error message when a fetch failure occurs.
| const [error, _setError] = useState<string | null>(null) | |
| useEffect(() => { | |
| setLoading(true) | |
| fetch(`/api/games/${game.id}/scores`) | |
| .then((res) => (res.ok ? res.json() : null)) | |
| const [error, setError] = useState<string | null>(null) | |
| useEffect(() => { | |
| setLoading(true) | |
| fetch(`/api/games/${game.id}/scores`) | |
| .then((res) => { | |
| if (res.ok) { | |
| return res.json() | |
| } else { | |
| throw new Error("Failed to fetch scores") | |
| } | |
| }) |
7cd346e to
9c9faf6
Compare
4043d3d to
bedd278
Compare
9c9faf6 to
a6dd414
Compare
bedd278 to
0bd2a4b
Compare
c3e12bd to
fb5151e
Compare
d0c752c to
d013d49
Compare
d5218f2 to
2942012
Compare
2942012 to
91dcf96
Compare
ca6f30b to
a2c3cc7
Compare
a2c3cc7 to
b5445e1
Compare
44888b4 to
e1fc16a
Compare
b5445e1 to
5e98b69
Compare
5e98b69 to
74cfd9a
Compare
e1fc16a to
28127a0
Compare
not-reed
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i forgot to submit my comments yesterday 😅 here you go
| <link rel="icon" type="image/svg+xml" href="/happychain.png" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>Leaderboard Frontend</title> | ||
| <!-- <link rel="stylesheet" href="/src/index.css"> --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no styles! 👀
| @@ -0,0 +1,52 @@ | |||
| import { Link, Route, BrowserRouter as Router, Routes } from "react-router-dom" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error: The following dependencies are imported but could not be resolved:
react-router-dom
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also why react-router-dom and not the main package react-router for a new project
(or tanstack router for that matter to line up with the iframe?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be new logo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets get a new background already 😆
| }, | ||
| "devDependencies": { | ||
| "@happy.tech/configs": "workspace:0.1.0", | ||
| "@types/react": "^18.3.4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you seem to be missing packages you are using 🧐
| }, | ||
| }, | ||
| }, | ||
| preview: { port: 6002, strictPort: true }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey, this ports taken, pick a new port 😆 6004 maybe
| @@ -0,0 +1,53 @@ | |||
| .leaderboards-container { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interestingly (to me anyways) none of these styles are scoped in any way, and applied globally.
I think it would be much clearer to have a 'styles' folder which contained
- styles/index.css
- styles/leaderboard.css
and your index.css can @import './leaderboard'
if you just open this up, and start at the App.tsx, theres currently not much for an indication these styles are pulled in and applied everywhere - could be confusing if you ever need to fix a styling bug
| @@ -0,0 +1,126 @@ | |||
| import type React from "react" | |||
| import { useEffect, useState } from "react" | |||
| import "../index.css" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is already imported in App.tsx, no need to import it here
| import type React from "react" | ||
| import { useEffect, useState } from "react" | ||
| import "../index.css" | ||
| import "./leaderboards.css" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see me comment on this file below, but importing into this component feels to me like it should be scoped to this component and lazy loaded, however that doesn't seem to be the case. since its globally applied, just import it into index.css so its obvious where its coming from :)
| import Leaderboards from "./components/Leaderboards" | ||
| import ProfilePage from "./components/ProfilePage" | ||
| import WalletConnect from "./components/WalletConnect" | ||
| import "./index.css" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably since these are all global, this should be imported by main.tsx or just directly from the html (this is preferred)
if its imported like this, then they styles are imported as a a byproduct of the processed CSS, which means we need to load and parse the JS before the styles can be applied. If its in the index.html, it can load and be applied in parallel to the JS, which means it goes faster ;)

Linked Issues
Description
Added a new leaderboard frontend application that provides a user interface for the leaderboard system. The frontend includes:
The application is built with React and uses the HappyWallet provider for authentication. It communicates with the leaderboard backend API to manage user profiles, guilds, games, and scores.
To run:
From the project root
make setupmake leaderboard-frontend.dev(It also has corresponding .build and .prod targets)This will spin up the iframe and the frontend react server
(Make sure to have the iframe .env set up properly, but nothing out of the ordinary)
(Don't forget to start the backend server as well
make leaderboard-backend.dev)Toggle Checklist
Checklist
Basics
norswap/build-system-caching).Reminder: PR review guidelines
Correctness
testnet, mainnet, standalone wallet, ...).
Chrome browser, local development environment with leaderboard backend running on port 4545
Tested scenarios:
Wallet connection
Profile creation and editing
Guild creation and member management
Game creation and score submission
C4. I have performed a thorough self-review of my code after submitting the PR,
and have updated the code & comments accordingly.
Architecture & Documentation
(2) commenting these boundaries correctly, (3) adding inline comments for context when needed.
Public APIS and meaningful (non-local) internal APIs are properly documented in code comments.
in a Markdown document.
make changesetforbreaking and meaningful changes in packages (not required for cleanups & refactors).