Public "Online now" now lists only players whose game account is linked to a STAFF website user (admin/editor/moderator) — linked players are no longer exposed publicly with their name and location. listOnlineLinked joins through to users and filters on role; the section is relabeled "Staff online". Character/roster/vendor reads gain an admin bypass: admins may view any character's data, while players (and editor/moderator staff) stay limited to accounts they have personally linked. The bypass lives in the shared player controller and only ever widens access for genuine admins. Also finalizes the uo-link character/vendor front end (player + admin character sheets, VendorSales component, ShardChar removed) and regenerates swagger-output.json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018kj5s1QCKobuFPYmqxjy1q
30 lines
1.3 KiB
JavaScript
30 lines
1.3 KiB
JavaScript
import { useParams, Link } from 'react-router-dom'
|
|
import { Loading, ErrorState } from '../../components/PageState.jsx'
|
|
import CharacterSheet from '../../components/CharacterSheet.jsx'
|
|
import { useAsync } from '../../lib/useAsync.js'
|
|
import { api } from '../../api/client.js'
|
|
|
|
// A player's character sheet inside the portal. Owner-checked: the endpoint only
|
|
// returns a sheet for a character on an account linked to the caller.
|
|
export default function PlayerCharacter() {
|
|
const { serial } = useParams()
|
|
const { loading, error, data } = useAsync(() => api.player.shard.char(serial), [serial])
|
|
const restarting = error && error.status === 503
|
|
const forbidden = error && error.status === 403
|
|
|
|
return (
|
|
<div>
|
|
<p style={{ margin: '0 0 18px' }}>
|
|
<Link to="/player" className="sans" style={{ color: 'var(--accent)', textDecoration: 'none', fontSize: '0.86rem' }}>
|
|
← Back to characters
|
|
</Link>
|
|
</p>
|
|
{loading && <Loading />}
|
|
{restarting && <ErrorState message="The game server is restarting — try again shortly." />}
|
|
{forbidden && <ErrorState message="That character is not on an account linked to you." />}
|
|
{error && !restarting && !forbidden && <ErrorState message="Could not load that character right now." />}
|
|
{!loading && !error && data && <CharacterSheet char={data} />}
|
|
</div>
|
|
)
|
|
}
|