diff --git a/pb_migrations/1756058328_updated_tournaments.js b/pb_migrations/1756058328_updated_tournaments.js
new file mode 100644
index 0000000..e8d1ded
--- /dev/null
+++ b/pb_migrations/1756058328_updated_tournaments.js
@@ -0,0 +1,48 @@
+///
+migrate((app) => {
+ const collection = app.findCollectionByNameOrId("pbc_340646327")
+
+ // remove field
+ collection.fields.removeById("text156371623")
+
+ // add field
+ collection.fields.addAt(9, new Field({
+ "hidden": false,
+ "id": "file3834550803",
+ "maxSelect": 1,
+ "maxSize": 0,
+ "mimeTypes": [],
+ "name": "logo",
+ "presentable": false,
+ "protected": false,
+ "required": false,
+ "system": false,
+ "thumbs": [],
+ "type": "file"
+ }))
+
+ return app.save(collection)
+}, (app) => {
+ const collection = app.findCollectionByNameOrId("pbc_340646327")
+
+ // add field
+ collection.fields.addAt(9, new Field({
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text156371623",
+ "max": 0,
+ "min": 0,
+ "name": "logo_url",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ }))
+
+ // remove field
+ collection.fields.removeById("file3834550803")
+
+ return app.save(collection)
+})
diff --git a/pb_migrations/1756058447_updated_teams.js b/pb_migrations/1756058447_updated_teams.js
new file mode 100644
index 0000000..cdb3434
--- /dev/null
+++ b/pb_migrations/1756058447_updated_teams.js
@@ -0,0 +1,45 @@
+///
+migrate((app) => {
+ const collection = app.findCollectionByNameOrId("pbc_1568971955")
+
+ // remove field
+ collection.fields.removeById("url156371623")
+
+ // add field
+ collection.fields.addAt(14, new Field({
+ "hidden": false,
+ "id": "file3834550803",
+ "maxSelect": 1,
+ "maxSize": 0,
+ "mimeTypes": [],
+ "name": "logo",
+ "presentable": false,
+ "protected": false,
+ "required": false,
+ "system": false,
+ "thumbs": [],
+ "type": "file"
+ }))
+
+ return app.save(collection)
+}, (app) => {
+ const collection = app.findCollectionByNameOrId("pbc_1568971955")
+
+ // add field
+ collection.fields.addAt(2, new Field({
+ "exceptDomains": null,
+ "hidden": false,
+ "id": "url156371623",
+ "name": "logo_url",
+ "onlyDomains": null,
+ "presentable": false,
+ "required": false,
+ "system": false,
+ "type": "url"
+ }))
+
+ // remove field
+ collection.fields.removeById("file3834550803")
+
+ return app.save(collection)
+})
diff --git a/src/app/routeTree.gen.ts b/src/app/routeTree.gen.ts
index eb6fa0a..ac4a6f7 100644
--- a/src/app/routeTree.gen.ts
+++ b/src/app/routeTree.gen.ts
@@ -24,8 +24,10 @@ import { Route as AuthedTeamsTeamIdRouteImport } from './routes/_authed/teams.$t
import { Route as AuthedProfilePlayerIdRouteImport } from './routes/_authed/profile.$playerId'
import { Route as AuthedAdminPreviewRouteImport } from './routes/_authed/admin/preview'
import { ServerRoute as ApiTestServerRouteImport } from './routes/api/test'
+import { ServerRoute as ApiTournamentsUploadLogoServerRouteImport } from './routes/api/tournaments/upload-logo'
import { ServerRoute as ApiEventsSplatServerRouteImport } from './routes/api/events.$'
import { ServerRoute as ApiAuthSplatServerRouteImport } from './routes/api/auth.$'
+import { ServerRoute as ApiFilesCollectionRecordIdFileServerRouteImport } from './routes/api/files/$collection/$recordId/$file'
const rootServerRouteImport = createServerRootRoute()
@@ -94,6 +96,12 @@ const ApiTestServerRoute = ApiTestServerRouteImport.update({
path: '/api/test',
getParentRoute: () => rootServerRouteImport,
} as any)
+const ApiTournamentsUploadLogoServerRoute =
+ ApiTournamentsUploadLogoServerRouteImport.update({
+ id: '/api/tournaments/upload-logo',
+ path: '/api/tournaments/upload-logo',
+ getParentRoute: () => rootServerRouteImport,
+ } as any)
const ApiEventsSplatServerRoute = ApiEventsSplatServerRouteImport.update({
id: '/api/events/$',
path: '/api/events/$',
@@ -104,6 +112,12 @@ const ApiAuthSplatServerRoute = ApiAuthSplatServerRouteImport.update({
path: '/api/auth/$',
getParentRoute: () => rootServerRouteImport,
} as any)
+const ApiFilesCollectionRecordIdFileServerRoute =
+ ApiFilesCollectionRecordIdFileServerRouteImport.update({
+ id: '/api/files/$collection/$recordId/$file',
+ path: '/api/files/$collection/$recordId/$file',
+ getParentRoute: () => rootServerRouteImport,
+ } as any)
export interface FileRoutesByFullPath {
'/login': typeof LoginRoute
@@ -196,30 +210,54 @@ export interface FileServerRoutesByFullPath {
'/api/test': typeof ApiTestServerRoute
'/api/auth/$': typeof ApiAuthSplatServerRoute
'/api/events/$': typeof ApiEventsSplatServerRoute
+ '/api/tournaments/upload-logo': typeof ApiTournamentsUploadLogoServerRoute
+ '/api/files/$collection/$recordId/$file': typeof ApiFilesCollectionRecordIdFileServerRoute
}
export interface FileServerRoutesByTo {
'/api/test': typeof ApiTestServerRoute
'/api/auth/$': typeof ApiAuthSplatServerRoute
'/api/events/$': typeof ApiEventsSplatServerRoute
+ '/api/tournaments/upload-logo': typeof ApiTournamentsUploadLogoServerRoute
+ '/api/files/$collection/$recordId/$file': typeof ApiFilesCollectionRecordIdFileServerRoute
}
export interface FileServerRoutesById {
__root__: typeof rootServerRouteImport
'/api/test': typeof ApiTestServerRoute
'/api/auth/$': typeof ApiAuthSplatServerRoute
'/api/events/$': typeof ApiEventsSplatServerRoute
+ '/api/tournaments/upload-logo': typeof ApiTournamentsUploadLogoServerRoute
+ '/api/files/$collection/$recordId/$file': typeof ApiFilesCollectionRecordIdFileServerRoute
}
export interface FileServerRouteTypes {
fileServerRoutesByFullPath: FileServerRoutesByFullPath
- fullPaths: '/api/test' | '/api/auth/$' | '/api/events/$'
+ fullPaths:
+ | '/api/test'
+ | '/api/auth/$'
+ | '/api/events/$'
+ | '/api/tournaments/upload-logo'
+ | '/api/files/$collection/$recordId/$file'
fileServerRoutesByTo: FileServerRoutesByTo
- to: '/api/test' | '/api/auth/$' | '/api/events/$'
- id: '__root__' | '/api/test' | '/api/auth/$' | '/api/events/$'
+ to:
+ | '/api/test'
+ | '/api/auth/$'
+ | '/api/events/$'
+ | '/api/tournaments/upload-logo'
+ | '/api/files/$collection/$recordId/$file'
+ id:
+ | '__root__'
+ | '/api/test'
+ | '/api/auth/$'
+ | '/api/events/$'
+ | '/api/tournaments/upload-logo'
+ | '/api/files/$collection/$recordId/$file'
fileServerRoutesById: FileServerRoutesById
}
export interface RootServerRouteChildren {
ApiTestServerRoute: typeof ApiTestServerRoute
ApiAuthSplatServerRoute: typeof ApiAuthSplatServerRoute
ApiEventsSplatServerRoute: typeof ApiEventsSplatServerRoute
+ ApiTournamentsUploadLogoServerRoute: typeof ApiTournamentsUploadLogoServerRoute
+ ApiFilesCollectionRecordIdFileServerRoute: typeof ApiFilesCollectionRecordIdFileServerRoute
}
declare module '@tanstack/react-router' {
@@ -319,6 +357,13 @@ declare module '@tanstack/react-start/server' {
preLoaderRoute: typeof ApiTestServerRouteImport
parentRoute: typeof rootServerRouteImport
}
+ '/api/tournaments/upload-logo': {
+ id: '/api/tournaments/upload-logo'
+ path: '/api/tournaments/upload-logo'
+ fullPath: '/api/tournaments/upload-logo'
+ preLoaderRoute: typeof ApiTournamentsUploadLogoServerRouteImport
+ parentRoute: typeof rootServerRouteImport
+ }
'/api/events/$': {
id: '/api/events/$'
path: '/api/events/$'
@@ -333,6 +378,13 @@ declare module '@tanstack/react-start/server' {
preLoaderRoute: typeof ApiAuthSplatServerRouteImport
parentRoute: typeof rootServerRouteImport
}
+ '/api/files/$collection/$recordId/$file': {
+ id: '/api/files/$collection/$recordId/$file'
+ path: '/api/files/$collection/$recordId/$file'
+ fullPath: '/api/files/$collection/$recordId/$file'
+ preLoaderRoute: typeof ApiFilesCollectionRecordIdFileServerRouteImport
+ parentRoute: typeof rootServerRouteImport
+ }
}
}
@@ -385,6 +437,9 @@ const rootServerRouteChildren: RootServerRouteChildren = {
ApiTestServerRoute: ApiTestServerRoute,
ApiAuthSplatServerRoute: ApiAuthSplatServerRoute,
ApiEventsSplatServerRoute: ApiEventsSplatServerRoute,
+ ApiTournamentsUploadLogoServerRoute: ApiTournamentsUploadLogoServerRoute,
+ ApiFilesCollectionRecordIdFileServerRoute:
+ ApiFilesCollectionRecordIdFileServerRoute,
}
export const serverRouteTree = rootServerRouteImport
._addFileChildren(rootServerRouteChildren)
diff --git a/src/app/routes/api/files/$collection/$recordId/$file.ts b/src/app/routes/api/files/$collection/$recordId/$file.ts
new file mode 100644
index 0000000..581e1fb
--- /dev/null
+++ b/src/app/routes/api/files/$collection/$recordId/$file.ts
@@ -0,0 +1,95 @@
+import { createServerFileRoute } from "@tanstack/react-start/server";
+import { logger } from "@/lib/logger";
+
+export const ServerRoute = createServerFileRoute("/api/files/$collection/$recordId/$file").methods({
+ GET: async ({ params, request }) => {
+ try {
+ const { collection, recordId, file } = params;
+ const pocketbaseUrl = process.env.VITE_POCKETBASE_URL || 'http://127.0.0.1:8090';
+ const fileUrl = `${pocketbaseUrl}/api/files/${collection}/${recordId}/${file}`;
+
+ logger.info('File proxy', {
+ collection,
+ recordId,
+ file,
+ targetUrl: fileUrl
+ });
+
+ const response = await fetch(fileUrl, {
+ method: 'GET',
+ headers: {
+ ...(request.headers.get('range') && { 'Range': request.headers.get('range')! }),
+ ...(request.headers.get('if-none-match') && { 'If-None-Match': request.headers.get('if-none-match')! }),
+ ...(request.headers.get('if-modified-since') && { 'If-Modified-Since': request.headers.get('if-modified-since')! }),
+ },
+ });
+
+ if (!response.ok) {
+ logger.error('PocketBase file request failed', {
+ status: response.status,
+ statusText: response.statusText,
+ url: fileUrl
+ });
+
+ if (response.status === 404) {
+ return new Response('File not found', { status: 404 });
+ }
+
+ return new Response(`PocketBase error: ${response.statusText}`, {
+ status: response.status
+ });
+ }
+
+ const body = response.body;
+ const responseHeaders = new Headers();
+ const headers = [
+ 'content-type',
+ 'content-length',
+ 'content-disposition',
+ 'etag',
+ 'last-modified',
+ 'cache-control',
+ 'accept-ranges',
+ 'content-range'
+ ];
+
+ headers.forEach(header => {
+ const value = response.headers.get(header);
+ if (value) {
+ responseHeaders.set(header, value);
+ }
+ });
+
+ responseHeaders.set('Access-Control-Allow-Origin', '*');
+ responseHeaders.set('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');
+ responseHeaders.set('Access-Control-Allow-Headers', 'Range, If-None-Match, If-Modified-Since');
+
+ logger.info('File proxy response', {
+ status: response.status,
+ contentType: response.headers.get('content-type'),
+ contentLength: response.headers.get('content-length')
+ });
+
+ return new Response(body, {
+ status: response.status,
+ statusText: response.statusText,
+ headers: responseHeaders
+ });
+
+ } catch (error) {
+ logger.error('File proxy error', error);
+ return new Response('Internal server error', { status: 500 });
+ }
+ },
+
+ OPTIONS: () => {
+ return new Response(null, {
+ status: 200,
+ headers: {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET, OPTIONS',
+ 'Access-Control-Max-Age': '86400',
+ }
+ });
+ }
+});
\ No newline at end of file
diff --git a/src/app/routes/api/tournaments/upload-logo.ts b/src/app/routes/api/tournaments/upload-logo.ts
new file mode 100644
index 0000000..40d45bf
--- /dev/null
+++ b/src/app/routes/api/tournaments/upload-logo.ts
@@ -0,0 +1,115 @@
+import { createServerFileRoute } from '@tanstack/react-start/server';
+import { superTokensRequestMiddleware } from '@/utils/supertokens';
+import { pbAdmin } from '@/lib/pocketbase/client';
+import { logger } from '@/lib/logger';
+import { z } from 'zod';
+
+const uploadSchema = z.object({
+ tournamentId: z.string().min(1, 'Tournament ID is required'),
+});
+
+export const ServerRoute = createServerFileRoute('/api/tournaments/upload-logo')
+ .middleware([superTokensRequestMiddleware])
+ .methods({
+ POST: async ({ request, context }) => {
+ try {
+ const userId = context.userAuthId;
+ const isAdmin = context.roles.includes("Admin");
+
+ if (!userId) return new Response('Unauthenticated', { status: 401 });
+ if (!isAdmin) return new Response('Unauthorized', { status: 403 });
+
+ const formData = await request.formData();
+ const tournamentId = formData.get('tournamentId') as string;
+ const logoFile = formData.get('logo') as File;
+
+ const validationResult = uploadSchema.safeParse({ tournamentId });
+ if (!validationResult.success) {
+ return new Response(JSON.stringify({
+ error: 'Invalid input',
+ details: validationResult.error.issues
+ }), {
+ status: 400,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ if (!logoFile || logoFile.size === 0) {
+ return new Response(JSON.stringify({
+ error: 'Logo file is required'
+ }), {
+ status: 400,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
+ if (!allowedTypes.includes(logoFile.type)) {
+ return new Response(JSON.stringify({
+ error: 'Invalid file type. Only JPEG, PNG and GIF are allowed.'
+ }), {
+ status: 400,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ const maxSize = 10 * 1024 * 1024;
+ if (logoFile.size > maxSize) {
+ return new Response(JSON.stringify({
+ error: 'File too large. Maximum size is 10MB.'
+ }), {
+ status: 400,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ const tournament = await pbAdmin.getTournament(tournamentId);
+ if (!tournament) {
+ return new Response(JSON.stringify({
+ error: 'Tournament not found'
+ }), {
+ status: 404,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+
+ logger.info('Uploading tournament logo', {
+ tournamentId,
+ fileName: logoFile.name,
+ fileSize: logoFile.size,
+ userId
+ });
+
+ const pbFormData = new FormData();
+ pbFormData.append('logo', logoFile);
+
+ const updatedTournament = await pbAdmin.updateTournament(tournamentId, pbFormData as any);
+
+ logger.info('Tournament logo uploaded successfully', {
+ tournamentId,
+ logo: updatedTournament.logo
+ });
+
+ return new Response(JSON.stringify({
+ success: true,
+ tournament: updatedTournament,
+ message: 'Logo uploaded successfully'
+ }), {
+ status: 200,
+ headers: { 'Content-Type': 'application/json' }
+ });
+
+ } catch (error: any) {
+ logger.error('Error uploading tournament logo:', error);
+
+ return new Response(JSON.stringify({
+ error: 'Failed to upload logo',
+ message: error.message || 'Unknown error occurred'
+ }), {
+ status: 500,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+ }
+ });
\ No newline at end of file
diff --git a/src/features/admin/components/create-tournament.tsx b/src/features/admin/components/create-tournament.tsx
index 98ca0a1..115bfcc 100644
--- a/src/features/admin/components/create-tournament.tsx
+++ b/src/features/admin/components/create-tournament.tsx
@@ -1,4 +1,4 @@
-import { Stack, TextInput, Textarea } from "@mantine/core";
+import { FileInput, Stack, TextInput, Textarea } from "@mantine/core";
import { useForm, UseFormInput } from "@mantine/form";
import { LinkIcon } from "@phosphor-icons/react";
import SlidePanel, { SlidePanelField } from "@/components/sheet/slide-panel";
@@ -6,6 +6,10 @@ import { TournamentFormInput } from "@/features/tournaments/types";
import { DateTimePicker } from "./date-time-picker";
import { isNotEmpty } from "@mantine/form";
import useCreateTournament from "../hooks/use-create-tournament";
+import toast from '@/lib/sonner';
+import { logger } from "..";
+import { useQueryClient } from "@tanstack/react-query";
+import { tournamentQueries } from "@/features/tournaments/queries";
const CreateTournament = ({ close }: { close: () => void }) => {
@@ -14,7 +18,6 @@ const CreateTournament = ({ close }: { close: () => void }) => {
name: 'Test Tournament',
location: 'Test Location',
desc: 'Test Description',
- logo_url: 'https://en.wikipedia.org/wiki/Trophy#/media/File:1934_Melbourne_Cup,_National_Museum_of_Australia.jpg',
start_time: '2025-01-01T00:00:00Z',
enroll_time: '2025-01-01T00:00:00Z',
},
@@ -28,12 +31,45 @@ const CreateTournament = ({ close }: { close: () => void }) => {
}
const form = useForm(config);
+ const queryClient = useQueryClient();
const { mutate: createTournament, isPending } = useCreateTournament();
const handleSubmit = async (values: TournamentFormInput) => {
- createTournament(values, {
- onSuccess: () => {
+ const { logo, ...tournamentData } = values;
+
+ createTournament(tournamentData, {
+ onSuccess: async (tournament) => {
+ if (logo && tournament) {
+ try {
+ const formData = new FormData();
+ formData.append('tournamentId', tournament.id);
+ formData.append('logo', logo);
+
+ const response = await fetch('/api/tournaments/upload-logo', {
+ method: 'POST',
+ body: formData,
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ throw new Error(error.error || 'Failed to upload logo');
+ }
+
+ const result = await response.json();
+
+ queryClient.invalidateQueries({ queryKey: tournamentQueries.list().queryKey });
+ queryClient.setQueryData(
+ tournamentQueries.details(result.tournament!.id).queryKey,
+ result.tournament
+ );
+
+ toast.success('Tournament created successfully!');
+ } catch (error: any) {
+ toast.error(`Tournament created but logo upload failed: ${error.message}`);
+ logger.error('Tournament logo upload error', error);
+ }
+ }
close();
}
});
@@ -67,12 +103,12 @@ const CreateTournament = ({ close }: { close: () => void }) => {
{...form.getInputProps('desc')}
/>
- }
- {...form.getInputProps('logo_url')}
+ {...form.getInputProps('logo')}
/>
{
toast.error('There was an issue creating your tournament. Please try again later.');
logger.error('Error creating tournament', data);
} else {
- toast.success('Tournament created successfully!');
logger.info('Tournament created successfully', data);
navigate({ to: '/tournaments' });
}
diff --git a/src/features/players/components/profile/index.tsx b/src/features/players/components/profile/index.tsx
index c58024e..a37e5b6 100644
--- a/src/features/players/components/profile/index.tsx
+++ b/src/features/players/components/profile/index.tsx
@@ -13,7 +13,7 @@ const Profile = ({ player }: ProfileProps) => {
const tabs = [
{
label: "Overview",
- content: Panel 1 content
+ content: Stats/Badges will go here
},
{
label: "Teams",
diff --git a/src/features/teams/types.ts b/src/features/teams/types.ts
index 0d75064..7a1b863 100644
--- a/src/features/teams/types.ts
+++ b/src/features/teams/types.ts
@@ -4,7 +4,7 @@ import { z } from 'zod';
export interface Team {
id: string;
name: string;
- logo_url: string;
+ logo: string;
primary_color: string;
accent_color: string;
song_id: string;
@@ -22,7 +22,7 @@ export interface Team {
export const teamInputSchema = z.object({
name: z.string().min(1, "Team name is required").max(100, "Name too long"),
- logo_url: z.url("Invalid logo URL").optional(),
+ logo: z.file("Invalid logo").optional(),
primary_color: z.string().regex(/^#[0-9A-F]{6}$/i, "Must be valid hex color (#FF0000)").optional(),
accent_color: z.string().regex(/^#[0-9A-F]{6}$/i, "Must be valid hex color (#FF0000)").optional(),
song_id: z.string().max(255).optional(),
diff --git a/src/features/tournaments/components/tournament-card.tsx b/src/features/tournaments/components/tournament-card.tsx
index cc6053b..9f30b12 100644
--- a/src/features/tournaments/components/tournament-card.tsx
+++ b/src/features/tournaments/components/tournament-card.tsx
@@ -1,7 +1,7 @@
import { Badge, Card, Text, Image, Stack, Flex } from "@mantine/core"
import { Tournament } from "@/features/tournaments/types"
import { useMemo } from "react"
-import { CaretRightIcon } from "@phosphor-icons/react"
+import { CaretRightIcon, TrophyIcon } from "@phosphor-icons/react"
import { useNavigate } from "@tanstack/react-router"
interface TournamentCardProps {
@@ -26,11 +26,12 @@ export const TournamentCard = ({ tournament }: TournamentCardProps) => {
{tournament.name}
diff --git a/src/features/tournaments/types.ts b/src/features/tournaments/types.ts
index 1119868..1393305 100644
--- a/src/features/tournaments/types.ts
+++ b/src/features/tournaments/types.ts
@@ -7,7 +7,7 @@ export interface Tournament {
location?: string;
desc?: string;
rules?: string;
- logo_url?: string;
+ logo?: string;
enroll_time?: string;
start_time: string;
end_time?: string;
@@ -22,7 +22,7 @@ export const tournamentFormSchema = z.object({
location: z.string().optional(),
desc: z.string().optional(),
rules: z.string().optional(),
- logo_url: z.string().optional(),
+ logo: z.file().optional(),
enroll_time: z.string(),
start_time: z.string(),
end_time: z.string().optional(),
@@ -34,7 +34,7 @@ export const tournamentInputSchema = z.object({
location: z.string().optional(),
desc: z.string().optional(),
rules: z.string().optional(),
- logo_url: z.string().optional(),
+ logo: z.file().optional(),
enroll_time: z.string(),
start_time: z.string(),
end_time: z.string().optional(),
diff --git a/src/lib/pocketbase/services/tournaments.ts b/src/lib/pocketbase/services/tournaments.ts
index 879f2bf..25db756 100644
--- a/src/lib/pocketbase/services/tournaments.ts
+++ b/src/lib/pocketbase/services/tournaments.ts
@@ -24,7 +24,7 @@ export function createTournamentsService(pb: PocketBase) {
const result = await pb
.collection("tournaments")
.getFullList({
- fields: "id,name,start_time,end_time,logo_url,created",
+ fields: "id,name,start_time,end_time,logo,created",
sort: "-created",
});
diff --git a/src/lib/pocketbase/util/transform-types.ts b/src/lib/pocketbase/util/transform-types.ts
index 0f80660..7350b39 100644
--- a/src/lib/pocketbase/util/transform-types.ts
+++ b/src/lib/pocketbase/util/transform-types.ts
@@ -36,7 +36,7 @@ export function transformTeam(record: any): Team {
return {
id: record.id,
name: record.name,
- logo_url: record.logo_url,
+ logo: record.logo,
primary_color: record.primary_color,
accent_color: record.accent_color,
song_id: record.song_id,
@@ -67,7 +67,7 @@ export function transformTournament(record: any): Tournament {
location: record.location,
desc: record.desc,
rules: record.rules,
- logo_url: record.logo_url,
+ logo: record.logo,
enroll_time: record.enroll_time,
start_time: record.start_time,
end_time: record.end_time,