Add backfill normalized usernames button to Admin page
This commit is contained in:
@@ -85,3 +85,14 @@ export async function retroactiveAchievements(): Promise<RetroactiveAchievements
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
export interface BackfillUsernamesResult {
|
||||
backfilled: number;
|
||||
}
|
||||
|
||||
export async function backfillUsernames(): Promise<BackfillUsernamesResult> {
|
||||
const { data } = await apiClient.post<BackfillUsernamesResult>(
|
||||
'/admin/backfill-usernames',
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@ import {
|
||||
recalculateScores,
|
||||
generateChallenge,
|
||||
retroactiveAchievements,
|
||||
backfillUsernames,
|
||||
type PlatformStats,
|
||||
type AdminUser,
|
||||
type RecalculateResult,
|
||||
type RetroactiveAchievementsResult,
|
||||
type BackfillUsernamesResult,
|
||||
} from '@/api/admin';
|
||||
import {
|
||||
Shield,
|
||||
@@ -58,6 +60,8 @@ export default function Admin() {
|
||||
<Separator />
|
||||
<AchievementsSection />
|
||||
<Separator />
|
||||
<BackfillUsernamesSection />
|
||||
<Separator />
|
||||
<GenerateChallengeSection />
|
||||
<Separator />
|
||||
<UsersSection />
|
||||
@@ -227,6 +231,59 @@ function AchievementsSection() {
|
||||
);
|
||||
}
|
||||
|
||||
function BackfillUsernamesSection() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [result, setResult] = useState<BackfillUsernamesResult | null>(null);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const handleBackfill = async () => {
|
||||
setLoading(true);
|
||||
setError('');
|
||||
setResult(null);
|
||||
try {
|
||||
const res = await backfillUsernames();
|
||||
setResult(res);
|
||||
} catch {
|
||||
setError('Failed to backfill usernames.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className="mb-3 flex items-center gap-2 text-lg font-semibold">
|
||||
<Users className="h-5 w-5" />
|
||||
Backfill Normalized Usernames
|
||||
</h2>
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
Populates the normalized username column for existing users so they can
|
||||
be found via friend search.
|
||||
</p>
|
||||
<Button onClick={handleBackfill} disabled={loading}>
|
||||
{loading ? (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<Users className="mr-2 h-4 w-4" />
|
||||
)}
|
||||
Backfill Usernames
|
||||
</Button>
|
||||
{result && (
|
||||
<Alert className="mt-3">
|
||||
<AlertDescription>
|
||||
Backfilled {result.backfilled} user{result.backfilled !== 1 ? 's' : ''}.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
{error && (
|
||||
<Alert variant="destructive" className="mt-3">
|
||||
<AlertDescription>{error}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function GenerateChallengeSection() {
|
||||
const [date, setDate] = useState('');
|
||||
const [difficulty, setDifficulty] = useState('medium');
|
||||
|
||||
Reference in New Issue
Block a user