diff --git a/src/app/p/[secret]/pets/page.tsx b/src/app/p/[secret]/pets/page.tsx
index 283ddb0..43b4900 100644
--- a/src/app/p/[secret]/pets/page.tsx
+++ b/src/app/p/[secret]/pets/page.tsx
@@ -9,7 +9,7 @@ import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { PetAvatar } from "@/components/ui/pet-avatar";
-import { ReferralRankBadge } from "@/components/referrals/ReferralRankBadge";
+import { AchievedRankBadges } from "@/components/admin/pets/AchievedRankBadges";
import { PetDetailSheet } from "@/components/admin/pets/PetDetailSheet";
type Filter = "all" | "verified" | "founding" | "ranked" | "bannedOwner";
@@ -135,7 +135,7 @@ export default function AdminPetsPage() {
{pet.isVerified && }
{pet.isFoundingMember && }
-
+
{pet.species.name} |
diff --git a/src/components/admin/pets/AchievedRankBadges.tsx b/src/components/admin/pets/AchievedRankBadges.tsx
new file mode 100644
index 0000000..4db26a0
--- /dev/null
+++ b/src/components/admin/pets/AchievedRankBadges.tsx
@@ -0,0 +1,39 @@
+"use client";
+
+import { useReferralRanks } from "@/hooks/useReferralRanks";
+import { ReferralIcon } from "@/components/referrals/ReferralRankBadge";
+
+type Achievement = { rankId: string; revokedAt: Date | string | null; grantedManually: boolean };
+
+/**
+ * Admin → Tiere: alle Ränge, die der Owner je erreicht hat (found.md — vorher
+ * nur der höchste). Unabhängig vom Vorteil NAME_BADGE, weil das hier eine
+ * Übersicht fürs Team ist. Entzogene Ränge bleiben ausgegraut sichtbar.
+ */
+export function AchievedRankBadges({ achievements }: { achievements: Achievement[] }) {
+ const { byId } = useReferralRanks();
+ const items = achievements.flatMap((achievement) => {
+ const rank = byId.get(achievement.rankId);
+ return rank ? [{ achievement, rank }] : [];
+ });
+ if (items.length === 0) return null;
+
+ return (
+
+ {items.map(({ achievement, rank }) => {
+ const isRevoked = !!achievement.revokedAt;
+ const status = isRevoked ? " · entzogen" : achievement.grantedManually ? " · manuell vergeben" : "";
+ return (
+
+
+
+ );
+ })}
+
+ );
+}
diff --git a/src/trpc/routers/pet-admin.ts b/src/trpc/routers/pet-admin.ts
index b35e115..16c740f 100644
--- a/src/trpc/routers/pet-admin.ts
+++ b/src/trpc/routers/pet-admin.ts
@@ -97,6 +97,11 @@ export const petAdminRouter = router({
sponsorSince: true,
sponsorPeriodEnd: true,
ban: { select: { expiresAt: true } },
+ // found.md: die Liste zeigt alle erreichten Ränge, nicht nur den höchsten (Cache referralRankId).
+ rankAchievements: {
+ select: { rankId: true, revokedAt: true, grantedManually: true },
+ orderBy: { rank: { threshold: "asc" } },
+ },
},
},
_count: { select: { posts: true, followers: true } },