Leagues where the user is a commissioner but has no team are now shown in a "Leagues I Commish" subsection below their member leagues, rather than silently appearing with no stats. A live draft always takes priority over the commish-only row so commissioners still see the draft banner. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
27e8ae505a
commit
6c3065f6f2
3 changed files with 45 additions and 3 deletions
|
|
@ -18,6 +18,7 @@ export interface LeagueRowProps {
|
|||
draftDateTime?: string | null;
|
||||
picksUntilMyTurn?: number;
|
||||
draftPosition?: number;
|
||||
isCommishOnly?: boolean;
|
||||
}
|
||||
|
||||
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
||||
|
|
@ -205,10 +206,28 @@ function CompletedRow({
|
|||
);
|
||||
}
|
||||
|
||||
// ─── Commish-only row ─────────────────────────────────────────────────────────
|
||||
|
||||
function CommishOnlyRow({ leagueId, leagueName }: Pick<LeagueRowProps, "leagueId" | "leagueName">) {
|
||||
return (
|
||||
<Link
|
||||
to={`/leagues/${leagueId}`}
|
||||
className="flex items-center gap-3 rounded-lg bg-card px-3 py-3 sm:px-5 sm:py-4 hover:bg-white/[0.06] transition-colors"
|
||||
>
|
||||
<LeagueAvatar leagueId={leagueId} leagueName={leagueName} />
|
||||
<div className="min-w-0">
|
||||
<p className="font-semibold leading-tight truncate">{leagueName}</p>
|
||||
<p className="text-xs text-muted-foreground mt-0.5">Commissioner</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Public export ────────────────────────────────────────────────────────────
|
||||
|
||||
export function LeagueRow(props: LeagueRowProps) {
|
||||
if (props.status === "draft") return <DraftRow {...props} />;
|
||||
if (props.isCommishOnly) return <CommishOnlyRow {...props} />;
|
||||
if (props.status === "active") return <ActiveRow {...props} />;
|
||||
if (props.status === "pre_draft") return <PreDraftRow {...props} />;
|
||||
return <CompletedRow {...props} />;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@ interface MyLeaguesCardProps {
|
|||
}
|
||||
|
||||
export function MyLeaguesCard({ leagues, viewAllUrl }: MyLeaguesCardProps) {
|
||||
const sorted = leagues.toSorted((a, b) => {
|
||||
const memberLeagues = leagues.filter((l) => !l.isCommishOnly);
|
||||
const commishOnlyLeagues = leagues
|
||||
.filter((l) => l.isCommishOnly)
|
||||
.toSorted((a, b) => a.leagueName.localeCompare(b.leagueName));
|
||||
|
||||
const sortedMember = memberLeagues.toSorted((a, b) => {
|
||||
const statusDiff = STATUS_ORDER[a.status] - STATUS_ORDER[b.status];
|
||||
if (statusDiff !== 0) return statusDiff;
|
||||
if (a.status === "active") {
|
||||
|
|
@ -35,11 +40,13 @@ export function MyLeaguesCard({ leagues, viewAllUrl }: MyLeaguesCardProps) {
|
|||
</Link>
|
||||
) : undefined;
|
||||
|
||||
const isEmpty = sortedMember.length === 0 && commishOnlyLeagues.length === 0;
|
||||
|
||||
return (
|
||||
<Card className="bg-[#181b22] gap-2">
|
||||
<SectionCardHeader icon={Shield} title="My Leagues" right={right} />
|
||||
<CardContent className="px-3 sm:px-6">
|
||||
{sorted.length === 0 ? (
|
||||
{isEmpty ? (
|
||||
<div className="py-4 text-center">
|
||||
<p className="text-sm text-muted-foreground mb-3">
|
||||
You aren't a member of any leagues yet.
|
||||
|
|
@ -53,9 +60,20 @@ export function MyLeaguesCard({ leagues, viewAllUrl }: MyLeaguesCardProps) {
|
|||
</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{sorted.map((league) => (
|
||||
{sortedMember.map((league) => (
|
||||
<LeagueRow key={league.leagueId} {...league} />
|
||||
))}
|
||||
{commishOnlyLeagues.length > 0 && (
|
||||
<>
|
||||
{sortedMember.length > 0 && <div className="border-t border-border/40 pt-1" />}
|
||||
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground px-1">
|
||||
Leagues I Commish
|
||||
</p>
|
||||
{commishOnlyLeagues.map((league) => (
|
||||
<LeagueRow key={league.leagueId} {...league} />
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
|
|
|
|||
|
|
@ -63,9 +63,12 @@ export async function loader(args: Route.LoaderArgs) {
|
|||
let completionPercentage = 0;
|
||||
let picksUntilMyTurn: number | undefined;
|
||||
let draftPosition: number | undefined;
|
||||
// False when there's no current season — a commish with no season has no team by definition.
|
||||
let hasTeam = false;
|
||||
|
||||
if (league.currentSeasonId && seasonWithSports?.seasonSports) {
|
||||
const myTeam = await findTeamByOwnerAndSeason(userId, league.currentSeasonId);
|
||||
hasTeam = !!myTeam;
|
||||
|
||||
if (myTeam) {
|
||||
// Fetch standing, completion %, and calendar events in parallel
|
||||
|
|
@ -153,6 +156,7 @@ export async function loader(args: Route.LoaderArgs) {
|
|||
draftPosition,
|
||||
draftDateTime: season?.draftDateTime?.toISOString() ?? null,
|
||||
calendarEvents,
|
||||
hasTeam,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
@ -209,6 +213,7 @@ export default function Home({ loaderData }: Route.ComponentProps) {
|
|||
picksUntilMyTurn: league.picksUntilMyTurn,
|
||||
draftPosition: league.draftPosition,
|
||||
draftDateTime: league.draftDateTime,
|
||||
isCommishOnly: !league.hasTeam,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue