Skip to content

Commit

Permalink
change game card? yes
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderjoe committed Jan 18, 2024
1 parent c2456d4 commit ecb5000
Show file tree
Hide file tree
Showing 9 changed files with 397 additions and 107 deletions.
219 changes: 217 additions & 2 deletions new-ui/src/components/display-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import { Game } from '~/interface';

import { FiCalendar, FiClock } from 'solid-icons/fi';
import { IoLocationOutline, IoWarning } from 'solid-icons/io';
import { OcDotfill3 } from 'solid-icons/oc';
import { Avatar, AvatarImage } from '~/components/ui/avatar';
import { Badge } from '~/components/ui/badge';
import { Button } from '~/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '~/components/ui/card';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '~/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '~/components/ui/table';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '~/components/ui/tabs';

const logos = import.meta.glob('../assets/teams/*.svg', { eager: true });
Expand All @@ -15,7 +19,7 @@ const getLogo = (team: string) => {

const shortName = (name: string) => {
const split = name.split(' ');
return split[split.length - 1];
return split.slice(1).join(' ');
};

const formattedTimeForUser = (time: number): string => {
Expand Down Expand Up @@ -58,6 +62,13 @@ const formattedDateForUser = (time: number): string => {
return new Intl.DateTimeFormat('en-US', options).format(date);
};

const winningTeam = (game: Game): number => {
if (game.status === 'Final') {
return game.home_team.score > game.away_team.score ? game.home_team.id : game.away_team.id;
}
return 0;
};

interface IDisplayCard {
game: Game;
}
Expand Down Expand Up @@ -85,6 +96,210 @@ export const DisplayCardHeader: Component<IDisplayCard> = (props: IDisplayCard)
);
};

