Skip to content

Add player standing admin page for centralized player lookup and cheat level management - #316

Draft
owens1127 with Copilot wants to merge 4 commits into
mainfrom
copilot/add-player-standing-page
Draft

Add player standing admin page for centralized player lookup and cheat level management#316
owens1127 with Copilot wants to merge 4 commits into
mainfrom
copilot/add-player-standing-page

Conversation

Copilot AI commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

Adds /admin/players page for looking up players by membershipId to view standing, flags, and blacklisted instances. Integrates with new API endpoint GET /admin/reporting/player-standing/{membershipId}.

Changes

  • Sidebar: Added "Player Standing" entry after "Reporting" with UserSearch icon
  • Page: src/app/admin/players/page.tsx - standard Next.js page wrapper
  • Dashboard: src/components/admin/players/player-standing-dashboard.tsx
    • Search input for membershipId with loading/error/empty states
    • Player info card with cheat level dropdown and save button (reuses useRaidHubUpdatePlayer)
    • Recent flags table with color-coded probability and decoded bitmask detection reasons
    • Blacklisted instances table
  • API Hook: src/services/raidhub/usePlayerStanding.ts - follows useReportedInstance pattern
  • Types: Added AdminPlayerStandingResponse schema and /admin/reporting/player-standing/{membershipId} endpoint to openapi.d.ts

Implementation Details

Reuses existing patterns:

// Cheat level update follows PlayerBox pattern from instance-info-tab.tsx
const updatePlayer = useRaidHubUpdatePlayer(membershipId, {
    onSuccess: () => {
        queryClient.setQueryData<RaidHubPlayerStandingResponse>(
            ["raidhub", "player-standing", membershipId],
            old => ({...old, playerInfo: {...old.playerInfo, cheatLevel: selectedCheatLevel}})
        )
    }
})

Color coding and bitmask decoding match existing PlayerOtherFlags and InstanceFlagArea components.

Original prompt

Overview

Add a new "Player Standing" admin page at /admin/players that allows admins to look up a player by membershipId and view their standing, recent flags, blacklisted instances, and cheat level — with the ability to update the cheat level directly.

This page consumes a new API endpoint GET /admin/reporting/player-standing/:membershipId being added in a companion PR on Raid-Hub/API. That endpoint returns:

{
  "playerInfo": { "membershipId", "membershipType", "iconPath", "displayName", "bungieGlobalDisplayName", "bungieGlobalDisplayNameCode", "lastSeen", "isPrivate", "cheatLevel" },
  "recentFlags": [{ "instanceId", "membershipId", "cheatCheckVersion", "cheatCheckBitmask", "cheatProbability", "flaggedAt", "instanceDate" }],
  "blacklistedInstances": [{ "instanceId", "instanceDate", "reason", "individualReason", "createdAt" }]
}

Current State

  • The admin dashboard exists at /admin with a sidebar defined in src/app/admin/sidebar.tsx
  • Current sidebar routes: Reporting (/reporting), Badges (/badges), Vanity (/vanity), Query Tool (/query), Cache (/cache)
  • Existing admin pages follow the pattern of: src/app/admin/<section>/page.tsx importing a dashboard component from src/components/admin/<section>/
  • The existing reporting page (src/components/admin/reporting/) already has great PlayerBox, PlayerBlacklistedInstances, PlayerOtherFlags, and InstanceFlagArea components in src/components/admin/reporting/tabs/instance-info-tab.tsx that display exactly the kind of data we need — reuse/reference these patterns
  • API hooks follow patterns in src/services/raidhub/ — see useReportedInstance.ts for the standing query pattern and useRaidHubUpdatePlayer.ts for the player update pattern
  • OpenAPI types are in src/services/raidhub/openapi.d.ts and derived types in src/services/raidhub/types.ts
  • The getRaidHubApi and postRaidHubApi helpers are used for API calls from src/services/raidhub/common
  • CheatLevel type already exists as Component<"CheatLevel"> (0 | 1 | 2 | 3 | 4)
  • useRaidHubUpdatePlayer hook already exists and works with PATCH /admin/reporting/player/:membershipId
  • The cheat check bitmask decoding helper getCheatCheckReasonsFromBitmask exists in src/components/admin/reporting/tabs/instance-info-tab.tsx

Requirements

1. Add sidebar entry (src/app/admin/sidebar.tsx)

Add a new entry to the adminRoutes array:

{
    name: "Player Standing",
    path: "/players",
    Icon: UserSearch // or User or Users from lucide-react
}

Place it after "Reporting" since it's related.

2. Create the page (src/app/admin/players/page.tsx)

Follow the same pattern as other admin pages:

import { type Metadata } from "next"
import { PlayerStandingDashboard } from "~/components/admin/players/player-standing-dashboard"

export const metadata: Metadata = {
    title: "Player Standing"
}

export default function Page() {
    return <PlayerStandingDashboard />
}

3. Create the dashboard component (src/components/admin/players/player-standing-dashboard.tsx)

This is the main component. It should be a "use client" component with:

Search Section:

  • A text input for entering a player's membershipId (the big numeric Destiny membership ID like 4611686018488107374)
  • A search/submit button
  • When submitted, fetch from the new API endpoint

Player Standing Display (shown after search):

Use the existing component patterns from instance-info-tab.tsx. The page should show:

a) Player Info Card — Display the player's:

  • Icon (from playerInfo.iconPath, use bungieIconUrl helper from ~/util/destiny)
  • Display name (use getBungieDisplayName helper from ~/util/destiny)
  • MembershipId (linked to /profile/{membershipId})
  • Cheat Level with a dropdown to change it (reuse the exact pattern from PlayerBox in instance-info-tab.tsxSelect with colored variants based on level, "Save Cheat Level" button that calls useRaidHubUpdatePlayer)
  • Last seen date
  • Total clears (if available in playerInfo)

b) Recent Flags Table — A table showing the player's recent flags across all instances:

  • Columns: Instance ID (linked to /pgcr/{instanceId}), Instance Date, Flagged At, Cheat Probability (color-coded like existing), Detection (decoded bitmask), Cheat Check Version
  • Reuse the same color coding pattern from PlayerOtherFlags in instance-info-tab.tsx
  • Use shadcn Table, TableHeader, TableRow, TableHead, TableBody, TableCell components

c) Blacklisted Instances Table — A table showing instances the player was blacklisted in:

  • Columns: Instance ID (linked to /pgcr/{instanceId}), Instance Date, Reason, Individual Reason, Blacklisted At
  • Reuse the same pattern from PlayerBlacklistedInstances in instance-info-tab.tsx

Use the AdminPageHeader component (seen in reporting-dashboard.tsx) for the page title.

**Use the `...

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercel Bot commented Feb 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
raid-hub Error Error Feb 6, 2026 5:59am

Request Review

…ality

Co-authored-by: owens1127 <98496129+owens1127@users.noreply.github.com>
Copilot AI and others added 2 commits February 6, 2026 05:58
Co-authored-by: owens1127 <98496129+owens1127@users.noreply.github.com>
Co-authored-by: owens1127 <98496129+owens1127@users.noreply.github.com>
Copilot AI changed the title [WIP] Add admin page for player standing overview Add player standing admin page for centralized player lookup and cheat level management Feb 6, 2026
Copilot AI requested a review from owens1127 February 6, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants