mirror of
https://github.com/ershisan99/www.git
synced 2025-12-17 12:34:17 +00:00
add mlb page
This commit is contained in:
69
src/components/countdown-timer.tsx
Normal file
69
src/components/countdown-timer.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
'use client'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export function CountdownTimer({ nextMatch }: { nextMatch: any }) {
|
||||
const [timeLeft, setTimeLeft] = useState({
|
||||
days: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const calculateTimeLeft = () => {
|
||||
const now = new Date()
|
||||
const matchTime = new Date(nextMatch.datetime)
|
||||
const difference = matchTime.getTime() - now.getTime()
|
||||
|
||||
if (difference <= 0) {
|
||||
return {
|
||||
days: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
|
||||
hours: Math.floor(
|
||||
(difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
|
||||
),
|
||||
minutes: Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60)),
|
||||
seconds: Math.floor((difference % (1000 * 60)) / 1000),
|
||||
}
|
||||
}
|
||||
|
||||
setTimeLeft(calculateTimeLeft())
|
||||
|
||||
const timer = setInterval(() => {
|
||||
setTimeLeft(calculateTimeLeft())
|
||||
}, 1000)
|
||||
|
||||
return () => clearInterval(timer)
|
||||
}, [nextMatch])
|
||||
|
||||
return (
|
||||
<div className='flex justify-center'>
|
||||
<div className='grid w-full max-w-xl grid-cols-4 gap-2 md:gap-4'>
|
||||
{[
|
||||
{ value: timeLeft.days, label: 'Days' },
|
||||
{ value: timeLeft.hours, label: 'Hours' },
|
||||
{ value: timeLeft.minutes, label: 'Minutes' },
|
||||
{ value: timeLeft.seconds, label: 'Seconds' },
|
||||
].map((item, index) => (
|
||||
<div key={index}>
|
||||
<div className='relative flex flex-col items-center justify-center rounded-lg border bg-card p-3 shadow-sm md:p-4'>
|
||||
<span className='font-bold text-2xl tabular-nums md:text-4xl lg:text-5xl'>
|
||||
{item.value.toString().padStart(2, '0')}
|
||||
</span>
|
||||
<span className='mt-1 text-muted-foreground text-xs md:text-sm'>
|
||||
{item.label}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import * as React from "react"
|
||||
import * as AvatarPrimitive from "@radix-ui/react-avatar"
|
||||
import * as AvatarPrimitive from '@radix-ui/react-avatar'
|
||||
import type * as React from 'react'
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
function Avatar({
|
||||
className,
|
||||
@@ -11,9 +11,9 @@ function Avatar({
|
||||
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
|
||||
return (
|
||||
<AvatarPrimitive.Root
|
||||
data-slot="avatar"
|
||||
data-slot='avatar'
|
||||
className={cn(
|
||||
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
|
||||
'relative flex size-8 shrink-0 overflow-hidden rounded-full',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -27,8 +27,8 @@ function AvatarImage({
|
||||
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
|
||||
return (
|
||||
<AvatarPrimitive.Image
|
||||
data-slot="avatar-image"
|
||||
className={cn("aspect-square size-full", className)}
|
||||
data-slot='avatar-image'
|
||||
className={cn('aspect-square size-full object-cover!', className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
@@ -40,9 +40,9 @@ function AvatarFallback({
|
||||
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
|
||||
return (
|
||||
<AvatarPrimitive.Fallback
|
||||
data-slot="avatar-fallback"
|
||||
data-slot='avatar-fallback'
|
||||
className={cn(
|
||||
"bg-muted flex size-full items-center justify-center rounded-full",
|
||||
'flex size-full items-center justify-center rounded-full bg-muted',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user