export const DemoCard: Component<IDisplayCard> = (props: IDisplayCard) => {
return (
<>
<Card class="w-full max-w-4xl mx-auto bg-gray-900 rounded-lg shadow-md overflow-hidden p-6 text-white">
<CardHeader>
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<Avatar>
<AvatarImage alt="Detroit Pistons Logo" src={getLogo(props.game.home_team.abbreviation.toLowerCase())} />
</Avatar>
<div>
<CardTitle class="text-lg font-bold">{props.game.home_team.name}</CardTitle>
<CardDescription class="text-sm">{`${props.game.home_team.wins} - ${props.game.home_team.losses}`}</CardDescription>
</div>
</div>
<Show when={winningTeam(props.game) === props.game.home_team.id}>
<Badge class="bg-yellow-500 text-black" variant="secondary">
Winner
</Badge>
</Show>
</div>
<div class="flex items-center justify-between mt-4">
<div class="flex items-center space-x-4">
<Avatar>
<AvatarImage alt="Minnesota Timberwolves Logo" src={getLogo(props.game.away_team.abbreviation.toLowerCase())} />
</Avatar>
<div>
<CardTitle class="text-lg font-bold">{props.game.away_team.name}</CardTitle>
<CardDescription class="text-sm">{`${props.game.away_team.wins} - ${props.game.away_team.losses}`}</CardDescription>
</div>
</div>
<Show when={winningTeam(props.game) === props.game.away_team.id}>
<Badge class="bg-yellow-500 text-black" variant="secondary">
Winner
</Badge>
</Show>
</div>
</CardHeader>
{/* <CardHeader class="flex items-center justify-between p-6">
<div class="flex items-center">
<img alt={`${props.game.home_team.name}'s Logo`} class="mr-2 rounded-full" height={50} src={getLogo(props.game.home_team.abbreviation.toLowerCase())} style={{ 'aspect-ratio': '50/50', 'object-fit': 'cover' }} width={50} />
<div>
<CardTitle class="text-lg font-bold text-white">{`${props.game.home_team.name}`}</CardTitle>
<p class="text-sm text-gray-400">30-15</p>
</div>
</div>
<div class="flex items-center">
<div>
<CardTitle class="text-lg font-bold text-white">{`${props.game.away_team.name}`}</CardTitle>
<p class="text-sm text-gray-400">35-10</p>
</div>
<img alt={`${props.game.away_team.name}'s Logo`} class="ml-2 rounded-full" height={50} src={getLogo(props.game.away_team.abbreviation.toLowerCase())} style={{ 'aspect-ratio': '50/50', 'object-fit': 'cover' }} width={50} />
<span class="ml-2 inline-block bg-green-500 text-white text-xs px-2 py-1 rounded-full">Projected Winner</span>
</div>
</CardHeader> */}
<CardContent class="">
<div class="flex justify-between mt-4 items-center">
<div class="flex items-center text-sm">
<FiCalendar class="mr-1 h-4 w-4 inline-block" />
<span class="ml-2">{formattedDateForUser(props.game.start_time_unix)}</span>
</div>
<Show when={props.game.location}>
<div class="flex items-center text-sm">
<IoLocationOutline class="mr-1 h-4 w-4 inline-block" />
<span class="ml-2">{`${props.game.location.name}, ${props.game.location.city}, ${props.game.location.state}`}</span>
</div>
</Show>
<div class="flex items-center justify-center text-sm">
<span class="text-red-500 animate-pulse mr-2">
<OcDotfill3 />
</span>
<span class="text-white font-bold">Live</span>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<Show when={props.game.home_team.leader !== null && props.game.away_team.leader !== null && !isLive(props.game)}>
<div class="bg-gray-700 p-4 rounded mt-4">
<h4 class="font-semibold">Key Player - {props.game.home_team.name}</h4>
<p>{props.game.home_team.leader.name}</p>
<p class="text-sm text-gray-200">Points: {props.game.home_team.leader.points}</p>
<p class="text-sm text-gray-200">Rebounds: {props.game.home_team.leader.rebounds}</p>
<p class="text-sm text-gray-200">Assists: {props.game.home_team.leader.assists}</p>
</div>
</Show>
<Show when={props.game.home_team.leader !== null && props.game.away_team.leader !== null && !isLive(props.game)}>
<div class="bg-gray-700 p-4 rounded mt-4">
<h4 class="font-semibold">Key Player - {props.game.away_team.name}</h4>
<p>{props.game.away_team.leader.name}</p>
<p class="text-sm text-gray-200">Points: {props.game.away_team.leader.points}</p>
<p class="text-sm text-gray-200">Rebounds: {props.game.away_team.leader.rebounds}</p>
<p class="text-sm text-gray-200">Assists: {props.game.away_team.leader.assists}</p>
</div>
</Show>
<div class="col-span-2">
<div class="text-center bg-gray-700 p-4 rounded-lg">
<div class="flex items-center justify-center mb-2">
<span class="text-red-500 animate-pulse mr-2"></span>
<span class="text-white font-bold">Live</span>
</div>
<p class="text-2xl text-white font-bold mb-2">
{`${shortName(props.game.home_team.name)} : ${props.game.home_team.score}`} - {`${shortName(props.game.away_team.name)}: ${props.game.away_team.score}`}
</p>
<p class="text-sm text-gray-400">{props.game.status}</p>
</div>
</div>
<div>
<div class="">
<h3 class="text-lg font-bold">Current Score</h3>
<div class="flex items-center justify-between bg-gray-600 p-3 rounded mt-2">
<span class="font-semibold">
{shortName(props.game.home_team.name)}: {props.game.home_team.score}
</span>
<span class="ml-4 text-sm text-gray-400">Final</span>
</div>
</div>
<div class="mt-4">
<h3 class="text-lg font-bold">Score Breakdown - {shortName(props.game.home_team.name)}</h3>
<Table class="mt-2">
<TableHeader>
<TableRow>
<TableHead class="text-center">1st Quarter</TableHead>
<TableHead class="text-center">2nd Quarter</TableHead>
<TableHead class="text-center">3rd Quarter</TableHead>
<TableHead class="text-center">4th Quarter</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell class="text-center">25</TableCell>
<TableCell class="text-center">22</TableCell>
<TableCell class="text-center">30</TableCell>
<TableCell class="text-center">27</TableCell>
</TableRow>
<TableRow>
<TableCell class="text-center">20</TableCell>
<TableCell class="text-center">25</TableCell>
<TableCell class="text-center">22</TableCell>
<TableCell class="text-center">30</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
<div class="mt-4">
<h4>Timeouts Remaining</h4>
<p>{shortName(props.game.home_team.name)}: 2</p>
</div>
</div>
<div>
<div class="">
<h3 class="text-lg font-bold">Current Score</h3>
<div class="flex items-center justify-between bg-gray-600 p-3 rounded mt-2">
<span class="font-semibold">
{shortName(props.game.away_team.name)}: {props.game.away_team.score}
</span>
<span class="ml-4 text-sm text-gray-400">Final</span>
</div>
</div>
<div class="mt-4">
<h3 class="text-lg font-bold">Score Breakdown - {shortName(props.game.away_team.name)}</h3>
<Table class="mt-2">
<TableHeader>
<TableRow>
<TableHead class="text-center">1st Quarter</TableHead>
<TableHead class="text-center">2nd Quarter</TableHead>
<TableHead class="text-center">3rd Quarter</TableHead>
<TableHead class="text-center">4th Quarter</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell class="text-center">25</TableCell>
<TableCell class="text-center">22</TableCell>
<TableCell class="text-center">30</TableCell>
<TableCell class="text-center">27</TableCell>
</TableRow>
<TableRow>
<TableCell class="text-center">20</TableCell>
<TableCell class="text-center">25</TableCell>
<TableCell class="text-center">22</TableCell>
<TableCell class="text-center">30</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
<div class="mt-4">
<h4>Timeouts Remaining</h4>
<p>{shortName(props.game.away_team.name)}: 1</p>
</div>
</div>
</div>
</CardContent>
<CardFooter class="flex justify-between mt-4">
<Button class="bg-yellow-300 text-yellow-800" variant="outline">
View Injury Report
</Button>
<Button class="text-gray-300" variant="ghost">
View Game Details
</Button>
</CardFooter>
</Card>
</>
);
};

