Files
Ivan VasilovandJordi Enric 56de26fe22 chore: Migrate the monorepo to use Tailwind v4 (#45318)
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.

---------

Co-authored-by: Jordi Enric <jordi.err@gmail.com>
2026-04-30 10:53:24 +00:00

132 lines
4.1 KiB
TypeScript

import SectionContainerWithCn from '~/components/Layouts/SectionContainerWithCn'
import { ReactNode, useEffect, useState } from 'react'
import { cn } from 'ui'
export const TicketHeader = ({ children, hidden }: { children: ReactNode; hidden?: boolean }) => {
if (hidden) return null
return (
<SectionContainerWithCn
height="none"
className="grid lg:grid-cols-[127px_1fr_127px] grid-cols-[1fr_1fr] w-full justify-between gap-6 md:gap-8 px-0"
>
{children}
</SectionContainerWithCn>
)
}
const SingleTick = ({ className }: { className?: string }) => {
return (
<div
className={cn(
'w-px h-2.5 bg-neutral-500 shadow-[0px_0px_4px_0px_rgba(255,255,255,0.25)]',
className
)}
/>
)
}
export const TicketHeaderClaim = () => {
return (
<div className="inline-flex justify-start items-center gap-8 w-full order-1 col-span-2 lg:col-auto lg:order-2">
<div className="hidden gap-4 flex-wrap w-full h-2.5 overflow-hidden justify-end shrink flex-1 md:flex">
{Array.from({ length: 7 }).map((_, i) => (
<SingleTick key={i} />
))}
</div>
<div className="text-start md:text-center justify-center text-neutral-500 text-sm font-normal uppercase [text-shadow:0px_0px_4px_rgb(255_255_255/0.25)] lg:text-nowrap grow max-w-[220px] md:max-w-none">
Launch Week is coming. Stay tuned!
</div>
<div className="hidden gap-4 flex-wrap w-full h-2.5 overflow-hidden shrink flex-1 md:flex">
{Array.from({ length: 7 }).map((_, i) => (
<SingleTick key={i} />
))}
</div>
</div>
)
}
interface TicketHeaderRemainingTimeProps {
targetDate: string | Date
}
export const TicketHeaderRemainingTime = ({
targetDate: extTargetDate,
}: TicketHeaderRemainingTimeProps) => {
const [timeLeft, setTimeLeft] = useState<string>('---------------')
useEffect(() => {
const calculateTimeLeft = () => {
const targetDate = new Date(extTargetDate)
const now = new Date()
// Calculate the time difference in milliseconds
const difference = targetDate.getTime() - now.getTime()
if (difference <= 0) {
setTimeLeft('00D:00H:00M:00S')
return
}
const days = Math.floor(difference / (1000 * 60 * 60 * 24))
const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60))
const seconds = Math.floor((difference % (1000 * 60)) / 1000)
// Format the time left
setTimeLeft(
`${days.toString().padStart(2, '0')}D:${hours.toString().padStart(2, '0')}H:${minutes
.toString()
.padStart(2, '0')}M:${seconds.toString().padStart(2, '0')}S`
)
}
calculateTimeLeft()
const interval = setInterval(calculateTimeLeft, 1000)
return () => clearInterval(interval)
}, [extTargetDate])
return (
<div className="flex-1 order-2 lg:order-1">
<div className="text-justify justify-center text-emerald-400 text-sm font-normal uppercase">
{timeLeft}
</div>
<div className="text-neutral-500 text-justify justify-center text-xs font-normal uppercase">
TIME LEFT
</div>
</div>
)
}
export const TicketHeaderDate = () => {
const [time, setTime] = useState<string>('')
useEffect(() => {
const updateTime = () => {
const now = new Date()
const hours = now.getHours().toString().padStart(2, '0')
const minutes = now.getMinutes().toString().padStart(2, '0')
const seconds = now.getSeconds().toString().padStart(2, '0')
setTime(`${hours}:${minutes}:${seconds}`)
}
updateTime()
const interval = setInterval(updateTime, 1000)
return () => clearInterval(interval)
}, [])
return (
<div className="flex-1 order-3 lg:order-3">
<div className="text-end text-neutral-500 text-sm font-normal uppercase [text-shadow:0px_0px_4px_rgb(255_255_255/0.25)]">
{time}
</div>
<div className="text-end text-neutral-500 text-xs font-normal uppercase [text-shadow:0px_0px_4px_rgb(255_255_255/0.25)] text-nowrap">
LOCAL TIME
</div>
</div>
)
}