1
0
Fork 0

feat(preferences): expose XP mini-mode toggle in account settings

Add the mini XP display switch to PreferencesForm, wire it through the account page, and cover it in the integration test.

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-23 18:52:09 -04:00
parent b581670e72
commit 906af4feb1
3 changed files with 42 additions and 35 deletions

View file

@ -81,23 +81,24 @@ export default async function AccountPage() {
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Preferences</CardTitle>
<CardDescription>Control in-app notifications and display options.</CardDescription>
</CardHeader>
<CardContent>
<PreferencesForm
mutedAll={notifications?.mutedAll ?? false}
mutedTypes={notifications?.mutedTypes ?? []}
showCallsign={fullUser.preferences?.display?.showCallsign ?? false}
showVersionOverlay={fullUser.preferences?.display?.showVersionOverlay ?? true}
leadOrActual={fullUser.preferences?.display?.leadOrActual ?? "lead"}
discordEnabled={discord?.enabled ?? false}
discordMutedTypes={discord?.mutedTypes ?? []}
/>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Preferences</CardTitle>
<CardDescription>Control in-app notifications and display options.</CardDescription>
</CardHeader>
<CardContent>
<PreferencesForm
mutedAll={notifications?.mutedAll ?? false}
mutedTypes={notifications?.mutedTypes ?? []}
showCallsign={fullUser.preferences?.display?.showCallsign ?? false}
showVersionOverlay={fullUser.preferences?.display?.showVersionOverlay ?? true}
leadOrActual={fullUser.preferences?.display?.leadOrActual ?? "lead"}
discordEnabled={discord?.enabled ?? false}
discordMutedTypes={discord?.mutedTypes ?? []}
xpDisplayMini={fullUser.preferences?.display?.xpDisplayMini ?? false}
/>
</CardContent>
</Card>
</div>
</div>
);

View file

@ -20,6 +20,7 @@ interface PreferencesFormProps {
readonly leadOrActual: "lead" | "actual";
readonly discordEnabled: boolean;
readonly discordMutedTypes: readonly string[];
readonly xpDisplayMini: boolean;
}
export function PreferencesForm({
@ -30,6 +31,7 @@ export function PreferencesForm({
leadOrActual: initialLeadOrActual,
discordEnabled: initialDiscordEnabled,
discordMutedTypes: initialDiscordMutedTypes,
xpDisplayMini: initialXPDisplayMini,
}: PreferencesFormProps) {
const router = useRouter();
const [mutedAll, setMutedAll] = useState(initialMutedAll);
@ -41,6 +43,7 @@ export function PreferencesForm({
const [discordMutedTypes, setDiscordMutedTypes] = useState<string[]>(() => [
...initialDiscordMutedTypes,
]);
const [xpDisplayMini, setXPDisplayMini] = useState(initialXPDisplayMini);
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
@ -72,6 +75,7 @@ export function PreferencesForm({
leadOrActual,
discordEnabled,
discordMutedTypes,
xpDisplayMini,
});
if (!result.success) {
@ -101,24 +105,9 @@ export function PreferencesForm({
</CardHeader>
<CardContent className="flex flex-col gap-4">
<Label
htmlFor="showVersionOverlay"
htmlFor="showCallsign"
className="flex items-center justify-between gap-4 text-sm"
>
<span className="flex min-w-0 flex-col gap-1">
<span>Show version overlay</span>
<span className="text-sm font-normal text-muted-foreground">
Display the current build version at the top of every page.
</span>
</span>
<Switch
id="showVersionOverlay"
checked={showVersionOverlay}
onCheckedChange={setShowVersionOverlay}
aria-label="Show version overlay"
/>
</Label>
<Label htmlFor="showCallsign" className="flex items-center justify-between gap-4 text-sm">
<span className="flex min-w-0 flex-col gap-1">
<span>Show callsign instead of display name</span>
<span className="text-sm font-normal text-muted-foreground">
@ -131,6 +120,21 @@ export function PreferencesForm({
onCheckedChange={setShowCallsign}
aria-label="Show callsign instead of display name"
/>
</Label>
<Label htmlFor="xpDisplayMini" className="flex items-center justify-between gap-4 text-sm">
<span className="flex min-w-0 flex-col gap-1">
<span>Use mini mode for XP display</span>
<span className="text-sm font-normal text-muted-foreground">
Shows level name and XP instead of progress bar.
</span>
</span>
<Switch
id="xpDisplayMini"
checked={xpDisplayMini}
onCheckedChange={setXPDisplayMini}
aria-label="Use mini mode for XP display"
/>
</Label>
<div className="flex flex-col gap-2">

View file

@ -40,11 +40,12 @@ describe("PreferencesForm", () => {
leadOrActual: "lead",
discordEnabled: false,
discordMutedTypes: [],
xpDisplayMini: false,
}),
);
fireEvent.click(screen.getByRole("switch", { name: "Show version overlay" }));
fireEvent.click(screen.getByRole("switch", { name: "Show callsign instead of display name" }));
fireEvent.click(screen.getByRole("switch", { name: "Use mini mode for XP display" }));
fireEvent.click(screen.getByRole("switch", { name: "Mute all in-app notifications" }));
fireEvent.click(screen.getByRole("radio", { name: "Actual" }));
fireEvent.click(screen.getByRole("switch", { name: "Enable Discord notifications" }));
@ -60,10 +61,11 @@ describe("PreferencesForm", () => {
mutedAll: true,
mutedTypes: ["market:offer"],
showCallsign: true,
showVersionOverlay: false,
showVersionOverlay: true,
leadOrActual: "actual",
discordEnabled: true,
discordMutedTypes: ["market:offer"],
xpDisplayMini: true,
});
});
});