diff --git a/src/app/app/(global)/amigos/loading.tsx b/src/app/app/(global)/amigos/loading.tsx new file mode 100644 index 0000000..4ca2e9b --- /dev/null +++ b/src/app/app/(global)/amigos/loading.tsx @@ -0,0 +1,19 @@ +import { Skeleton } from "@/components/ui/skeleton"; + +/** Silueta de Amigos: encabezado, carril de pestañas y filas de gente. */ +export default function AmigosLoading() { + return ( +
- Busca a tus compañeros por{" "} - @usuario{" "} - o mándales tu link de invitación. Cuando acepten verás su progreso en - tu inicio. -
-- Tu handle es{" "} - - @{username} - - . -
-- Compite en XP de la semana contra tu división. Sube de liga si - terminas arriba; baja si te quedas atrás — todo se reinicia cada - lunes. + Compites con el XP que ganas esta semana contra tu división. Todo + se reinicia el lunes.
Liga {LEAGUE_TIER_LABEL[standing.tier]}
-- {standing.rows.length} {standing.rows.length === 1 ? "alumno" : "alumnos"} en tu división -
-- #{standing.rows.find((r) => r.isSelf)?.rank ?? "—"} -
-tu lugar
++ Liga {LEAGUE_TIER_LABEL[standing.tier]} +
++ {standing.rows.length}{" "} + {standing.rows.length === 1 ? "alumno" : "alumnos"} · termina{" "} + {relativeFromNow(standing.season.endsAt)} +
++ #{self?.rank ?? "—"} +
+
+ {self ? (
+ <>
+
+ {parts.join(" · ")}. +
+ ); +} + +function NearbySection({ standing }: { standing: LeagueStanding }) { const selfIdx = standing.rows.findIndex((r) => r.isSelf); if (selfIdx < 0 || selfIdx < 3) return null; // ya está en el top3 mostrado arriba @@ -125,12 +178,19 @@ function StandingRow({ row, standing, }: { - row: { userId: string; username: string; name: string; image: string | null; xp: number; rank: number; isSelf: boolean }; - standing: { promoteCount: number; relegateCount: number; rows: { rank: number }[] }; + row: LeagueStanding["rows"][number]; + standing: LeagueStanding; }) { - const n = standing.rows.length; - const inPromotionZone = row.rank <= standing.promoteCount; - const inRelegationZone = row.rank > n - standing.relegateCount; + // La misma función que decide el rollover decide qué flecha se pinta: + // en Diamante nadie sube (held_at_ceiling) y en Bronce nadie baja + // (held_at_floor), así que ahí no se marca ninguna zona. + const { outcome } = resolveRolloverOutcome( + row.rank, + standing.rows.length, + standing.tier, + ); + const inPromotionZone = outcome === "promoted"; + const inRelegationZone = outcome === "relegated"; return (+ @{profile.username} +
++ Miembro desde {memberSince} +
- @{profile.username} -
-- Miembro desde {memberSince} -
- {user.email} +
+ @{user.username}
-- Miembro desde {memberSince} +
+ {user.email} · desde {memberSince}
+ + Ver mi perfil público + + + {" "}— es lo que ven tus compañeros. + +
+ ) : null} +