enroll team polish?
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
"@tanstack/react-router-devtools": "^1.130.13",
|
"@tanstack/react-router-devtools": "^1.130.13",
|
||||||
"@tanstack/react-router-with-query": "^1.130.12",
|
"@tanstack/react-router-with-query": "^1.130.12",
|
||||||
"@tanstack/react-start": "^1.130.15",
|
"@tanstack/react-start": "^1.130.15",
|
||||||
|
"@tanstack/react-virtual": "^3.13.12",
|
||||||
"@tiptap/pm": "^3.4.3",
|
"@tiptap/pm": "^3.4.3",
|
||||||
"@tiptap/react": "^3.4.3",
|
"@tiptap/react": "^3.4.3",
|
||||||
"@tiptap/starter-kit": "^3.4.3",
|
"@tiptap/starter-kit": "^3.4.3",
|
||||||
|
|||||||
28
pb_migrations/1758123221_updated_reactions.js
Normal file
28
pb_migrations/1758123221_updated_reactions.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/// <reference path="../pb_data/types.d.ts" />
|
||||||
|
migrate((app) => {
|
||||||
|
const collection = app.findCollectionByNameOrId("pbc_1549310251")
|
||||||
|
|
||||||
|
// add field
|
||||||
|
collection.fields.addAt(3, new Field({
|
||||||
|
"cascadeDelete": false,
|
||||||
|
"collectionId": "pbc_2541054544",
|
||||||
|
"hidden": false,
|
||||||
|
"id": "relation2052834565",
|
||||||
|
"maxSelect": 1,
|
||||||
|
"minSelect": 0,
|
||||||
|
"name": "match",
|
||||||
|
"presentable": false,
|
||||||
|
"required": false,
|
||||||
|
"system": false,
|
||||||
|
"type": "relation"
|
||||||
|
}))
|
||||||
|
|
||||||
|
return app.save(collection)
|
||||||
|
}, (app) => {
|
||||||
|
const collection = app.findCollectionByNameOrId("pbc_1549310251")
|
||||||
|
|
||||||
|
// remove field
|
||||||
|
collection.fields.removeById("relation2052834565")
|
||||||
|
|
||||||
|
return app.save(collection)
|
||||||
|
})
|
||||||
@@ -32,7 +32,7 @@ export function createRouter() {
|
|||||||
defaultPreload: "intent",
|
defaultPreload: "intent",
|
||||||
defaultErrorComponent: DefaultCatchBoundary,
|
defaultErrorComponent: DefaultCatchBoundary,
|
||||||
scrollRestoration: true,
|
scrollRestoration: true,
|
||||||
defaultViewTransition: true,
|
defaultViewTransition: false,
|
||||||
}),
|
}),
|
||||||
queryClient
|
queryClient
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ export const Route = createFileRoute("/_authed")({
|
|||||||
},
|
},
|
||||||
pendingComponent: () => (
|
pendingComponent: () => (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Flex w='100%' align="center">
|
<Flex w='100%' h="40dvh" justify="center" align="flex-end">
|
||||||
<Loader />
|
<Loader size='xl' />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Layout>
|
</Layout>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
import {
|
import { Text, Group, Stack, Paper, Indicator, Box } from "@mantine/core";
|
||||||
Text,
|
|
||||||
Group,
|
|
||||||
Stack,
|
|
||||||
Paper,
|
|
||||||
Indicator,
|
|
||||||
Box,
|
|
||||||
} from "@mantine/core";
|
|
||||||
import { CrownIcon } from "@phosphor-icons/react";
|
import { CrownIcon } from "@phosphor-icons/react";
|
||||||
import { useNavigate } from "@tanstack/react-router";
|
import { useNavigate } from "@tanstack/react-router";
|
||||||
import { Match } from "../types";
|
import { Match } from "../types";
|
||||||
@@ -46,7 +39,13 @@ const MatchCard = ({ match }: MatchCardProps) => {
|
|||||||
offset={2}
|
offset={2}
|
||||||
>
|
>
|
||||||
<Box style={{ position: "relative" }}>
|
<Box style={{ position: "relative" }}>
|
||||||
<Paper px="md" py="md" withBorder radius="md" style={{ position: "relative", zIndex: 2 }}>
|
<Paper
|
||||||
|
px="md"
|
||||||
|
py="md"
|
||||||
|
withBorder
|
||||||
|
radius="md"
|
||||||
|
style={{ position: "relative", zIndex: 2 }}
|
||||||
|
>
|
||||||
<Stack gap="sm">
|
<Stack gap="sm">
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<Text size="xs" fw={600} lineClamp={1} c="dimmed">
|
<Text size="xs" fw={600} lineClamp={1} c="dimmed">
|
||||||
@@ -65,7 +64,16 @@ const MatchCard = ({ match }: MatchCardProps) => {
|
|||||||
style={{ position: "relative", cursor: "pointer" }}
|
style={{ position: "relative", cursor: "pointer" }}
|
||||||
onClick={handleHomeTeamClick}
|
onClick={handleHomeTeamClick}
|
||||||
>
|
>
|
||||||
<Avatar size={40} name={match.home?.name!} radius="sm" />
|
<Avatar
|
||||||
|
size={40}
|
||||||
|
name={match.home?.name!}
|
||||||
|
radius="sm"
|
||||||
|
src={
|
||||||
|
match.home?.logo
|
||||||
|
? `/api/files/teams/${match.home?.id}/${match.home?.logo}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
{isHomeWin && (
|
{isHomeWin && (
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
@@ -89,11 +97,7 @@ const MatchCard = ({ match }: MatchCardProps) => {
|
|||||||
{match.home?.name!}
|
{match.home?.name!}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
<Text
|
<Text size="xl" fw={700} c={"dimmed"}>
|
||||||
size="xl"
|
|
||||||
fw={700}
|
|
||||||
c={"dimmed"}
|
|
||||||
>
|
|
||||||
{match.home_cups}
|
{match.home_cups}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
@@ -104,7 +108,16 @@ const MatchCard = ({ match }: MatchCardProps) => {
|
|||||||
style={{ position: "relative", cursor: "pointer" }}
|
style={{ position: "relative", cursor: "pointer" }}
|
||||||
onClick={handleAwayTeamClick}
|
onClick={handleAwayTeamClick}
|
||||||
>
|
>
|
||||||
<Avatar size={40} name={match.away?.name!} radius="sm" />
|
<Avatar
|
||||||
|
size={40}
|
||||||
|
name={match.away?.name!}
|
||||||
|
radius="sm"
|
||||||
|
src={
|
||||||
|
match.away?.logo
|
||||||
|
? `/api/files/teams/${match.away?.id}/${match.away?.logo}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
{isAwayWin && (
|
{isAwayWin && (
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
@@ -128,11 +141,7 @@ const MatchCard = ({ match }: MatchCardProps) => {
|
|||||||
{match.away?.name}
|
{match.away?.name}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
<Text
|
<Text size="xl" fw={700} c={"dimmed"}>
|
||||||
size="xl"
|
|
||||||
fw={700}
|
|
||||||
c={"dimmed"}
|
|
||||||
>
|
|
||||||
{match.away_cups}
|
{match.away_cups}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
@@ -149,7 +158,8 @@ const MatchCard = ({ match }: MatchCardProps) => {
|
|||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
backgroundColor: "var(--mantine-color-gray-light)",
|
backgroundColor: "var(--mantine-color-gray-light)",
|
||||||
borderTop: "none",
|
borderTop: "none",
|
||||||
borderRadius: "0 0 var(--mantine-radius-md) var(--mantine-radius-md)",
|
borderRadius:
|
||||||
|
"0 0 var(--mantine-radius-md) var(--mantine-radius-md)",
|
||||||
border: "1px solid var(--mantine-color-default-border)",
|
border: "1px solid var(--mantine-color-default-border)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ const Profile = ({ id }: ProfileProps) => {
|
|||||||
const { data: matches } = usePlayerMatches(id);
|
const { data: matches } = usePlayerMatches(id);
|
||||||
const { data: stats, isLoading: statsLoading } = usePlayerStats(id);
|
const { data: stats, isLoading: statsLoading } = usePlayerStats(id);
|
||||||
|
|
||||||
|
console.log(player.teams)
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
label: "Overview",
|
label: "Overview",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Group,
|
Group,
|
||||||
UnstyledButton,
|
Button,
|
||||||
Text,
|
Text,
|
||||||
Tabs,
|
Tabs,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
@@ -71,61 +71,34 @@ const EmojiBar = ({
|
|||||||
<Group gap="xs" wrap="wrap" justify="space-between">
|
<Group gap="xs" wrap="wrap" justify="space-between">
|
||||||
<Group gap="xs" wrap="wrap">
|
<Group gap="xs" wrap="wrap">
|
||||||
{reactions.map((reaction) => (
|
{reactions.map((reaction) => (
|
||||||
<UnstyledButton
|
<Button
|
||||||
key={reaction.emoji}
|
key={reaction.emoji}
|
||||||
|
variant={reaction.hasReacted ? "filled" : "light"}
|
||||||
|
color={reaction.hasReacted ? "var(--mantine-primary-color-filled)" : "gray"}
|
||||||
|
size="compact-xs"
|
||||||
|
radius="xl"
|
||||||
onMouseDown={() => handleLongPressStart(reaction.emoji)}
|
onMouseDown={() => handleLongPressStart(reaction.emoji)}
|
||||||
onMouseUp={handleLongPressEnd}
|
onMouseUp={handleLongPressEnd}
|
||||||
onMouseLeave={handleLongPressEnd}
|
onMouseLeave={handleLongPressEnd}
|
||||||
onTouchStart={() => handleLongPressStart(reaction.emoji)}
|
onTouchStart={() => handleLongPressStart(reaction.emoji)}
|
||||||
onTouchEnd={handleLongPressEnd}
|
onTouchEnd={handleLongPressEnd}
|
||||||
onClick={() => handleReactionClick(reaction.emoji)}
|
onClick={() => handleReactionClick(reaction.emoji)}
|
||||||
px="8px"
|
|
||||||
py="10px"
|
|
||||||
style={{
|
style={{
|
||||||
borderRadius: "var(--mantine-radius-xl)",
|
|
||||||
border: reaction.hasReacted
|
|
||||||
? "1px solid var(--mantine-primary-color-filled)"
|
|
||||||
: "1px solid var(--mantine-color-default-border)",
|
|
||||||
backgroundColor: reaction.hasReacted
|
|
||||||
? "var(--mantine-primary-color-light)"
|
|
||||||
: "transparent",
|
|
||||||
transition: "all 0.15s ease",
|
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
WebkitUserSelect: "none",
|
WebkitUserSelect: "none",
|
||||||
MozUserSelect: "none",
|
MozUserSelect: "none",
|
||||||
msUserSelect: "none",
|
msUserSelect: "none",
|
||||||
}}
|
}}
|
||||||
styles={{
|
|
||||||
root: {
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: reaction.hasReacted
|
|
||||||
? "var(--mantine-primary-color-light)"
|
|
||||||
: "var(--mantine-color-gray-1)",
|
|
||||||
transform: "scale(1.05)",
|
|
||||||
},
|
|
||||||
"&:active": {
|
|
||||||
transform: "scale(0.95)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Group gap={4} align="center">
|
<Group gap={4} align="center">
|
||||||
<Text size="10px" style={{ lineHeight: 1 }}>
|
<Text size="10px" style={{ lineHeight: 1 }}>
|
||||||
{reaction.emoji}
|
{reaction.emoji}
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text size="10px" fw={600}>
|
||||||
size="10px"
|
|
||||||
fw={700}
|
|
||||||
c={
|
|
||||||
reaction.hasReacted
|
|
||||||
? "var(--mantine-primary-color-filled)"
|
|
||||||
: "dimmed"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{reaction.count}
|
{reaction.count}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
</UnstyledButton>
|
</Button>
|
||||||
))}
|
))}
|
||||||
</Group>
|
</Group>
|
||||||
<EmojiPicker onSelect={onReactionPress || (() => {})} />
|
<EmojiPicker onSelect={onReactionPress || (() => {})} />
|
||||||
|
|||||||
18
src/features/teams/components/team-card-skeleton.tsx
Normal file
18
src/features/teams/components/team-card-skeleton.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Paper, Group, Skeleton, Box } from "@mantine/core";
|
||||||
|
|
||||||
|
const TeamCardSkeleton = () => {
|
||||||
|
return (
|
||||||
|
<Paper p="sm" withBorder radius="md">
|
||||||
|
<Group gap="sm" align="center">
|
||||||
|
<Skeleton height={32} width={32} radius="sm" />
|
||||||
|
<Box style={{ flex: 1 }}>
|
||||||
|
<Skeleton height={16} width="70%" mb={4} />
|
||||||
|
<Skeleton height={12} width="40%" />
|
||||||
|
</Box>
|
||||||
|
<Skeleton height={20} width={60} radius="xl" />
|
||||||
|
</Group>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TeamCardSkeleton;
|
||||||
78
src/features/teams/components/team-card.tsx
Normal file
78
src/features/teams/components/team-card.tsx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
Paper,
|
||||||
|
Text,
|
||||||
|
Group,
|
||||||
|
Box,
|
||||||
|
Stack,
|
||||||
|
Divider
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { useTeam } from "../queries";
|
||||||
|
import Avatar from "@/components/avatar";
|
||||||
|
import SongSummary from "./team-form/song-summary";
|
||||||
|
|
||||||
|
interface TeamCardProps {
|
||||||
|
teamId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TeamCard = ({ teamId }: TeamCardProps) => {
|
||||||
|
const { data: team, error } = useTeam(teamId);
|
||||||
|
|
||||||
|
console.log(team)
|
||||||
|
|
||||||
|
if (error || !team) {
|
||||||
|
return (
|
||||||
|
<Paper p="sm" withBorder radius="md">
|
||||||
|
<Text c="red" ta="center" size="sm">
|
||||||
|
Failed to load team
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const song = {
|
||||||
|
song_id: team.song_id,
|
||||||
|
song_name: team.song_name,
|
||||||
|
song_artist: team.song_artist,
|
||||||
|
song_album: team.song_album,
|
||||||
|
song_start: team.song_start,
|
||||||
|
song_end: team.song_end,
|
||||||
|
song_image_url: team.song_image_url,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper
|
||||||
|
withBorder
|
||||||
|
radius="lg"
|
||||||
|
shadow="xs"
|
||||||
|
>
|
||||||
|
<Stack gap={2}>
|
||||||
|
<Group gap="md" align="center" p="xs">
|
||||||
|
<Avatar
|
||||||
|
name={team.name}
|
||||||
|
size={40}
|
||||||
|
radius="md"
|
||||||
|
src={team.logo ? `/api/files/teams/${team.id}/${team.logo}` : undefined}
|
||||||
|
style={{
|
||||||
|
backgroundColor: team.primary_color || undefined,
|
||||||
|
color: team.accent_color || undefined,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Box style={{ flex: 1, minWidth: 0 }}>
|
||||||
|
<Text size="md" fw={600} lineClamp={1} mb={2}>
|
||||||
|
{team.name}
|
||||||
|
</Text>
|
||||||
|
<Text size="sm" c="dimmed" lineClamp={1}>
|
||||||
|
{team.players?.map(p => `${p.first_name} ${p.last_name}`).join(', ')}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
<Divider />
|
||||||
|
<Box p="sm">
|
||||||
|
<SongSummary song={song} />
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TeamCard;
|
||||||
@@ -21,6 +21,7 @@ interface TeamFormProps {
|
|||||||
initialValues?: Partial<TeamInput>;
|
initialValues?: Partial<TeamInput>;
|
||||||
teamId?: string;
|
teamId?: string;
|
||||||
tournamentId?: string;
|
tournamentId?: string;
|
||||||
|
onSubmit?: (teamId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TeamForm = ({
|
const TeamForm = ({
|
||||||
@@ -28,6 +29,7 @@ const TeamForm = ({
|
|||||||
initialValues,
|
initialValues,
|
||||||
teamId,
|
teamId,
|
||||||
tournamentId,
|
tournamentId,
|
||||||
|
onSubmit
|
||||||
}: TeamFormProps) => {
|
}: TeamFormProps) => {
|
||||||
const isEditMode = !!teamId;
|
const isEditMode = !!teamId;
|
||||||
|
|
||||||
@@ -103,7 +105,13 @@ const TeamForm = ({
|
|||||||
: "Failed to create team";
|
: "Failed to create team";
|
||||||
|
|
||||||
mutation(teamData, {
|
mutation(teamData, {
|
||||||
onSuccess: async (team) => {
|
onSuccess: async (team: any) => {
|
||||||
|
console.log(team)
|
||||||
|
queryClient.invalidateQueries({ queryKey: teamKeys.list });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: teamKeys.details(team.id),
|
||||||
|
});
|
||||||
|
|
||||||
if (logo && team) {
|
if (logo && team) {
|
||||||
try {
|
try {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
@@ -122,10 +130,8 @@ const TeamForm = ({
|
|||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
queryClient.invalidateQueries({ queryKey: teamKeys.list });
|
console.log('here for some reason', result)
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: teamKeys.details(result.team!.id),
|
|
||||||
});
|
|
||||||
queryClient.setQueryData(
|
queryClient.setQueryData(
|
||||||
tournamentKeys.details(result.team!.id),
|
tournamentKeys.details(result.team!.id),
|
||||||
result.team
|
result.team
|
||||||
@@ -137,7 +143,10 @@ const TeamForm = ({
|
|||||||
toast.error(logoErrorMessage);
|
toast.error(logoErrorMessage);
|
||||||
logger.error("Team logo upload error", error);
|
logger.error("Team logo upload error", error);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (team && team.id) {
|
||||||
|
onSubmit?.(team.id)
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ interface SongSummaryProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SongSummary = ({ song }: SongSummaryProps) => {
|
const SongSummary = ({ song }: SongSummaryProps) => {
|
||||||
// Format time helper
|
|
||||||
const formatTime = (seconds: number | undefined) => {
|
const formatTime = (seconds: number | undefined) => {
|
||||||
if (seconds === undefined) return null;
|
if (seconds === undefined) return null;
|
||||||
const minutes = Math.floor(seconds / 60);
|
const minutes = Math.floor(seconds / 60);
|
||||||
@@ -24,7 +23,6 @@ const SongSummary = ({ song }: SongSummaryProps) => {
|
|||||||
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If no song selected
|
|
||||||
if (!song?.song_name) {
|
if (!song?.song_name) {
|
||||||
return (
|
return (
|
||||||
<Group gap="xs" c="dimmed">
|
<Group gap="xs" c="dimmed">
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import { Divider, Group, List, ListItem, Skeleton, Stack, Text } from "@mantine/core";
|
import {
|
||||||
|
Divider,
|
||||||
|
Group,
|
||||||
|
List,
|
||||||
|
ListItem,
|
||||||
|
Skeleton,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
} from "@mantine/core";
|
||||||
import Avatar from "@/components/avatar";
|
import Avatar from "@/components/avatar";
|
||||||
import { TeamInfo } from "@/features/teams/types";
|
import { TeamInfo } from "@/features/teams/types";
|
||||||
import { useNavigate } from "@tanstack/react-router";
|
import { useNavigate } from "@tanstack/react-router";
|
||||||
@@ -15,14 +23,14 @@ const TeamListItem = React.memo(({ team }: TeamListItemProps) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group justify="space-between" w='100%'>
|
<Group justify="space-between" w="100%">
|
||||||
<Text fw={500}>{`${team.name}`}</Text>
|
<Text fw={500}>{`${team.name}`}</Text>
|
||||||
<Stack ml="auto" gap={0}>
|
<Stack ml="auto" gap={0}>
|
||||||
{playerNames.map((name) => (
|
{playerNames.map((name) => (
|
||||||
<Text size="xs" c="dimmed" ta="right">
|
<Text size="xs" c="dimmed" ta="right">
|
||||||
{name}
|
{name}
|
||||||
</Text>
|
</Text>
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
@@ -62,12 +70,23 @@ const TeamList = ({ teams, loading = false }: TeamListProps) => {
|
|||||||
<div key={team.id}>
|
<div key={team.id}>
|
||||||
<ListItem
|
<ListItem
|
||||||
p="xs"
|
p="xs"
|
||||||
icon={<Avatar radius="sm" size={40} name={`${team.name}`} />}
|
icon={
|
||||||
|
<Avatar
|
||||||
|
radius="sm"
|
||||||
|
size={40}
|
||||||
|
name={`${team.name}`}
|
||||||
|
src={
|
||||||
|
team.logo
|
||||||
|
? `/api/files/teams/${team.id}/${team.logo}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
onClick={() => handleClick(team.id)}
|
onClick={() => handleClick(team.id)}
|
||||||
styles={{
|
styles={{
|
||||||
itemWrapper: { width: "100%" },
|
itemWrapper: { width: "100%" },
|
||||||
itemLabel: { width: "100%" }
|
itemLabel: { width: "100%" },
|
||||||
}}
|
}}
|
||||||
w="100%"
|
w="100%"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,13 +5,19 @@ import { Team } from "../../types";
|
|||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
name: string;
|
name: string;
|
||||||
logo?: string;
|
logo?: string;
|
||||||
|
id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Header = ({ name, logo }: HeaderProps) => {
|
const Header = ({ name, logo, id }: HeaderProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex px="xl" w="100%" align="self-end" gap="md">
|
<Flex px="xl" w="100%" align="self-end" gap="md">
|
||||||
<Avatar radius="sm" name={name} size={125} />
|
<Avatar
|
||||||
|
radius="sm"
|
||||||
|
name={name}
|
||||||
|
size={125}
|
||||||
|
src={logo && id ? `/api/files/teams/${id}/${logo}` : undefined}
|
||||||
|
/>
|
||||||
<Flex align="center" justify="center" gap={4} pb={20} w="100%">
|
<Flex align="center" justify="center" gap={4} pb={20} w="100%">
|
||||||
<Title ta="center" order={2}>
|
<Title ta="center" order={2}>
|
||||||
{name}
|
{name}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const TeamProfile = ({ id }: ProfileProps) => {
|
|||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header name={team.name} logo={team.logo} />
|
<Header name={team.name} logo={team.logo} id={team.id} />
|
||||||
<Box mt="lg">
|
<Box mt="lg">
|
||||||
<SwipeableTabs tabs={tabs} />
|
<SwipeableTabs tabs={tabs} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ const useCreateTeam = () => {
|
|||||||
onMutate: (data) => {
|
onMutate: (data) => {
|
||||||
logger.info('Creating team', data);
|
logger.info('Creating team', data);
|
||||||
},
|
},
|
||||||
onSuccess: (team) => {
|
|
||||||
navigate({ to: '/teams/$id', params: { id: team.id } });
|
|
||||||
},
|
|
||||||
successMessage: 'Team created successfully!',
|
successMessage: 'Team created successfully!',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,7 +34,15 @@ const TeamItem = memo(({ team, onUnenroll, disabled }: TeamItemProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Group py="xs" px="sm" w="100%" gap="sm" align="center">
|
<Group py="xs" px="sm" w="100%" gap="sm" align="center">
|
||||||
<Avatar size={32} name={team.name} />
|
<Avatar
|
||||||
|
size={32}
|
||||||
|
name={team.name}
|
||||||
|
src={
|
||||||
|
team.logo
|
||||||
|
? `/api/files/teams/${team.id}/${team.logo}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Stack gap={0} style={{ flex: 1, minWidth: 0 }}>
|
<Stack gap={0} style={{ flex: 1, minWidth: 0 }}>
|
||||||
<Text fw={500} truncate>
|
<Text fw={500} truncate>
|
||||||
{team.name}
|
{team.name}
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ interface SeedTournamentProps {
|
|||||||
|
|
||||||
const SeedTournament: React.FC<SeedTournamentProps> = ({
|
const SeedTournament: React.FC<SeedTournamentProps> = ({
|
||||||
tournamentId,
|
tournamentId,
|
||||||
teams
|
teams,
|
||||||
}) => {
|
}) => {
|
||||||
const [orderedTeams, setOrderedTeams] = useState<TeamInfo[]>(teams);
|
const [orderedTeams, setOrderedTeams] = useState<TeamInfo[]>(teams);
|
||||||
const { data: bracketPreview } = useBracketPreview(teams.length);
|
const { data: bracketPreview } = useBracketPreview(teams.length);
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const bracket: BracketData = useMemo(
|
const bracket: BracketData = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -48,7 +48,7 @@ const SeedTournament: React.FC<SeedTournamentProps> = ({
|
|||||||
: undefined,
|
: undefined,
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
losers: bracketPreview.losers
|
losers: bracketPreview.losers,
|
||||||
}),
|
}),
|
||||||
[bracketPreview, orderedTeams]
|
[bracketPreview, orderedTeams]
|
||||||
);
|
);
|
||||||
@@ -58,8 +58,8 @@ const SeedTournament: React.FC<SeedTournamentProps> = ({
|
|||||||
successMessage: "Tournament bracket generated successfully!",
|
successMessage: "Tournament bracket generated successfully!",
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: tournamentKeys.details(tournamentId)
|
queryKey: tournamentKeys.details(tournamentId),
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ const SeedTournament: React.FC<SeedTournamentProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', gap: '2rem', alignItems: 'flex-start' }}>
|
<div style={{ display: "flex", gap: "2rem", alignItems: "flex-start" }}>
|
||||||
<Stack gap="lg" style={{ flexShrink: 0 }}>
|
<Stack gap="lg" style={{ flexShrink: 0 }}>
|
||||||
<Stack gap={0} pos="relative" w={400}>
|
<Stack gap={0} pos="relative" w={400}>
|
||||||
<LoadingOverlay visible={generateBracket.isPending} />
|
<LoadingOverlay visible={generateBracket.isPending} />
|
||||||
@@ -171,7 +171,16 @@ const SeedTournament: React.FC<SeedTournamentProps> = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Avatar size={24} radius="sm" name={team.name} />
|
<Avatar
|
||||||
|
size={24}
|
||||||
|
radius="sm"
|
||||||
|
name={team.name}
|
||||||
|
src={
|
||||||
|
team.logo
|
||||||
|
? `/api/files/teams/${team.id}/${team.logo}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<Text fw={500} size="sm" style={{ flex: 1 }}>
|
<Text fw={500} size="sm" style={{ flex: 1 }}>
|
||||||
{team.name}
|
{team.name}
|
||||||
@@ -197,8 +206,8 @@ const SeedTournament: React.FC<SeedTournamentProps> = ({
|
|||||||
Confirm Seeding
|
Confirm Seeding
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<div style={{ flex: 1, overflow: 'auto' }}>
|
<div style={{ flex: 1, overflow: "auto" }}>
|
||||||
<BracketView bracket={bracket} />
|
<BracketView bracket={bracket} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,12 +8,16 @@ import TeamForm from "@/features/teams/components/team-form";
|
|||||||
import { teamQueries } from "@/features/teams/queries";
|
import { teamQueries } from "@/features/teams/queries";
|
||||||
import { Team } from "@/features/teams/types";
|
import { Team } from "@/features/teams/types";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { Loader } from "@mantine/core";
|
||||||
|
import useEnrollTeam from "@/features/tournaments/hooks/use-enroll-team";
|
||||||
|
import { useServerQuery } from "@/lib/tanstack-query/hooks";
|
||||||
|
|
||||||
interface EnrollTeamProps {
|
interface EnrollTeamProps {
|
||||||
tournamentId: string;
|
tournamentId: string;
|
||||||
|
onSubmit: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EnrollTeam = ({ tournamentId }: EnrollTeamProps) => {
|
const EnrollTeam = ({ tournamentId, onSubmit }: EnrollTeamProps) => {
|
||||||
const { open, isOpen, toggle } = useSheet();
|
const { open, isOpen, toggle } = useSheet();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
@@ -22,14 +26,14 @@ const EnrollTeam = ({ tournamentId }: EnrollTeamProps) => {
|
|||||||
const [showTeamForm, setShowTeamForm] = useState<boolean>(!hasTeams);
|
const [showTeamForm, setShowTeamForm] = useState<boolean>(!hasTeams);
|
||||||
const [selectedTeam, setSelectedTeam] = useState<Team | null>(null);
|
const [selectedTeam, setSelectedTeam] = useState<Team | null>(null);
|
||||||
|
|
||||||
const { data: teamData } = useQuery({
|
const { data: teamData } = useServerQuery({
|
||||||
...teamQueries.details(selectedTeamId!),
|
...teamQueries.details(selectedTeamId!),
|
||||||
enabled: !!selectedTeamId,
|
options: { enabled: !!selectedTeamId }
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (teamData?.success) {
|
if (teamData) {
|
||||||
setSelectedTeam(teamData.data);
|
setSelectedTeam(teamData);
|
||||||
setShowTeamForm(true);
|
setShowTeamForm(true);
|
||||||
}
|
}
|
||||||
}, [teamData]);
|
}, [teamData]);
|
||||||
@@ -71,6 +75,16 @@ const EnrollTeam = ({ tournamentId }: EnrollTeamProps) => {
|
|||||||
};
|
};
|
||||||
}, [selectedTeam]);
|
}, [selectedTeam]);
|
||||||
|
|
||||||
|
const { mutate: enrollTeam, isPending: isEnrolling } = useEnrollTeam();
|
||||||
|
const handleEnrollTeam = (teamId: string) => {
|
||||||
|
enrollTeam({ tournamentId, teamId }, {
|
||||||
|
onSuccess: () => {
|
||||||
|
toggle();
|
||||||
|
onSubmit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button size="sm" onClick={open}>
|
<Button size="sm" onClick={open}>
|
||||||
@@ -78,12 +92,14 @@ const EnrollTeam = ({ tournamentId }: EnrollTeamProps) => {
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Sheet title={showTeamForm ? "Team Details" : "Enroll Team"} opened={isOpen} onChange={toggle}>
|
<Sheet title={showTeamForm ? "Team Details" : "Enroll Team"} opened={isOpen} onChange={toggle}>
|
||||||
{showTeamForm ? (
|
{ isEnrolling && <Loader size="lg" /> }
|
||||||
|
{showTeamForm && !isEnrolling ? (
|
||||||
<TeamForm
|
<TeamForm
|
||||||
close={handleBack}
|
close={handleBack}
|
||||||
tournamentId={tournamentId}
|
tournamentId={tournamentId}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
teamId={selectedTeamId}
|
teamId={selectedTeamId}
|
||||||
|
onSubmit={handleEnrollTeam}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,27 +1,21 @@
|
|||||||
import { useMemo } from "react";
|
import { Suspense, useCallback, useMemo } from "react";
|
||||||
import { Tournament } from "../../types";
|
import { Tournament } from "../../types";
|
||||||
import { useAuth } from "@/contexts/auth-context";
|
import { useAuth } from "@/contexts/auth-context";
|
||||||
import {
|
import { Box, Button, Card, Divider, Group, Stack, Text } from "@mantine/core";
|
||||||
Box,
|
|
||||||
Card,
|
|
||||||
Divider,
|
|
||||||
Group,
|
|
||||||
Stack,
|
|
||||||
Text,
|
|
||||||
} from "@mantine/core";
|
|
||||||
import Countdown from "@/components/countdown";
|
import Countdown from "@/components/countdown";
|
||||||
import ListLink from "@/components/list-link";
|
import ListLink from "@/components/list-link";
|
||||||
import ListButton from "@/components/list-button";
|
import ListButton from "@/components/list-button";
|
||||||
import {
|
import { UsersIcon, ListIcon } from "@phosphor-icons/react";
|
||||||
UsersIcon,
|
|
||||||
ListIcon,
|
|
||||||
} from "@phosphor-icons/react";
|
|
||||||
import EnrollTeam from "./enroll-team";
|
import EnrollTeam from "./enroll-team";
|
||||||
import EnrollFreeAgent from "./enroll-free-agent";
|
import EnrollFreeAgent from "./enroll-free-agent";
|
||||||
import TeamListButton from "./team-list-button";
|
import TeamListButton from "./team-list-button";
|
||||||
import Header from "./header";
|
import Header from "./header";
|
||||||
import EmojiPicker from "@/features/reactions/components/emoji-picker";
|
import TeamCardSkeleton from "@/features/teams/components/team-card-skeleton";
|
||||||
import EmojiBar from "@/features/reactions/components/emoji-bar";
|
import TeamCard from "@/features/teams/components/team-card";
|
||||||
|
import UpdateTeam from "./update-team";
|
||||||
|
import UnenrollTeam from "./unenroll-team";
|
||||||
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { tournamentKeys } from "../../queries";
|
||||||
|
|
||||||
const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
||||||
tournament,
|
tournament,
|
||||||
@@ -43,18 +37,21 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
|||||||
: new Date(tournament.start_time);
|
: new Date(tournament.start_time);
|
||||||
const isEnrollmentOpen = enrollmentDeadline > new Date();
|
const isEnrollmentOpen = enrollmentDeadline > new Date();
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const handleSubmit = () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: tournamentKeys.current })
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(userTeam)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap="lg">
|
<Stack gap="lg">
|
||||||
|
|
||||||
<Header tournament={tournament} />
|
<Header tournament={tournament} />
|
||||||
|
|
||||||
<EmojiBar />
|
|
||||||
|
|
||||||
{tournament.desc && <Text size="sm">{tournament.desc}</Text>}
|
{tournament.desc && <Text size="sm">{tournament.desc}</Text>}
|
||||||
|
|
||||||
<Card withBorder radius="md" p="lg">
|
<Card withBorder radius="lg" p="lg">
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
<Group mb='sm' gap="xs" align="center">
|
<Group mb="sm" gap="xs" align="center">
|
||||||
<UsersIcon size={16} />
|
<UsersIcon size={16} />
|
||||||
<Text size="sm" fw={500}>
|
<Text size="sm" fw={500}>
|
||||||
Enrollment
|
Enrollment
|
||||||
@@ -70,17 +67,29 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
|||||||
)}
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
{!isEnrollmentOpen && !isUserEnrolled && (
|
{!isUserEnrolled &&!isEnrollmentOpen && (
|
||||||
<Text fw={600} c="dimmed" size="sm">Enrollment has been closed for this tournament.</Text>
|
<Text fw={600} c="dimmed" size="sm">
|
||||||
|
Enrollment has been closed for this tournament.
|
||||||
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isUserEnrolled && isEnrollmentOpen && (
|
{!isUserEnrolled &&isEnrollmentOpen && (
|
||||||
<>
|
<>
|
||||||
<EnrollTeam tournamentId={tournament.id} />
|
<EnrollTeam tournamentId={tournament.id} onSubmit={handleSubmit} />
|
||||||
<Divider my={0} label="or" />
|
<Divider my={0} label="or" />
|
||||||
<EnrollFreeAgent />
|
<EnrollFreeAgent />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{
|
||||||
|
isUserEnrolled && <>
|
||||||
|
<Suspense fallback={<TeamCardSkeleton />}>
|
||||||
|
<TeamCard teamId={userTeam.id} />
|
||||||
|
</Suspense>
|
||||||
|
<UpdateTeam tournamentId={tournament.id} teamId={userTeam.id} />
|
||||||
|
{ isEnrollmentOpen && <UnenrollTeam tournamentId={tournament.id} teamId={userTeam.id} onSubmit={handleSubmit} />}
|
||||||
|
</>
|
||||||
|
}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import Button from "@/components/button";
|
||||||
|
import Sheet from "@/components/sheet/sheet";
|
||||||
|
import { useSheet } from "@/hooks/use-sheet";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import useUnenrollTeam from "../../hooks/use-unenroll-team";
|
||||||
|
import { Stack, Text } from "@mantine/core";
|
||||||
|
|
||||||
|
interface UnenrollTeamProps {
|
||||||
|
tournamentId: string;
|
||||||
|
teamId: string
|
||||||
|
onSubmit: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UnenrollTeam = ({ tournamentId, teamId, onSubmit }: UnenrollTeamProps) => {
|
||||||
|
const { open, isOpen, toggle } = useSheet();
|
||||||
|
const { mutate: unenrollTeam } = useUnenrollTeam();
|
||||||
|
const handleUnenrollTeam = useCallback(
|
||||||
|
async () => {
|
||||||
|
await unenrollTeam({ tournamentId, teamId }, {
|
||||||
|
onSuccess: () => {
|
||||||
|
toggle();
|
||||||
|
onSubmit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[unenrollTeam, tournamentId]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button size="sm" onClick={open} variant="subtle">
|
||||||
|
Unenroll
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Sheet title={"Unenroll Team"} opened={isOpen} onChange={toggle}>
|
||||||
|
<Stack gap='xs'>
|
||||||
|
<Text size="sm" fw={500}>Are you sure you want to unenroll from this tournament? You can enroll again at any point before the deadline.</Text>
|
||||||
|
<Button onClick={handleUnenrollTeam}>Confirm</Button>
|
||||||
|
<Button variant="subtle" color="red" onClick={toggle}>Cancel</Button>
|
||||||
|
</Stack>
|
||||||
|
</Sheet>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UnenrollTeam;
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import Button from "@/components/button";
|
||||||
|
import Sheet from "@/components/sheet/sheet";
|
||||||
|
import { useAuth } from "@/contexts/auth-context";
|
||||||
|
import { useSheet } from "@/hooks/use-sheet";
|
||||||
|
import { useMemo, useState, useCallback, useEffect } from "react";
|
||||||
|
import TeamSelectionView from "./enroll-team/team-selection-view";
|
||||||
|
import TeamForm from "@/features/teams/components/team-form";
|
||||||
|
import { teamQueries, useTeam } from "@/features/teams/queries";
|
||||||
|
import { Team } from "@/features/teams/types";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { Loader } from "@mantine/core";
|
||||||
|
import useEnrollTeam from "@/features/tournaments/hooks/use-enroll-team";
|
||||||
|
|
||||||
|
interface UpdateTeamProps {
|
||||||
|
tournamentId: string;
|
||||||
|
teamId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateTeam = ({ tournamentId, teamId }: UpdateTeamProps) => {
|
||||||
|
const { open, isOpen, toggle } = useSheet();
|
||||||
|
|
||||||
|
const { data: team } = useTeam(teamId);
|
||||||
|
|
||||||
|
const initialValues = useMemo(() => {
|
||||||
|
if (!team) return undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: team.name,
|
||||||
|
song_id: team.song_id,
|
||||||
|
song_name: team.song_name,
|
||||||
|
song_artist: team.song_artist,
|
||||||
|
song_album: team.song_album,
|
||||||
|
song_start: team.song_start,
|
||||||
|
song_end: team.song_end,
|
||||||
|
song_image_url: team.song_image_url,
|
||||||
|
players: team.players?.map(player => player.id),
|
||||||
|
};
|
||||||
|
}, [team]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button size="sm" onClick={open}>
|
||||||
|
Update Team
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Sheet title={"Update Team"} opened={isOpen} onChange={toggle}>
|
||||||
|
<TeamForm
|
||||||
|
close={toggle}
|
||||||
|
tournamentId={tournamentId}
|
||||||
|
initialValues={initialValues}
|
||||||
|
teamId={teamId}
|
||||||
|
onSubmit={(_) => close()}
|
||||||
|
/>
|
||||||
|
</Sheet>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UpdateTeam;
|
||||||
@@ -22,6 +22,7 @@ export function transformTeamInfo(record: any): TeamInfo {
|
|||||||
primary_color: record.primary_color,
|
primary_color: record.primary_color,
|
||||||
accent_color: record.accent_color,
|
accent_color: record.accent_color,
|
||||||
players,
|
players,
|
||||||
|
logo: record.logo
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ export function transformTeam(record: any): Team {
|
|||||||
song_artist: record.song_artist,
|
song_artist: record.song_artist,
|
||||||
song_album: record.song_album,
|
song_album: record.song_album,
|
||||||
song_start: record.song_start,
|
song_start: record.song_start,
|
||||||
song_end: 0,
|
song_end: record.song_end,
|
||||||
song_image_url: record.song_image_url,
|
song_image_url: record.song_image_url,
|
||||||
created: record.created,
|
created: record.created,
|
||||||
updated: record.updated,
|
updated: record.updated,
|
||||||
|
|||||||
Reference in New Issue
Block a user