export const DisplayCard: Component<IDisplayCard> = (props: IDisplayCard) => {
return (
<>
Expand Down
11 changes: 11 additions & 0 deletions new-ui/src/components/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from 'solid-js';

export const Loading: Component = () => {
return (
<div class="flex items-center justify-center h-screen">
<div class="flex flex-col items-center space-y-4">
<div class="animate-spin h-20 w-20 rounded-full border-t-2 border-gray-400"></div>
</div>
</div>
);
};
23 changes: 23 additions & 0 deletions new-ui/src/components/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Component } from 'solid-js';
import { splitProps } from 'solid-js';

import { Image as ImagePrimitive } from '@kobalte/core';

import { cn } from '~/lib/utils';

const Avatar: Component<ImagePrimitive.ImageRootProps> = (props) => {
const [, rest] = splitProps(props, ['class']);
return <ImagePrimitive.Root class={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', props.class)} {...rest} />;
};

const AvatarImage: Component<ImagePrimitive.ImageImgProps> = (props) => {
const [, rest] = splitProps(props, ['class']);
return <ImagePrimitive.Img class={cn('aspect-square h-full w-full', props.class)} {...rest} />;
};

const AvatarFallback: Component<ImagePrimitive.ImageFallbackProps> = (props) => {
const [, rest] = splitProps(props, ['class']);
return <ImagePrimitive.Fallback class={cn('bg-muted flex h-full w-full items-center justify-center rounded-full', props.class)} {...rest} />;
};

export { Avatar, AvatarFallback, AvatarImage };
30 changes: 30 additions & 0 deletions new-ui/src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Component, ComponentProps } from 'solid-js';
import { splitProps } from 'solid-js';

import type { VariantProps } from 'class-variance-authority';
import { cva } from 'class-variance-authority';

import { cn } from '~/lib/utils';

const badgeVariants = cva('focus:ring-ring inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2', {
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/80 border-transparent',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent',
outline: 'text-foreground',
},
},
defaultVariants: {
variant: 'default',
},
});

export interface BadgeProps extends ComponentProps<'div'>, VariantProps<typeof badgeVariants> {}

const Badge: Component<BadgeProps> = (props) => {
const [, rest] = splitProps(props, ['variant', 'class']);
return <div class={cn(badgeVariants({ variant: props.variant }), props.class)} {...rest} />;
};

export { Badge, badgeVariants };
72 changes: 31 additions & 41 deletions new-ui/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,39 @@
import type { Component, ComponentProps } from "solid-js"
import { splitProps } from "solid-js"
import type { Component, ComponentProps } from 'solid-js';
import { splitProps } from 'solid-js';

import type { VariantProps } from "class-variance-authority"
import { cva } from "class-variance-authority"
import type { VariantProps } from 'class-variance-authority';
import { cva } from 'class-variance-authority';

import { cn } from "~/lib/utils"
import { cn } from '~/lib/utils';

const buttonVariants = cva(
"ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border-input hover:bg-accent hover:text-accent-foreground border",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline"
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10"
}
const buttonVariants = cva('ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', {
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline: 'border-input hover:bg-accent hover:text-accent-foreground border',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
defaultVariants: {
variant: "default",
size: "default"
}
}
)
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
});

export interface ButtonProps
extends ComponentProps<"button">,
VariantProps<typeof buttonVariants> {}
export interface ButtonProps extends ComponentProps<'button'>, VariantProps<typeof buttonVariants> {}

const Button: Component<ButtonProps> = (props) => {
const [, rest] = splitProps(props, ["variant", "size", "class"])
return (
<button
class={cn(buttonVariants({ variant: props.variant, size: props.size }), props.class)}
{...rest}
/>
)
}
const [, rest] = splitProps(props, ['variant', 'size', 'class']);
return <button class={cn(buttonVariants({ variant: props.variant, size: props.size }), props.class)} {...rest} />;
};

export { Button, buttonVariants }
export { Button, buttonVariants };
Loading

0 comments on commit ecb5000

Please sign in to comment.