1
0
Fork 0

feat(xp): expose experience descriptions

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Jason Fraley 2026-08-27 18:36:11 -04:00
parent 21f61ca33f
commit 523b19ee52
3 changed files with 13 additions and 10 deletions

View file

@ -58,6 +58,7 @@ export default async function RootLayout(props: { children: React.ReactNode }) {
let xpLevel: ResolvedLevel = { let xpLevel: ResolvedLevel = {
levelName: "Recruit", levelName: "Recruit",
levelDesc: "",
progress: 0, progress: 0,
currentLevelXP: 0, currentLevelXP: 0,
nextLevelXP: null, nextLevelXP: null,
@ -96,6 +97,7 @@ export default async function RootLayout(props: { children: React.ReactNode }) {
limit: 100, limit: 100,
select: { select: {
name: true, name: true,
description: true,
requiredPoints: true, requiredPoints: true,
}, },
}), }),
@ -156,11 +158,7 @@ export default async function RootLayout(props: { children: React.ReactNode }) {
{user && <GameTickRealtime />} {user && <GameTickRealtime />}
{isLogistics && <ShipmentToasts />} {isLogistics && <ShipmentToasts />}
<Toaster /> <Toaster />
<ShimLoader <ShimLoader shims={shimEntries} userId={user?.id ?? null} userRoles={user?.roles ?? []} />
shims={shimEntries}
userId={user?.id ?? null}
userRoles={user?.roles ?? []}
/>
</body> </body>
</html> </html>
); );

View file

@ -38,7 +38,7 @@ export default async function HomePage() {
collection: "experience", collection: "experience",
sort: "requiredPoints", sort: "requiredPoints",
limit: 100, limit: 100,
select: { name: true, requiredPoints: true }, select: { name: true, description: true, requiredPoints: true },
}), }),
payload.find({ payload.find({
collection: "assignments", collection: "assignments",

View file

@ -1,10 +1,14 @@
import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext";
export type ExperienceLevel = { export type ExperienceLevel = {
name: string; name: string;
description: any;
requiredPoints: number; requiredPoints: number;
}; };
export type ResolvedLevel = { export type ResolvedLevel = {
levelName: string; levelName: string;
levelDesc: string;
progress: number; progress: number;
currentLevelXP: number; currentLevelXP: number;
nextLevelXP: number | null; nextLevelXP: number | null;
@ -19,13 +23,11 @@ export type ResolvedLevel = {
* current bracket: (xp - currentLevelXP) / (nextLevelXP - currentLevelXP). * current bracket: (xp - currentLevelXP) / (nextLevelXP - currentLevelXP).
* At the max level the bar sits at 100%. * At the max level the bar sits at 100%.
*/ */
export function resolveLevel( export function resolveLevel(xp: number, levels: ExperienceLevel[]): ResolvedLevel {
xp: number,
levels: ExperienceLevel[],
): ResolvedLevel {
if (levels.length === 0) { if (levels.length === 0) {
return { return {
levelName: "Unknown", levelName: "Unknown",
levelDesc: "Could not retrieve description.",
progress: 0, progress: 0,
currentLevelXP: 0, currentLevelXP: 0,
nextLevelXP: null, nextLevelXP: null,
@ -60,6 +62,9 @@ export function resolveLevel(
return { return {
levelName: current.name, levelName: current.name,
levelDesc:
convertLexicalToPlaintext({ data: current.description }) ||
"Failed to retrieve description!",
progress: Math.min(Math.max(progress, 0), 100), progress: Math.min(Math.max(progress, 0), 100),
currentLevelXP, currentLevelXP,
nextLevelXP, nextLevelXP,