style: improve code formatting and readability in league route component
This commit is contained in:
parent
61929536a1
commit
1b790ed5bc
1 changed files with 42 additions and 21 deletions
|
|
@ -40,51 +40,69 @@ export async function loader(args: Route.LoaderArgs) {
|
||||||
const commissioners = await findCommissionersByLeagueId(leagueId);
|
const commissioners = await findCommissionersByLeagueId(leagueId);
|
||||||
|
|
||||||
// Check if current user is a commissioner
|
// Check if current user is a commissioner
|
||||||
const isUserCommissioner = userId ? await isCommissioner(leagueId, userId) : false;
|
const isUserCommissioner = userId
|
||||||
|
? await isCommissioner(leagueId, userId)
|
||||||
|
: false;
|
||||||
|
|
||||||
// Check if user is a member (has a team in current season)
|
// Check if user is a member (has a team in current season)
|
||||||
const isUserMember = userId ? await isUserLeagueMember(leagueId, userId) : false;
|
const isUserMember = userId
|
||||||
|
? await isUserLeagueMember(leagueId, userId)
|
||||||
|
: false;
|
||||||
|
|
||||||
// Check access: user must be a commissioner, a member, or an admin
|
// Check access: user must be a commissioner, a member, or an admin
|
||||||
// If not logged in or not authorized, throw 403
|
// If not logged in or not authorized, throw 403
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
throw new Response("You must be logged in to view this league", { status: 401 });
|
throw new Response("You must be logged in to view this league", {
|
||||||
|
status: 401,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isUserCommissioner && !isUserMember) {
|
if (!isUserCommissioner && !isUserMember) {
|
||||||
throw new Response("You do not have access to this league", { status: 403 });
|
throw new Response("You do not have access to this league", {
|
||||||
|
status: 403,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch teams for current season
|
// Fetch teams for current season
|
||||||
const teams = season ? await findTeamsBySeasonId(season.id) : [];
|
const teams = season ? await findTeamsBySeasonId(season.id) : [];
|
||||||
|
|
||||||
// Fetch user data for team owners
|
// Fetch user data for team owners
|
||||||
const ownerIds = teams.map(t => t.ownerId).filter((id): id is string => id !== null);
|
const ownerIds = teams
|
||||||
|
.map((t) => t.ownerId)
|
||||||
|
.filter((id): id is string => id !== null);
|
||||||
const uniqueOwnerIds = [...new Set(ownerIds)];
|
const uniqueOwnerIds = [...new Set(ownerIds)];
|
||||||
const owners = await Promise.all(
|
const owners = await Promise.all(
|
||||||
uniqueOwnerIds.map(async (ownerId) => {
|
uniqueOwnerIds.map(async (ownerId) => {
|
||||||
const user = await findUserByClerkId(ownerId);
|
const user = await findUserByClerkId(ownerId);
|
||||||
return user ? { clerkId: ownerId, name: user.username || user.displayName } : null;
|
return user
|
||||||
|
? { clerkId: ownerId, name: user.username || user.displayName }
|
||||||
|
: null;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const ownerMap = new Map(
|
const ownerMap = new Map(
|
||||||
owners.filter((o): o is NonNullable<typeof o> => o !== null).map(o => [o.clerkId, o.name])
|
owners
|
||||||
|
.filter((o): o is NonNullable<typeof o> => o !== null)
|
||||||
|
.map((o) => [o.clerkId, o.name])
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fetch user data for commissioners
|
// Fetch user data for commissioners
|
||||||
const commissionerIds = commissioners.map(c => c.userId);
|
const commissionerIds = commissioners.map((c) => c.userId);
|
||||||
const commissionerUsers = await Promise.all(
|
const commissionerUsers = await Promise.all(
|
||||||
commissionerIds.map(async (commissionerId) => {
|
commissionerIds.map(async (commissionerId) => {
|
||||||
const user = await findUserByClerkId(commissionerId);
|
const user = await findUserByClerkId(commissionerId);
|
||||||
return user ? { clerkId: commissionerId, name: user.username || user.displayName } : null;
|
return user
|
||||||
|
? { clerkId: commissionerId, name: user.username || user.displayName }
|
||||||
|
: null;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const commissionerMap = new Map(
|
const commissionerMap = new Map(
|
||||||
commissionerUsers.filter((c): c is NonNullable<typeof c> => c !== null).map(c => [c.clerkId, c.name])
|
commissionerUsers
|
||||||
|
.filter((c): c is NonNullable<typeof c> => c !== null)
|
||||||
|
.map((c) => [c.clerkId, c.name])
|
||||||
);
|
);
|
||||||
|
|
||||||
// Count available teams
|
// Count available teams
|
||||||
const availableTeamCount = teams.filter(t => !t.ownerId).length;
|
const availableTeamCount = teams.filter((t) => !t.ownerId).length;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
league,
|
league,
|
||||||
|
|
@ -100,12 +118,12 @@ export async function loader(args: Route.LoaderArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
||||||
const {
|
const {
|
||||||
league,
|
league,
|
||||||
season,
|
season,
|
||||||
teams,
|
teams,
|
||||||
commissioners,
|
commissioners,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
isUserCommissioner,
|
isUserCommissioner,
|
||||||
ownerMap,
|
ownerMap,
|
||||||
commissionerMap,
|
commissionerMap,
|
||||||
|
|
@ -127,14 +145,14 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
||||||
|
|
||||||
const handleCopyInviteLink = async () => {
|
const handleCopyInviteLink = async () => {
|
||||||
if (!season?.inviteCode) return;
|
if (!season?.inviteCode) return;
|
||||||
|
|
||||||
const inviteUrl = `${window.location.origin}/i/${season.inviteCode}`;
|
const inviteUrl = `${window.location.origin}/i/${season.inviteCode}`;
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(inviteUrl);
|
await navigator.clipboard.writeText(inviteUrl);
|
||||||
setCopied(true);
|
setCopied(true);
|
||||||
toast.success("Invite link copied to clipboard!");
|
toast.success("Invite link copied to clipboard!");
|
||||||
setTimeout(() => setCopied(false), 2000);
|
setTimeout(() => setCopied(false), 2000);
|
||||||
} catch (err) {
|
} catch {
|
||||||
toast.error("Failed to copy invite link");
|
toast.error("Failed to copy invite link");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -171,7 +189,9 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Invite Link</CardTitle>
|
<CardTitle>Invite Link</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Share this link to invite people to join your league ({availableTeamCount} spot{availableTeamCount !== 1 ? "s" : ""} available)
|
Share this link to invite people to join your league (
|
||||||
|
{availableTeamCount} spot{availableTeamCount !== 1 ? "s" : ""}{" "}
|
||||||
|
available)
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-3">
|
<CardContent className="space-y-3">
|
||||||
|
|
@ -266,7 +286,8 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Commissioners</CardTitle>
|
<CardTitle>Commissioners</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
{commissioners.length} commissioner{commissioners.length !== 1 ? "s" : ""}
|
{commissioners.length} commissioner
|
||||||
|
{commissioners.length !== 1 ? "s" : ""}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue