Spaces:
Sleeping
Sleeping
Merge pull request #12 from ArnavSingh76533/copilot/update-front-page-ui-design
Browse files- components/ui/button.tsx +59 -0
- components/ui/card.tsx +72 -0
- components/ui/input.tsx +19 -0
- components/ui/label.tsx +23 -0
- components/ui/skeleton.tsx +13 -0
- components/ui/switch.tsx +29 -0
- lib/cn.ts +6 -0
- package-lock.json +303 -1
- package.json +8 -1
- pages/global.css +59 -0
- pages/index.tsx +306 -196
- public/streaming-room-.jpg +1 -0
- tsconfig.json +3 -0
- yarn.lock +120 -3
components/ui/button.tsx
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react'
|
| 2 |
+
import { Slot } from '@radix-ui/react-slot'
|
| 3 |
+
import { cva, type VariantProps } from 'class-variance-authority'
|
| 4 |
+
|
| 5 |
+
import { cn } from '@/lib/cn'
|
| 6 |
+
|
| 7 |
+
const buttonVariants = cva(
|
| 8 |
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
| 9 |
+
{
|
| 10 |
+
variants: {
|
| 11 |
+
variant: {
|
| 12 |
+
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
| 13 |
+
destructive:
|
| 14 |
+
'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20',
|
| 15 |
+
outline:
|
| 16 |
+
'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground',
|
| 17 |
+
secondary:
|
| 18 |
+
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
| 19 |
+
ghost:
|
| 20 |
+
'hover:bg-accent hover:text-accent-foreground',
|
| 21 |
+
link: 'text-primary underline-offset-4 hover:underline',
|
| 22 |
+
},
|
| 23 |
+
size: {
|
| 24 |
+
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
| 25 |
+
sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
|
| 26 |
+
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
|
| 27 |
+
icon: 'size-9',
|
| 28 |
+
'icon-sm': 'size-8',
|
| 29 |
+
'icon-lg': 'size-10',
|
| 30 |
+
},
|
| 31 |
+
},
|
| 32 |
+
defaultVariants: {
|
| 33 |
+
variant: 'default',
|
| 34 |
+
size: 'default',
|
| 35 |
+
},
|
| 36 |
+
},
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
export interface ButtonProps
|
| 40 |
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
| 41 |
+
VariantProps<typeof buttonVariants> {
|
| 42 |
+
asChild?: boolean
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
| 46 |
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
| 47 |
+
const Comp = asChild ? Slot : 'button'
|
| 48 |
+
return (
|
| 49 |
+
<Comp
|
| 50 |
+
className={cn(buttonVariants({ variant, size, className }))}
|
| 51 |
+
ref={ref}
|
| 52 |
+
{...props}
|
| 53 |
+
/>
|
| 54 |
+
)
|
| 55 |
+
}
|
| 56 |
+
)
|
| 57 |
+
Button.displayName = 'Button'
|
| 58 |
+
|
| 59 |
+
export { Button, buttonVariants }
|
components/ui/card.tsx
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react'
|
| 2 |
+
|
| 3 |
+
import { cn } from '@/lib/cn'
|
| 4 |
+
|
| 5 |
+
function Card({ className, ...props }: React.ComponentProps<'div'>) {
|
| 6 |
+
return (
|
| 7 |
+
<div
|
| 8 |
+
className={cn(
|
| 9 |
+
'flex flex-col gap-6 rounded-xl border py-6 shadow-sm',
|
| 10 |
+
className,
|
| 11 |
+
)}
|
| 12 |
+
{...props}
|
| 13 |
+
/>
|
| 14 |
+
)
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
| 18 |
+
return (
|
| 19 |
+
<div
|
| 20 |
+
className={cn(
|
| 21 |
+
'grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6',
|
| 22 |
+
className,
|
| 23 |
+
)}
|
| 24 |
+
{...props}
|
| 25 |
+
/>
|
| 26 |
+
)
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
| 30 |
+
return (
|
| 31 |
+
<div
|
| 32 |
+
className={cn('leading-none font-semibold', className)}
|
| 33 |
+
{...props}
|
| 34 |
+
/>
|
| 35 |
+
)
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
|
| 39 |
+
return (
|
| 40 |
+
<div
|
| 41 |
+
className={cn('text-sm', className)}
|
| 42 |
+
{...props}
|
| 43 |
+
/>
|
| 44 |
+
)
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
|
| 48 |
+
return (
|
| 49 |
+
<div
|
| 50 |
+
className={cn('px-6', className)}
|
| 51 |
+
{...props}
|
| 52 |
+
/>
|
| 53 |
+
)
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
| 57 |
+
return (
|
| 58 |
+
<div
|
| 59 |
+
className={cn('flex items-center px-6', className)}
|
| 60 |
+
{...props}
|
| 61 |
+
/>
|
| 62 |
+
)
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
export {
|
| 66 |
+
Card,
|
| 67 |
+
CardHeader,
|
| 68 |
+
CardFooter,
|
| 69 |
+
CardTitle,
|
| 70 |
+
CardDescription,
|
| 71 |
+
CardContent,
|
| 72 |
+
}
|
components/ui/input.tsx
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react'
|
| 2 |
+
|
| 3 |
+
import { cn } from '@/lib/cn'
|
| 4 |
+
|
| 5 |
+
function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
|
| 6 |
+
return (
|
| 7 |
+
<input
|
| 8 |
+
type={type}
|
| 9 |
+
className={cn(
|
| 10 |
+
'file:text-foreground placeholder:text-muted-foreground h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
| 11 |
+
'focus-visible:ring-2 focus-visible:ring-primary-500/50',
|
| 12 |
+
className,
|
| 13 |
+
)}
|
| 14 |
+
{...props}
|
| 15 |
+
/>
|
| 16 |
+
)
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
export { Input }
|
components/ui/label.tsx
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client'
|
| 2 |
+
|
| 3 |
+
import * as React from 'react'
|
| 4 |
+
import * as LabelPrimitive from '@radix-ui/react-label'
|
| 5 |
+
|
| 6 |
+
import { cn } from '@/lib/cn'
|
| 7 |
+
|
| 8 |
+
function Label({
|
| 9 |
+
className,
|
| 10 |
+
...props
|
| 11 |
+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
| 12 |
+
return (
|
| 13 |
+
<LabelPrimitive.Root
|
| 14 |
+
className={cn(
|
| 15 |
+
'flex items-center gap-2 text-sm leading-none font-medium select-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
|
| 16 |
+
className,
|
| 17 |
+
)}
|
| 18 |
+
{...props}
|
| 19 |
+
/>
|
| 20 |
+
)
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
export { Label }
|
components/ui/skeleton.tsx
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from 'react'
|
| 2 |
+
import { cn } from '@/lib/cn'
|
| 3 |
+
|
| 4 |
+
function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
|
| 5 |
+
return (
|
| 6 |
+
<div
|
| 7 |
+
className={cn('animate-pulse rounded-md bg-white/[0.02]', className)}
|
| 8 |
+
{...props}
|
| 9 |
+
/>
|
| 10 |
+
)
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export { Skeleton }
|
components/ui/switch.tsx
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client'
|
| 2 |
+
|
| 3 |
+
import * as React from 'react'
|
| 4 |
+
import * as SwitchPrimitive from '@radix-ui/react-switch'
|
| 5 |
+
|
| 6 |
+
import { cn } from '@/lib/cn'
|
| 7 |
+
|
| 8 |
+
function Switch({
|
| 9 |
+
className,
|
| 10 |
+
...props
|
| 11 |
+
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
|
| 12 |
+
return (
|
| 13 |
+
<SwitchPrimitive.Root
|
| 14 |
+
className={cn(
|
| 15 |
+
'peer inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary-600 data-[state=unchecked]:bg-white/10',
|
| 16 |
+
className,
|
| 17 |
+
)}
|
| 18 |
+
{...props}
|
| 19 |
+
>
|
| 20 |
+
<SwitchPrimitive.Thumb
|
| 21 |
+
className={
|
| 22 |
+
'pointer-events-none block size-4 rounded-full ring-0 transition-transform bg-white data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0'
|
| 23 |
+
}
|
| 24 |
+
/>
|
| 25 |
+
</SwitchPrimitive.Root>
|
| 26 |
+
)
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
export { Switch }
|
lib/cn.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { clsx, type ClassValue } from 'clsx'
|
| 2 |
+
import { twMerge } from 'tailwind-merge'
|
| 3 |
+
|
| 4 |
+
export function cn(...inputs: ClassValue[]) {
|
| 5 |
+
return twMerge(clsx(inputs))
|
| 6 |
+
}
|
package-lock.json
CHANGED
|
@@ -5,6 +5,12 @@
|
|
| 5 |
"packages": {
|
| 6 |
"": {
|
| 7 |
"dependencies": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
"next": "14.2.10",
|
| 9 |
"react": "^18.2.0",
|
| 10 |
"react-beautiful-dnd": "^13.1.1",
|
|
@@ -16,6 +22,7 @@
|
|
| 16 |
"socket.io": "^4.7.2",
|
| 17 |
"socket.io-client": "^4.7.2",
|
| 18 |
"swr": "^2.2.4",
|
|
|
|
| 19 |
"unique-names-generator": "^4.7.1"
|
| 20 |
},
|
| 21 |
"devDependencies": {
|
|
@@ -950,6 +957,261 @@
|
|
| 950 |
"url": "https://opencollective.com/unts"
|
| 951 |
}
|
| 952 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 953 |
"node_modules/@rushstack/eslint-patch": {
|
| 954 |
"version": "1.5.1",
|
| 955 |
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz",
|
|
@@ -1147,7 +1409,7 @@
|
|
| 1147 |
"version": "18.2.18",
|
| 1148 |
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz",
|
| 1149 |
"integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==",
|
| 1150 |
-
"
|
| 1151 |
"license": "MIT",
|
| 1152 |
"dependencies": {
|
| 1153 |
"@types/react": "*"
|
|
@@ -1885,6 +2147,18 @@
|
|
| 1885 |
"node": ">= 6"
|
| 1886 |
}
|
| 1887 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1888 |
"node_modules/classnames": {
|
| 1889 |
"version": "2.5.0",
|
| 1890 |
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz",
|
|
@@ -1900,6 +2174,15 @@
|
|
| 1900 |
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
| 1901 |
"license": "MIT"
|
| 1902 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1903 |
"node_modules/color": {
|
| 1904 |
"version": "4.2.3",
|
| 1905 |
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
|
@@ -4085,6 +4368,15 @@
|
|
| 4085 |
"node": ">=10"
|
| 4086 |
}
|
| 4087 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4088 |
"node_modules/make-error": {
|
| 4089 |
"version": "1.3.6",
|
| 4090 |
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
|
@@ -5655,6 +5947,16 @@
|
|
| 5655 |
"url": "https://opencollective.com/unts"
|
| 5656 |
}
|
| 5657 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5658 |
"node_modules/tailwindcss": {
|
| 5659 |
"version": "3.4.0",
|
| 5660 |
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
|
|
|
| 5 |
"packages": {
|
| 6 |
"": {
|
| 7 |
"dependencies": {
|
| 8 |
+
"@radix-ui/react-label": "^2.1.8",
|
| 9 |
+
"@radix-ui/react-slot": "^1.2.4",
|
| 10 |
+
"@radix-ui/react-switch": "^1.2.6",
|
| 11 |
+
"class-variance-authority": "^0.7.1",
|
| 12 |
+
"clsx": "^2.1.1",
|
| 13 |
+
"lucide-react": "^0.561.0",
|
| 14 |
"next": "14.2.10",
|
| 15 |
"react": "^18.2.0",
|
| 16 |
"react-beautiful-dnd": "^13.1.1",
|
|
|
|
| 22 |
"socket.io": "^4.7.2",
|
| 23 |
"socket.io-client": "^4.7.2",
|
| 24 |
"swr": "^2.2.4",
|
| 25 |
+
"tailwind-merge": "^3.4.0",
|
| 26 |
"unique-names-generator": "^4.7.1"
|
| 27 |
},
|
| 28 |
"devDependencies": {
|
|
|
|
| 957 |
"url": "https://opencollective.com/unts"
|
| 958 |
}
|
| 959 |
},
|
| 960 |
+
"node_modules/@radix-ui/primitive": {
|
| 961 |
+
"version": "1.1.3",
|
| 962 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
|
| 963 |
+
"integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
|
| 964 |
+
"license": "MIT"
|
| 965 |
+
},
|
| 966 |
+
"node_modules/@radix-ui/react-compose-refs": {
|
| 967 |
+
"version": "1.1.2",
|
| 968 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
|
| 969 |
+
"integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
|
| 970 |
+
"license": "MIT",
|
| 971 |
+
"peerDependencies": {
|
| 972 |
+
"@types/react": "*",
|
| 973 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 974 |
+
},
|
| 975 |
+
"peerDependenciesMeta": {
|
| 976 |
+
"@types/react": {
|
| 977 |
+
"optional": true
|
| 978 |
+
}
|
| 979 |
+
}
|
| 980 |
+
},
|
| 981 |
+
"node_modules/@radix-ui/react-context": {
|
| 982 |
+
"version": "1.1.2",
|
| 983 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
|
| 984 |
+
"integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
|
| 985 |
+
"license": "MIT",
|
| 986 |
+
"peerDependencies": {
|
| 987 |
+
"@types/react": "*",
|
| 988 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 989 |
+
},
|
| 990 |
+
"peerDependenciesMeta": {
|
| 991 |
+
"@types/react": {
|
| 992 |
+
"optional": true
|
| 993 |
+
}
|
| 994 |
+
}
|
| 995 |
+
},
|
| 996 |
+
"node_modules/@radix-ui/react-label": {
|
| 997 |
+
"version": "2.1.8",
|
| 998 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz",
|
| 999 |
+
"integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==",
|
| 1000 |
+
"license": "MIT",
|
| 1001 |
+
"dependencies": {
|
| 1002 |
+
"@radix-ui/react-primitive": "2.1.4"
|
| 1003 |
+
},
|
| 1004 |
+
"peerDependencies": {
|
| 1005 |
+
"@types/react": "*",
|
| 1006 |
+
"@types/react-dom": "*",
|
| 1007 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
| 1008 |
+
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1009 |
+
},
|
| 1010 |
+
"peerDependenciesMeta": {
|
| 1011 |
+
"@types/react": {
|
| 1012 |
+
"optional": true
|
| 1013 |
+
},
|
| 1014 |
+
"@types/react-dom": {
|
| 1015 |
+
"optional": true
|
| 1016 |
+
}
|
| 1017 |
+
}
|
| 1018 |
+
},
|
| 1019 |
+
"node_modules/@radix-ui/react-primitive": {
|
| 1020 |
+
"version": "2.1.4",
|
| 1021 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz",
|
| 1022 |
+
"integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==",
|
| 1023 |
+
"license": "MIT",
|
| 1024 |
+
"dependencies": {
|
| 1025 |
+
"@radix-ui/react-slot": "1.2.4"
|
| 1026 |
+
},
|
| 1027 |
+
"peerDependencies": {
|
| 1028 |
+
"@types/react": "*",
|
| 1029 |
+
"@types/react-dom": "*",
|
| 1030 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
| 1031 |
+
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1032 |
+
},
|
| 1033 |
+
"peerDependenciesMeta": {
|
| 1034 |
+
"@types/react": {
|
| 1035 |
+
"optional": true
|
| 1036 |
+
},
|
| 1037 |
+
"@types/react-dom": {
|
| 1038 |
+
"optional": true
|
| 1039 |
+
}
|
| 1040 |
+
}
|
| 1041 |
+
},
|
| 1042 |
+
"node_modules/@radix-ui/react-slot": {
|
| 1043 |
+
"version": "1.2.4",
|
| 1044 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
|
| 1045 |
+
"integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
|
| 1046 |
+
"license": "MIT",
|
| 1047 |
+
"dependencies": {
|
| 1048 |
+
"@radix-ui/react-compose-refs": "1.1.2"
|
| 1049 |
+
},
|
| 1050 |
+
"peerDependencies": {
|
| 1051 |
+
"@types/react": "*",
|
| 1052 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1053 |
+
},
|
| 1054 |
+
"peerDependenciesMeta": {
|
| 1055 |
+
"@types/react": {
|
| 1056 |
+
"optional": true
|
| 1057 |
+
}
|
| 1058 |
+
}
|
| 1059 |
+
},
|
| 1060 |
+
"node_modules/@radix-ui/react-switch": {
|
| 1061 |
+
"version": "1.2.6",
|
| 1062 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz",
|
| 1063 |
+
"integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==",
|
| 1064 |
+
"license": "MIT",
|
| 1065 |
+
"dependencies": {
|
| 1066 |
+
"@radix-ui/primitive": "1.1.3",
|
| 1067 |
+
"@radix-ui/react-compose-refs": "1.1.2",
|
| 1068 |
+
"@radix-ui/react-context": "1.1.2",
|
| 1069 |
+
"@radix-ui/react-primitive": "2.1.3",
|
| 1070 |
+
"@radix-ui/react-use-controllable-state": "1.2.2",
|
| 1071 |
+
"@radix-ui/react-use-previous": "1.1.1",
|
| 1072 |
+
"@radix-ui/react-use-size": "1.1.1"
|
| 1073 |
+
},
|
| 1074 |
+
"peerDependencies": {
|
| 1075 |
+
"@types/react": "*",
|
| 1076 |
+
"@types/react-dom": "*",
|
| 1077 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
| 1078 |
+
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1079 |
+
},
|
| 1080 |
+
"peerDependenciesMeta": {
|
| 1081 |
+
"@types/react": {
|
| 1082 |
+
"optional": true
|
| 1083 |
+
},
|
| 1084 |
+
"@types/react-dom": {
|
| 1085 |
+
"optional": true
|
| 1086 |
+
}
|
| 1087 |
+
}
|
| 1088 |
+
},
|
| 1089 |
+
"node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": {
|
| 1090 |
+
"version": "2.1.3",
|
| 1091 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
|
| 1092 |
+
"integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
|
| 1093 |
+
"license": "MIT",
|
| 1094 |
+
"dependencies": {
|
| 1095 |
+
"@radix-ui/react-slot": "1.2.3"
|
| 1096 |
+
},
|
| 1097 |
+
"peerDependencies": {
|
| 1098 |
+
"@types/react": "*",
|
| 1099 |
+
"@types/react-dom": "*",
|
| 1100 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
| 1101 |
+
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1102 |
+
},
|
| 1103 |
+
"peerDependenciesMeta": {
|
| 1104 |
+
"@types/react": {
|
| 1105 |
+
"optional": true
|
| 1106 |
+
},
|
| 1107 |
+
"@types/react-dom": {
|
| 1108 |
+
"optional": true
|
| 1109 |
+
}
|
| 1110 |
+
}
|
| 1111 |
+
},
|
| 1112 |
+
"node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-slot": {
|
| 1113 |
+
"version": "1.2.3",
|
| 1114 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
|
| 1115 |
+
"integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
|
| 1116 |
+
"license": "MIT",
|
| 1117 |
+
"dependencies": {
|
| 1118 |
+
"@radix-ui/react-compose-refs": "1.1.2"
|
| 1119 |
+
},
|
| 1120 |
+
"peerDependencies": {
|
| 1121 |
+
"@types/react": "*",
|
| 1122 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1123 |
+
},
|
| 1124 |
+
"peerDependenciesMeta": {
|
| 1125 |
+
"@types/react": {
|
| 1126 |
+
"optional": true
|
| 1127 |
+
}
|
| 1128 |
+
}
|
| 1129 |
+
},
|
| 1130 |
+
"node_modules/@radix-ui/react-use-controllable-state": {
|
| 1131 |
+
"version": "1.2.2",
|
| 1132 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
|
| 1133 |
+
"integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
|
| 1134 |
+
"license": "MIT",
|
| 1135 |
+
"dependencies": {
|
| 1136 |
+
"@radix-ui/react-use-effect-event": "0.0.2",
|
| 1137 |
+
"@radix-ui/react-use-layout-effect": "1.1.1"
|
| 1138 |
+
},
|
| 1139 |
+
"peerDependencies": {
|
| 1140 |
+
"@types/react": "*",
|
| 1141 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1142 |
+
},
|
| 1143 |
+
"peerDependenciesMeta": {
|
| 1144 |
+
"@types/react": {
|
| 1145 |
+
"optional": true
|
| 1146 |
+
}
|
| 1147 |
+
}
|
| 1148 |
+
},
|
| 1149 |
+
"node_modules/@radix-ui/react-use-effect-event": {
|
| 1150 |
+
"version": "0.0.2",
|
| 1151 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
|
| 1152 |
+
"integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
|
| 1153 |
+
"license": "MIT",
|
| 1154 |
+
"dependencies": {
|
| 1155 |
+
"@radix-ui/react-use-layout-effect": "1.1.1"
|
| 1156 |
+
},
|
| 1157 |
+
"peerDependencies": {
|
| 1158 |
+
"@types/react": "*",
|
| 1159 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1160 |
+
},
|
| 1161 |
+
"peerDependenciesMeta": {
|
| 1162 |
+
"@types/react": {
|
| 1163 |
+
"optional": true
|
| 1164 |
+
}
|
| 1165 |
+
}
|
| 1166 |
+
},
|
| 1167 |
+
"node_modules/@radix-ui/react-use-layout-effect": {
|
| 1168 |
+
"version": "1.1.1",
|
| 1169 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
|
| 1170 |
+
"integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
|
| 1171 |
+
"license": "MIT",
|
| 1172 |
+
"peerDependencies": {
|
| 1173 |
+
"@types/react": "*",
|
| 1174 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1175 |
+
},
|
| 1176 |
+
"peerDependenciesMeta": {
|
| 1177 |
+
"@types/react": {
|
| 1178 |
+
"optional": true
|
| 1179 |
+
}
|
| 1180 |
+
}
|
| 1181 |
+
},
|
| 1182 |
+
"node_modules/@radix-ui/react-use-previous": {
|
| 1183 |
+
"version": "1.1.1",
|
| 1184 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
|
| 1185 |
+
"integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
|
| 1186 |
+
"license": "MIT",
|
| 1187 |
+
"peerDependencies": {
|
| 1188 |
+
"@types/react": "*",
|
| 1189 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1190 |
+
},
|
| 1191 |
+
"peerDependenciesMeta": {
|
| 1192 |
+
"@types/react": {
|
| 1193 |
+
"optional": true
|
| 1194 |
+
}
|
| 1195 |
+
}
|
| 1196 |
+
},
|
| 1197 |
+
"node_modules/@radix-ui/react-use-size": {
|
| 1198 |
+
"version": "1.1.1",
|
| 1199 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
|
| 1200 |
+
"integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
|
| 1201 |
+
"license": "MIT",
|
| 1202 |
+
"dependencies": {
|
| 1203 |
+
"@radix-ui/react-use-layout-effect": "1.1.1"
|
| 1204 |
+
},
|
| 1205 |
+
"peerDependencies": {
|
| 1206 |
+
"@types/react": "*",
|
| 1207 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 1208 |
+
},
|
| 1209 |
+
"peerDependenciesMeta": {
|
| 1210 |
+
"@types/react": {
|
| 1211 |
+
"optional": true
|
| 1212 |
+
}
|
| 1213 |
+
}
|
| 1214 |
+
},
|
| 1215 |
"node_modules/@rushstack/eslint-patch": {
|
| 1216 |
"version": "1.5.1",
|
| 1217 |
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz",
|
|
|
|
| 1409 |
"version": "18.2.18",
|
| 1410 |
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz",
|
| 1411 |
"integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==",
|
| 1412 |
+
"devOptional": true,
|
| 1413 |
"license": "MIT",
|
| 1414 |
"dependencies": {
|
| 1415 |
"@types/react": "*"
|
|
|
|
| 2147 |
"node": ">= 6"
|
| 2148 |
}
|
| 2149 |
},
|
| 2150 |
+
"node_modules/class-variance-authority": {
|
| 2151 |
+
"version": "0.7.1",
|
| 2152 |
+
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
|
| 2153 |
+
"integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
|
| 2154 |
+
"license": "Apache-2.0",
|
| 2155 |
+
"dependencies": {
|
| 2156 |
+
"clsx": "^2.1.1"
|
| 2157 |
+
},
|
| 2158 |
+
"funding": {
|
| 2159 |
+
"url": "https://polar.sh/cva"
|
| 2160 |
+
}
|
| 2161 |
+
},
|
| 2162 |
"node_modules/classnames": {
|
| 2163 |
"version": "2.5.0",
|
| 2164 |
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz",
|
|
|
|
| 2174 |
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
| 2175 |
"license": "MIT"
|
| 2176 |
},
|
| 2177 |
+
"node_modules/clsx": {
|
| 2178 |
+
"version": "2.1.1",
|
| 2179 |
+
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
| 2180 |
+
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
| 2181 |
+
"license": "MIT",
|
| 2182 |
+
"engines": {
|
| 2183 |
+
"node": ">=6"
|
| 2184 |
+
}
|
| 2185 |
+
},
|
| 2186 |
"node_modules/color": {
|
| 2187 |
"version": "4.2.3",
|
| 2188 |
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
|
|
|
| 4368 |
"node": ">=10"
|
| 4369 |
}
|
| 4370 |
},
|
| 4371 |
+
"node_modules/lucide-react": {
|
| 4372 |
+
"version": "0.561.0",
|
| 4373 |
+
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.561.0.tgz",
|
| 4374 |
+
"integrity": "sha512-Y59gMY38tl4/i0qewcqohPdEbieBy7SovpBL9IFebhc2mDd8x4PZSOsiFRkpPcOq6bj1r/mjH/Rk73gSlIJP2A==",
|
| 4375 |
+
"license": "ISC",
|
| 4376 |
+
"peerDependencies": {
|
| 4377 |
+
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
| 4378 |
+
}
|
| 4379 |
+
},
|
| 4380 |
"node_modules/make-error": {
|
| 4381 |
"version": "1.3.6",
|
| 4382 |
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
|
|
|
| 5947 |
"url": "https://opencollective.com/unts"
|
| 5948 |
}
|
| 5949 |
},
|
| 5950 |
+
"node_modules/tailwind-merge": {
|
| 5951 |
+
"version": "3.4.0",
|
| 5952 |
+
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz",
|
| 5953 |
+
"integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==",
|
| 5954 |
+
"license": "MIT",
|
| 5955 |
+
"funding": {
|
| 5956 |
+
"type": "github",
|
| 5957 |
+
"url": "https://github.com/sponsors/dcastil"
|
| 5958 |
+
}
|
| 5959 |
+
},
|
| 5960 |
"node_modules/tailwindcss": {
|
| 5961 |
"version": "3.4.0",
|
| 5962 |
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
package.json
CHANGED
|
@@ -7,6 +7,12 @@
|
|
| 7 |
"lint": "next lint"
|
| 8 |
},
|
| 9 |
"dependencies": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
"next": "14.2.10",
|
| 11 |
"react": "^18.2.0",
|
| 12 |
"react-beautiful-dnd": "^13.1.1",
|
|
@@ -18,6 +24,7 @@
|
|
| 18 |
"socket.io": "^4.7.2",
|
| 19 |
"socket.io-client": "^4.7.2",
|
| 20 |
"swr": "^2.2.4",
|
|
|
|
| 21 |
"unique-names-generator": "^4.7.1"
|
| 22 |
},
|
| 23 |
"devDependencies": {
|
|
@@ -37,4 +44,4 @@
|
|
| 37 |
"ts-node": "^10.9.2",
|
| 38 |
"typescript": "5.3.3"
|
| 39 |
}
|
| 40 |
-
}
|
|
|
|
| 7 |
"lint": "next lint"
|
| 8 |
},
|
| 9 |
"dependencies": {
|
| 10 |
+
"@radix-ui/react-label": "^2.1.8",
|
| 11 |
+
"@radix-ui/react-slot": "^1.2.4",
|
| 12 |
+
"@radix-ui/react-switch": "^1.2.6",
|
| 13 |
+
"class-variance-authority": "^0.7.1",
|
| 14 |
+
"clsx": "^2.1.1",
|
| 15 |
+
"lucide-react": "^0.561.0",
|
| 16 |
"next": "14.2.10",
|
| 17 |
"react": "^18.2.0",
|
| 18 |
"react-beautiful-dnd": "^13.1.1",
|
|
|
|
| 24 |
"socket.io": "^4.7.2",
|
| 25 |
"socket.io-client": "^4.7.2",
|
| 26 |
"swr": "^2.2.4",
|
| 27 |
+
"tailwind-merge": "^3.4.0",
|
| 28 |
"unique-names-generator": "^4.7.1"
|
| 29 |
},
|
| 30 |
"devDependencies": {
|
|
|
|
| 44 |
"ts-node": "^10.9.2",
|
| 45 |
"typescript": "5.3.3"
|
| 46 |
}
|
| 47 |
+
}
|
pages/global.css
CHANGED
|
@@ -149,3 +149,62 @@ html {
|
|
| 149 |
object-fit: contain;
|
| 150 |
}
|
| 151 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
object-fit: contain;
|
| 150 |
}
|
| 151 |
}
|
| 152 |
+
|
| 153 |
+
/* New animations for front page */
|
| 154 |
+
@keyframes fade-in {
|
| 155 |
+
from {
|
| 156 |
+
opacity: 0;
|
| 157 |
+
}
|
| 158 |
+
to {
|
| 159 |
+
opacity: 1;
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
@keyframes fade-up {
|
| 164 |
+
from {
|
| 165 |
+
opacity: 0;
|
| 166 |
+
transform: translateY(8px);
|
| 167 |
+
}
|
| 168 |
+
to {
|
| 169 |
+
opacity: 1;
|
| 170 |
+
transform: translateY(0);
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
@keyframes pulse-slow {
|
| 175 |
+
0%,
|
| 176 |
+
100% {
|
| 177 |
+
opacity: 1;
|
| 178 |
+
transform: scale(1);
|
| 179 |
+
}
|
| 180 |
+
50% {
|
| 181 |
+
opacity: 0.7;
|
| 182 |
+
transform: scale(1.01);
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
@keyframes bounce-subtle {
|
| 187 |
+
0%,
|
| 188 |
+
100% {
|
| 189 |
+
transform: translateY(0);
|
| 190 |
+
}
|
| 191 |
+
50% {
|
| 192 |
+
transform: translateY(2px);
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
.animate-fade-in {
|
| 197 |
+
animation: fade-in 150ms ease-out forwards;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.animate-fade-up {
|
| 201 |
+
animation: fade-up 150ms ease-out both;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
.animate-pulse-slow {
|
| 205 |
+
animation: pulse-slow 8s ease-in-out infinite;
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
.animate-bounce-subtle {
|
| 209 |
+
animation: bounce-subtle 2.5s ease-in-out infinite;
|
| 210 |
+
}
|
pages/index.tsx
CHANGED
|
@@ -1,10 +1,15 @@
|
|
| 1 |
import Layout from "../components/Layout"
|
| 2 |
import { useState, useEffect } from "react"
|
| 3 |
-
import InputText from "../components/input/InputText"
|
| 4 |
-
import Button from "../components/action/Button"
|
| 5 |
import { useRouter } from "next/router"
|
| 6 |
-
import { Tooltip } from "react-tooltip"
|
| 7 |
import useSWR from "swr"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
interface PublicRoom {
|
| 10 |
id: string
|
|
@@ -12,23 +17,30 @@ interface PublicRoom {
|
|
| 12 |
memberCount: number
|
| 13 |
}
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
export default function Index() {
|
| 16 |
const router = useRouter()
|
| 17 |
-
const { data } = useSWR("/api/stats", (url) =>
|
| 18 |
-
fetch(url).then((r) => r.json())
|
| 19 |
-
)
|
| 20 |
-
const { data: roomsData } = useSWR<{ rooms: PublicRoom[] }>(
|
| 21 |
-
"/api/rooms",
|
| 22 |
-
(url) => fetch(url).then((r) => r.json()),
|
| 23 |
-
{ refreshInterval: 5000 } // Auto-refresh every 5 seconds
|
| 24 |
-
)
|
| 25 |
-
|
| 26 |
const [room, setRoom] = useState("")
|
| 27 |
const [userName, setUserName] = useState("")
|
| 28 |
const [isPublic, setIsPublic] = useState(false)
|
| 29 |
const [nameError, setNameError] = useState("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
// Load saved user name from localStorage on mount
|
| 32 |
useEffect(() => {
|
| 33 |
if (typeof window !== "undefined") {
|
| 34 |
const savedName = localStorage.getItem("userName")
|
|
@@ -36,213 +48,311 @@ export default function Index() {
|
|
| 36 |
setUserName(savedName)
|
| 37 |
}
|
| 38 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
}, [])
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
return (
|
| 42 |
<Layout meta={{ robots: "index, archive, follow" }} showNavbar={false}>
|
| 43 |
-
<div className=
|
| 44 |
-
<
|
| 45 |
-
className={
|
| 46 |
-
"
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
e.preventDefault()
|
| 50 |
-
|
| 51 |
-
if (room.length >= 4) {
|
| 52 |
-
// Save user name to localStorage
|
| 53 |
-
if (userName.trim() && typeof window !== "undefined") {
|
| 54 |
-
localStorage.setItem("userName", userName.trim())
|
| 55 |
-
}
|
| 56 |
-
await router.push("/room/" + room)
|
| 57 |
-
}
|
| 58 |
-
}}
|
| 59 |
>
|
| 60 |
-
<div className="
|
| 61 |
-
<
|
| 62 |
-
|
| 63 |
-
</
|
| 64 |
-
<
|
| 65 |
-
</div>
|
| 66 |
-
|
| 67 |
-
{/* User Name Input */}
|
| 68 |
-
<div>
|
| 69 |
-
<label className="block text-sm font-medium text-dark-300 mb-1.5">
|
| 70 |
-
Your Name {" "}
|
| 71 |
-
<span className="text-xs text-dark-500">(optional for joining, required for creating)</span>
|
| 72 |
-
</label>
|
| 73 |
-
<InputText
|
| 74 |
-
value={userName}
|
| 75 |
-
placeholder={"Enter your display name"}
|
| 76 |
-
onChange={(value) => {
|
| 77 |
-
setUserName(value)
|
| 78 |
-
setNameError("")
|
| 79 |
-
}}
|
| 80 |
-
/>
|
| 81 |
-
{nameError && (
|
| 82 |
-
<p className="text-red-500 text-xs mt-1">{nameError}</p>
|
| 83 |
-
)}
|
| 84 |
</div>
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
<
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
<
|
| 92 |
-
value={room}
|
| 93 |
-
placeholder={"Enter a room ID"}
|
| 94 |
-
onChange={(value) =>
|
| 95 |
-
setRoom(value.toLowerCase().replace(/[^a-z]/g, ""))
|
| 96 |
-
}
|
| 97 |
-
/>
|
| 98 |
</div>
|
| 99 |
-
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
<Button
|
| 102 |
-
|
| 103 |
-
className={"px-4 py-2.5 font-medium"}
|
| 104 |
-
actionClasses={
|
| 105 |
-
"bg-accent-600 hover:bg-accent-700 active:bg-accent-800 shadow-lg hover:shadow-xl"
|
| 106 |
-
}
|
| 107 |
onClick={() => {
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
setNameError("Please enter your name before creating a room")
|
| 111 |
-
return
|
| 112 |
-
}
|
| 113 |
-
|
| 114 |
-
// Save user name to localStorage
|
| 115 |
-
if (typeof window !== "undefined") {
|
| 116 |
-
localStorage.setItem("userName", userName.trim())
|
| 117 |
-
}
|
| 118 |
-
|
| 119 |
-
fetch("/api/generate")
|
| 120 |
-
.then((r) => r.json())
|
| 121 |
-
.then(async ({ roomId }) => {
|
| 122 |
-
if (
|
| 123 |
-
typeof roomId === "string" &&
|
| 124 |
-
roomId.length >= 4 &&
|
| 125 |
-
roomId.match(/^[a-z]{4,}$/)
|
| 126 |
-
) {
|
| 127 |
-
console.log("Generated new roomId:", roomId)
|
| 128 |
-
// Store room metadata in sessionStorage
|
| 129 |
-
if (typeof window !== "undefined") {
|
| 130 |
-
sessionStorage.setItem(
|
| 131 |
-
`room_${roomId}_meta`,
|
| 132 |
-
JSON.stringify({ isPublic })
|
| 133 |
-
)
|
| 134 |
-
}
|
| 135 |
-
await router.push("/room/" + roomId)
|
| 136 |
-
} else {
|
| 137 |
-
throw Error("Invalid roomId generated: " + roomId)
|
| 138 |
-
}
|
| 139 |
-
})
|
| 140 |
-
.catch((error) => {
|
| 141 |
-
console.error("Failed to generate new roomId", error)
|
| 142 |
-
})
|
| 143 |
}}
|
|
|
|
| 144 |
>
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
tooltip={room.length < 4 ? "Invalid room id" : "Join room"}
|
| 149 |
-
className={"px-4 py-2.5 font-medium"}
|
| 150 |
-
actionClasses={
|
| 151 |
-
room.length >= 4
|
| 152 |
-
? "bg-primary-600 hover:bg-primary-700 active:bg-primary-800 shadow-lg hover:shadow-xl hover:shadow-glow"
|
| 153 |
-
: "bg-dark-700 hover:bg-dark-600 active:bg-red-700 cursor-not-allowed opacity-50"
|
| 154 |
-
}
|
| 155 |
-
disabled={room.length < 4}
|
| 156 |
-
type={"submit"}
|
| 157 |
-
>
|
| 158 |
-
Join room
|
| 159 |
</Button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
</div>
|
| 161 |
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
onChange={(e) => setIsPublic(e.target.checked)}
|
| 169 |
-
className="w-4 h-4 rounded border-dark-600 text-primary-600 focus:ring-primary-500 focus:ring-offset-dark-900"
|
| 170 |
-
/>
|
| 171 |
-
<span className="text-sm text-dark-300">
|
| 172 |
-
Make room public (visible in lobby)
|
| 173 |
-
</span>
|
| 174 |
-
</label>
|
| 175 |
</div>
|
| 176 |
-
|
| 177 |
-
<div className=
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
</
|
| 185 |
-
<
|
| 186 |
-
<span className="inline-block w-2 h-2 bg-accent-500 rounded-full"></span>
|
| 187 |
-
<span>{data?.users || 0} Users</span>
|
| 188 |
-
</div>
|
| 189 |
</div>
|
| 190 |
-
</small>
|
| 191 |
-
</div>
|
| 192 |
-
</form>
|
| 193 |
-
</div>
|
| 194 |
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
</div>
|
| 213 |
-
|
| 214 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
</div>
|
| 216 |
-
</
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
>
|
| 229 |
-
Join
|
|
|
|
| 230 |
</Button>
|
| 231 |
</div>
|
| 232 |
-
|
| 233 |
-
</
|
| 234 |
-
</
|
| 235 |
</div>
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
<Tooltip
|
| 239 |
-
style={{
|
| 240 |
-
backgroundColor: "var(--dark-700)",
|
| 241 |
-
borderRadius: "0.5rem",
|
| 242 |
-
padding: "0.5rem 0.75rem",
|
| 243 |
-
fontSize: "0.875rem",
|
| 244 |
-
}}
|
| 245 |
-
/>
|
| 246 |
</Layout>
|
| 247 |
)
|
| 248 |
}
|
|
|
|
| 1 |
import Layout from "../components/Layout"
|
| 2 |
import { useState, useEffect } from "react"
|
|
|
|
|
|
|
| 3 |
import { useRouter } from "next/router"
|
|
|
|
| 4 |
import useSWR from "swr"
|
| 5 |
+
import { Button } from "@/components/ui/button"
|
| 6 |
+
import { Input } from "@/components/ui/input"
|
| 7 |
+
import { Label } from "@/components/ui/label"
|
| 8 |
+
import { Card, CardContent } from "@/components/ui/card"
|
| 9 |
+
import { Skeleton } from "@/components/ui/skeleton"
|
| 10 |
+
import { Switch } from "@/components/ui/switch"
|
| 11 |
+
import { Play, Users, ChevronRight, Search, Settings, ChevronDown } from "lucide-react"
|
| 12 |
+
import { cn } from "@/lib/cn"
|
| 13 |
|
| 14 |
interface PublicRoom {
|
| 15 |
id: string
|
|
|
|
| 17 |
memberCount: number
|
| 18 |
}
|
| 19 |
|
| 20 |
+
interface Stats {
|
| 21 |
+
rooms: number
|
| 22 |
+
users: number
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
const fetcher = (url: string) => fetch(url).then((r) => r.json())
|
| 26 |
+
|
| 27 |
export default function Index() {
|
| 28 |
const router = useRouter()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
const [room, setRoom] = useState("")
|
| 30 |
const [userName, setUserName] = useState("")
|
| 31 |
const [isPublic, setIsPublic] = useState(false)
|
| 32 |
const [nameError, setNameError] = useState("")
|
| 33 |
+
const [isGenerating, setIsGenerating] = useState(false)
|
| 34 |
+
const [mounted, setMounted] = useState(false)
|
| 35 |
+
const [scrolled, setScrolled] = useState(false)
|
| 36 |
+
|
| 37 |
+
const { data: stats, isLoading: statsLoading } = useSWR<Stats>("/api/stats", fetcher)
|
| 38 |
+
const { data: roomsData, isLoading: roomsLoading } = useSWR<{ rooms: PublicRoom[] }>(
|
| 39 |
+
"/api/rooms",
|
| 40 |
+
fetcher,
|
| 41 |
+
{ refreshInterval: 5000 }
|
| 42 |
+
)
|
| 43 |
|
|
|
|
| 44 |
useEffect(() => {
|
| 45 |
if (typeof window !== "undefined") {
|
| 46 |
const savedName = localStorage.getItem("userName")
|
|
|
|
| 48 |
setUserName(savedName)
|
| 49 |
}
|
| 50 |
}
|
| 51 |
+
setMounted(true)
|
| 52 |
+
|
| 53 |
+
const handleScroll = () => {
|
| 54 |
+
setScrolled(window.scrollY > 20)
|
| 55 |
+
}
|
| 56 |
+
window.addEventListener("scroll", handleScroll, { passive: true })
|
| 57 |
+
return () => window.removeEventListener("scroll", handleScroll)
|
| 58 |
}, [])
|
| 59 |
|
| 60 |
+
const handleJoinRoom = async (roomId: string) => {
|
| 61 |
+
// Save user name if provided
|
| 62 |
+
if (userName.trim() && typeof window !== "undefined") {
|
| 63 |
+
localStorage.setItem("userName", userName.trim())
|
| 64 |
+
}
|
| 65 |
+
await router.push("/room/" + roomId)
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
const handleGenerateRoom = () => {
|
| 69 |
+
// Validate name
|
| 70 |
+
if (!userName.trim()) {
|
| 71 |
+
setNameError("Please enter your name before creating a room")
|
| 72 |
+
return
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
setIsGenerating(true)
|
| 76 |
+
// Save user name to localStorage
|
| 77 |
+
if (typeof window !== "undefined") {
|
| 78 |
+
localStorage.setItem("userName", userName.trim())
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
fetch("/api/generate")
|
| 82 |
+
.then((r) => r.json())
|
| 83 |
+
.then(async ({ roomId }) => {
|
| 84 |
+
if (
|
| 85 |
+
typeof roomId === "string" &&
|
| 86 |
+
roomId.length >= 4 &&
|
| 87 |
+
roomId.match(/^[a-z]{4,}$/)
|
| 88 |
+
) {
|
| 89 |
+
console.log("Generated new roomId:", roomId)
|
| 90 |
+
// Store room metadata in sessionStorage
|
| 91 |
+
if (typeof window !== "undefined") {
|
| 92 |
+
sessionStorage.setItem(
|
| 93 |
+
`room_${roomId}_meta`,
|
| 94 |
+
JSON.stringify({ isPublic })
|
| 95 |
+
)
|
| 96 |
+
}
|
| 97 |
+
await router.push("/room/" + roomId)
|
| 98 |
+
} else {
|
| 99 |
+
throw Error("Invalid roomId generated: " + roomId)
|
| 100 |
+
}
|
| 101 |
+
})
|
| 102 |
+
.catch((error) => {
|
| 103 |
+
console.error("Failed to generate new roomId", error)
|
| 104 |
+
setIsGenerating(false)
|
| 105 |
+
})
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
return (
|
| 109 |
<Layout meta={{ robots: "index, archive, follow" }} showNavbar={false}>
|
| 110 |
+
<div className="min-h-screen bg-[#0B0E13]">
|
| 111 |
+
<nav
|
| 112 |
+
className={cn(
|
| 113 |
+
"fixed top-0 left-0 right-0 z-50 h-[52px] flex items-center justify-between px-6 transition-all duration-200",
|
| 114 |
+
scrolled ? "bg-[#0B0E13]/95 backdrop-blur-sm border-b border-white/[0.04]" : "bg-transparent",
|
| 115 |
+
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
>
|
| 117 |
+
<div className="flex items-center gap-3">
|
| 118 |
+
<div className="w-9 h-9 rounded-xl bg-gradient-to-br from-[#3B82F6] to-[#8B5CF6] flex items-center justify-center">
|
| 119 |
+
<Play className="w-4 h-4 fill-white text-white" />
|
| 120 |
+
</div>
|
| 121 |
+
<span className="text-lg font-bold text-white tracking-tight">Streamer</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
</div>
|
| 123 |
+
<div className="flex items-center gap-1.5">
|
| 124 |
+
<button className="w-9 h-9 rounded-full bg-white/[0.04] hover:bg-white/[0.06] flex items-center justify-center transition-colors duration-150">
|
| 125 |
+
<Search className="w-4 h-4 text-white/40" />
|
| 126 |
+
</button>
|
| 127 |
+
<button className="w-9 h-9 rounded-full bg-white/[0.04] hover:bg-white/[0.06] flex items-center justify-center transition-colors duration-150">
|
| 128 |
+
<Settings className="w-4 h-4 text-white/40" />
|
| 129 |
+
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
</div>
|
| 131 |
+
</nav>
|
| 132 |
+
|
| 133 |
+
<div className="relative h-[80vh] flex items-center justify-center overflow-hidden">
|
| 134 |
+
<div className="absolute inset-0 bg-gradient-to-b from-[#0B0E13] via-[#0B0E13] to-[#0B0E13]" />
|
| 135 |
+
<div className="absolute top-1/3 left-1/4 w-[300px] h-[300px] rounded-full bg-[#3B82F6]/[0.06] blur-[100px] animate-pulse-slow" />
|
| 136 |
+
<div
|
| 137 |
+
className="absolute bottom-1/3 right-1/4 w-[250px] h-[250px] rounded-full bg-[#8B5CF6]/[0.05] blur-[80px] animate-pulse-slow"
|
| 138 |
+
style={{ animationDelay: "3s" }}
|
| 139 |
+
/>
|
| 140 |
+
|
| 141 |
+
<div className="relative z-10 w-full max-w-6xl mx-auto px-6 text-center animate-fade-up">
|
| 142 |
+
<h1 className="text-4xl md:text-5xl lg:text-6xl font-extrabold tracking-tight leading-[1.1] text-white mb-4">
|
| 143 |
+
Watch Together,
|
| 144 |
+
<br />
|
| 145 |
+
<span className="bg-gradient-to-r from-[#3B82F6] to-[#8B5CF6] bg-clip-text text-transparent">
|
| 146 |
+
Stream Anywhere
|
| 147 |
+
</span>
|
| 148 |
+
</h1>
|
| 149 |
+
<p className="text-sm text-white/25 max-w-sm mx-auto mb-8 font-light">
|
| 150 |
+
Create a room and invite friends to watch in perfect sync
|
| 151 |
+
</p>
|
| 152 |
+
|
| 153 |
<Button
|
| 154 |
+
size="lg"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
onClick={() => {
|
| 156 |
+
const formSection = document.getElementById("join-section")
|
| 157 |
+
formSection?.scrollIntoView({ behavior: "smooth" })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
}}
|
| 159 |
+
className="group h-12 px-8 bg-gradient-to-r from-[#3B82F6] to-[#8B5CF6] hover:from-[#4B8FF7] hover:to-[#9B6CF7] text-white text-base font-semibold rounded-2xl shadow-[0_0_24px_rgba(59,130,246,0.2)] hover:shadow-[0_0_32px_rgba(59,130,246,0.3)] transition-all duration-150 active:scale-[0.98]"
|
| 160 |
>
|
| 161 |
+
<Play className="w-4 h-4 mr-2 fill-white" />
|
| 162 |
+
Get Started
|
| 163 |
+
<ChevronRight className="w-4 h-4 ml-1 group-hover:translate-x-0.5 transition-transform duration-150" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
</Button>
|
| 165 |
+
|
| 166 |
+
<div className="flex items-center justify-center gap-2.5 mt-6">
|
| 167 |
+
<div className="flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-white/[0.02]">
|
| 168 |
+
<div className="w-1 h-1 bg-white/20 rounded-full" />
|
| 169 |
+
<span className="text-[11px] text-white/20">
|
| 170 |
+
{mounted && !statsLoading ? (stats?.rooms ?? 0) : "—"} Rooms
|
| 171 |
+
</span>
|
| 172 |
+
</div>
|
| 173 |
+
<div className="flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-white/[0.02]">
|
| 174 |
+
<div className="w-1 h-1 bg-white/20 rounded-full" />
|
| 175 |
+
<span className="text-[11px] text-white/20">
|
| 176 |
+
{mounted && !statsLoading ? (stats?.users ?? 0) : "—"} Watching
|
| 177 |
+
</span>
|
| 178 |
+
</div>
|
| 179 |
+
</div>
|
| 180 |
</div>
|
| 181 |
|
| 182 |
+
<div
|
| 183 |
+
className="absolute bottom-8 left-1/2 -translate-x-1/2 flex flex-col items-center gap-1 animate-fade-in opacity-0"
|
| 184 |
+
style={{ animationDelay: "500ms", animationFillMode: "forwards" }}
|
| 185 |
+
>
|
| 186 |
+
<span className="text-[9px] text-white/15 font-medium tracking-wider uppercase">Scroll</span>
|
| 187 |
+
<ChevronDown className="w-3.5 h-3.5 text-white/15 animate-bounce-subtle" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
</div>
|
| 189 |
+
|
| 190 |
+
<div className="absolute bottom-0 left-0 right-0 h-40 bg-gradient-to-t from-[#0B0E13] via-[#0B0E13]/90 to-transparent pointer-events-none" />
|
| 191 |
+
</div>
|
| 192 |
+
|
| 193 |
+
<div id="join-section" className="w-full max-w-6xl mx-auto px-6 py-10">
|
| 194 |
+
{roomsData && roomsData.rooms && roomsData.rooms.length > 0 && (
|
| 195 |
+
<div className="mb-12">
|
| 196 |
+
<div className="flex items-center justify-between mb-4">
|
| 197 |
+
<h2 className="text-lg font-semibold text-white">Trending Now</h2>
|
| 198 |
+
<span className="text-[11px] text-white/20">{roomsData.rooms.length} active</span>
|
|
|
|
|
|
|
|
|
|
| 199 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
+
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3">
|
| 202 |
+
{roomsData.rooms.map((publicRoom, idx) => (
|
| 203 |
+
<button
|
| 204 |
+
key={publicRoom.id}
|
| 205 |
+
onClick={() => handleJoinRoom(publicRoom.id)}
|
| 206 |
+
className={cn(
|
| 207 |
+
"group relative rounded-xl overflow-hidden transition-all duration-150 text-left",
|
| 208 |
+
"bg-[#12151B] border border-white/[0.04]",
|
| 209 |
+
"hover:border-white/[0.08] hover:scale-[1.01]",
|
| 210 |
+
idx === 0 && "col-span-2 row-span-1 md:col-span-2",
|
| 211 |
+
)}
|
| 212 |
+
style={{ animation: `fade-up 150ms ease-out ${200 + idx * 40}ms both` }}
|
| 213 |
+
>
|
| 214 |
+
<div className="relative aspect-video bg-[#0B0E13] overflow-hidden">
|
| 215 |
+
<div className="w-full h-full bg-gradient-to-br from-[#3B82F6]/20 to-[#8B5CF6]/20 flex items-center justify-center">
|
| 216 |
+
<Play className="w-12 h-12 text-white/30" />
|
| 217 |
+
</div>
|
| 218 |
+
<div className="absolute inset-0 shadow-[inset_0_0_40px_rgba(0,0,0,0.3)]" />
|
| 219 |
+
|
| 220 |
+
<div className="absolute inset-0 bg-black/20 opacity-0 group-hover:opacity-100 transition-opacity duration-150 flex items-center justify-center">
|
| 221 |
+
<div className="w-11 h-11 rounded-full bg-white/90 flex items-center justify-center scale-90 opacity-0 group-hover:scale-100 group-hover:opacity-100 transition-all duration-150">
|
| 222 |
+
<Play className="w-4 h-4 fill-[#0B0E13] text-[#0B0E13] ml-0.5" />
|
| 223 |
+
</div>
|
| 224 |
+
</div>
|
| 225 |
+
|
| 226 |
+
<div className="absolute bottom-2 right-2 px-1.5 py-0.5 rounded bg-black/50">
|
| 227 |
+
<span className="text-[9px] text-white/40 font-medium">Live</span>
|
| 228 |
+
</div>
|
| 229 |
+
|
| 230 |
+
{idx === 0 && (
|
| 231 |
+
<div className="absolute top-2 left-2 px-1.5 py-0.5 rounded bg-gradient-to-r from-[#3B82F6] to-[#8B5CF6]">
|
| 232 |
+
<span className="text-[9px] text-white font-medium">Featured</span>
|
| 233 |
+
</div>
|
| 234 |
+
)}
|
| 235 |
</div>
|
| 236 |
+
|
| 237 |
+
<div className="p-3">
|
| 238 |
+
<div className="text-sm font-medium text-white/70 truncate">{publicRoom.ownerName}'s Room</div>
|
| 239 |
+
<div className="flex items-center gap-1 text-[10px] text-white/20 mt-1">
|
| 240 |
+
<Users className="w-3 h-3" />
|
| 241 |
+
<span>{publicRoom.memberCount} watching</span>
|
| 242 |
+
</div>
|
| 243 |
</div>
|
| 244 |
+
</button>
|
| 245 |
+
))}
|
| 246 |
+
|
| 247 |
+
{!mounted || (roomsLoading && (!roomsData || roomsData.rooms.length === 0)) ? (
|
| 248 |
+
<>
|
| 249 |
+
{[1, 2, 3, 4].map((i) => (
|
| 250 |
+
<div
|
| 251 |
+
key={i}
|
| 252 |
+
className={cn(
|
| 253 |
+
"rounded-xl overflow-hidden bg-[#12151B] border border-white/[0.04]",
|
| 254 |
+
i === 1 && "col-span-2",
|
| 255 |
+
)}
|
| 256 |
+
>
|
| 257 |
+
<Skeleton className="aspect-video w-full bg-white/[0.02]" />
|
| 258 |
+
<div className="p-3 space-y-2">
|
| 259 |
+
<Skeleton className="h-4 w-3/4 bg-white/[0.02]" />
|
| 260 |
+
<Skeleton className="h-3 w-1/3 bg-white/[0.02]" />
|
| 261 |
+
</div>
|
| 262 |
+
</div>
|
| 263 |
+
))}
|
| 264 |
+
</>
|
| 265 |
+
) : null}
|
| 266 |
+
</div>
|
| 267 |
+
</div>
|
| 268 |
+
)}
|
| 269 |
+
|
| 270 |
+
<Card className="max-w-md mx-auto bg-[#12151B] border-white/[0.04] rounded-xl">
|
| 271 |
+
<CardContent className="pt-6 pb-6">
|
| 272 |
+
<div className="text-center mb-5">
|
| 273 |
+
<h2 className="text-base font-semibold text-white mb-1">Create Your Room</h2>
|
| 274 |
+
<p className="text-[11px] text-white/25">Start streaming together in seconds</p>
|
| 275 |
+
</div>
|
| 276 |
+
|
| 277 |
+
<form
|
| 278 |
+
onSubmit={(e) => {
|
| 279 |
+
e.preventDefault()
|
| 280 |
+
if (room.length >= 4) {
|
| 281 |
+
handleJoinRoom(room)
|
| 282 |
+
}
|
| 283 |
+
}}
|
| 284 |
+
className="space-y-3.5"
|
| 285 |
+
>
|
| 286 |
+
<div className="space-y-1.5">
|
| 287 |
+
<Label htmlFor="userName" className="text-[11px] font-medium text-white/40">
|
| 288 |
+
Your Name
|
| 289 |
+
</Label>
|
| 290 |
+
<Input
|
| 291 |
+
id="userName"
|
| 292 |
+
value={userName}
|
| 293 |
+
placeholder="Enter your display name"
|
| 294 |
+
onChange={(e) => {
|
| 295 |
+
setUserName(e.target.value)
|
| 296 |
+
setNameError("")
|
| 297 |
}}
|
| 298 |
+
className={cn(
|
| 299 |
+
"bg-white/[0.03] border-white/[0.06] text-white placeholder:text-white/15 h-10 rounded-lg text-sm",
|
| 300 |
+
"focus-visible:ring-[#3B82F6]/15 focus-visible:border-white/[0.1] transition-all duration-150",
|
| 301 |
+
nameError && "border-red-500/40",
|
| 302 |
+
)}
|
| 303 |
+
/>
|
| 304 |
+
{nameError && <p className="text-[10px] text-red-400/80">{nameError}</p>}
|
| 305 |
+
</div>
|
| 306 |
+
|
| 307 |
+
<div className="space-y-1.5">
|
| 308 |
+
<Label htmlFor="roomId" className="text-[11px] font-medium text-white/40">
|
| 309 |
+
Room ID <span className="text-white/15 font-normal">(optional)</span>
|
| 310 |
+
</Label>
|
| 311 |
+
<Input
|
| 312 |
+
id="roomId"
|
| 313 |
+
value={room}
|
| 314 |
+
placeholder="Enter a room ID to join"
|
| 315 |
+
onChange={(e) => setRoom(e.target.value.toLowerCase().replace(/[^a-z]/g, ""))}
|
| 316 |
+
className="bg-white/[0.03] border-white/[0.06] text-white placeholder:text-white/15 h-10 rounded-lg text-sm focus-visible:ring-[#3B82F6]/15 focus-visible:border-white/[0.1] transition-all duration-150"
|
| 317 |
+
/>
|
| 318 |
+
</div>
|
| 319 |
+
|
| 320 |
+
<div className="flex items-center justify-between p-2.5 rounded-lg bg-white/[0.02] border border-white/[0.04]">
|
| 321 |
+
<Label htmlFor="public-toggle" className="cursor-pointer text-[11px] text-white/30">
|
| 322 |
+
Make room public
|
| 323 |
+
</Label>
|
| 324 |
+
<Switch
|
| 325 |
+
id="public-toggle"
|
| 326 |
+
checked={isPublic}
|
| 327 |
+
onCheckedChange={setIsPublic}
|
| 328 |
+
className="scale-[0.85]"
|
| 329 |
+
/>
|
| 330 |
+
</div>
|
| 331 |
+
|
| 332 |
+
<div className="flex gap-2 pt-1">
|
| 333 |
+
<Button
|
| 334 |
+
type="button"
|
| 335 |
+
variant="outline"
|
| 336 |
+
className="flex-1 h-10 bg-transparent border-white/[0.06] text-white/35 hover:bg-white/[0.03] hover:text-white/50 hover:border-white/[0.08] rounded-lg text-sm transition-all duration-150 active:scale-[0.98]"
|
| 337 |
+
onClick={handleGenerateRoom}
|
| 338 |
+
disabled={isGenerating}
|
| 339 |
+
>
|
| 340 |
+
{isGenerating ? "Creating..." : "Generate"}
|
| 341 |
+
</Button>
|
| 342 |
+
<Button
|
| 343 |
+
type="submit"
|
| 344 |
+
disabled={room.length < 4}
|
| 345 |
+
className="flex-1 h-10 bg-gradient-to-r from-[#3B82F6] to-[#8B5CF6] hover:from-[#4B8FF7] hover:to-[#9B6CF7] text-white font-medium rounded-lg text-sm transition-all duration-150 active:scale-[0.98] disabled:opacity-25 disabled:cursor-not-allowed"
|
| 346 |
>
|
| 347 |
+
Join Room
|
| 348 |
+
<ChevronRight className="w-3.5 h-3.5 ml-1" />
|
| 349 |
</Button>
|
| 350 |
</div>
|
| 351 |
+
</form>
|
| 352 |
+
</CardContent>
|
| 353 |
+
</Card>
|
| 354 |
</div>
|
| 355 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 356 |
</Layout>
|
| 357 |
)
|
| 358 |
}
|
public/streaming-room-.jpg
ADDED
|
tsconfig.json
CHANGED
|
@@ -5,6 +5,9 @@
|
|
| 5 |
"jsx": "preserve",
|
| 6 |
"lib": ["dom", "es2017"],
|
| 7 |
"baseUrl": ".",
|
|
|
|
|
|
|
|
|
|
| 8 |
"moduleResolution": "node",
|
| 9 |
"strict": true,
|
| 10 |
"allowJs": true,
|
|
|
|
| 5 |
"jsx": "preserve",
|
| 6 |
"lib": ["dom", "es2017"],
|
| 7 |
"baseUrl": ".",
|
| 8 |
+
"paths": {
|
| 9 |
+
"@/*": ["./*"]
|
| 10 |
+
},
|
| 11 |
"moduleResolution": "node",
|
| 12 |
"strict": true,
|
| 13 |
"allowJs": true,
|
yarn.lock
CHANGED
|
@@ -216,6 +216,101 @@
|
|
| 216 |
tiny-glob "^0.2.9"
|
| 217 |
tslib "^2.4.0"
|
| 218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
"@rushstack/eslint-patch@^1.3.3":
|
| 220 |
version "1.5.1"
|
| 221 |
resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz"
|
|
@@ -353,7 +448,7 @@
|
|
| 353 |
dependencies:
|
| 354 |
"@types/react" "*"
|
| 355 |
|
| 356 |
-
"@types/react-dom@^18.2.18":
|
| 357 |
version "18.2.18"
|
| 358 |
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz"
|
| 359 |
integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==
|
|
@@ -751,6 +846,13 @@ chokidar@^3.5.3:
|
|
| 751 |
optionalDependencies:
|
| 752 |
fsevents "~2.3.2"
|
| 753 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 754 |
classnames@^2.3.0, classnames@^2.5.0:
|
| 755 |
version "2.5.0"
|
| 756 |
resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz"
|
|
@@ -761,6 +863,11 @@ client-only@^0.0.1, client-only@0.0.1:
|
|
| 761 |
resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz"
|
| 762 |
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
| 763 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 764 |
color-convert@^2.0.1:
|
| 765 |
version "2.0.1"
|
| 766 |
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
|
|
@@ -1987,6 +2094,11 @@ lru-cache@^6.0.0:
|
|
| 1987 |
dependencies:
|
| 1988 |
yallist "^4.0.0"
|
| 1989 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1990 |
make-error@^1.1.1:
|
| 1991 |
version "1.3.6"
|
| 1992 |
resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz"
|
|
@@ -2387,7 +2499,7 @@ react-beautiful-dnd@^13.1.1:
|
|
| 2387 |
redux "^4.0.4"
|
| 2388 |
use-memo-one "^1.1.1"
|
| 2389 |
|
| 2390 |
-
"react-dom@^16.8.5 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0, react-dom@>=16.14.0:
|
| 2391 |
version "18.2.0"
|
| 2392 |
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
|
| 2393 |
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
|
@@ -2448,7 +2560,7 @@ react-tooltip@*, react-tooltip@^5.25.1:
|
|
| 2448 |
"@floating-ui/dom" "^1.0.0"
|
| 2449 |
classnames "^2.3.0"
|
| 2450 |
|
| 2451 |
-
"react@^16.11.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.3 || ^17 || ^18", "react@^16.8.5 || ^17.0.0 || ^18.0.0", react@^18.2.0, "react@>= 16.8.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16.14.0, react@>=16.6.0:
|
| 2452 |
version "18.2.0"
|
| 2453 |
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
| 2454 |
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
|
@@ -2834,6 +2946,11 @@ synckit@^0.8.4:
|
|
| 2834 |
"@pkgr/utils" "^2.3.1"
|
| 2835 |
tslib "^2.4.0"
|
| 2836 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2837 |
tailwindcss@^3.4.0:
|
| 2838 |
version "3.4.0"
|
| 2839 |
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz"
|
|
|
|
| 216 |
tiny-glob "^0.2.9"
|
| 217 |
tslib "^2.4.0"
|
| 218 |
|
| 219 |
+
"@radix-ui/primitive@1.1.3":
|
| 220 |
+
version "1.1.3"
|
| 221 |
+
resolved "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz"
|
| 222 |
+
integrity sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==
|
| 223 |
+
|
| 224 |
+
"@radix-ui/react-compose-refs@1.1.2":
|
| 225 |
+
version "1.1.2"
|
| 226 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz"
|
| 227 |
+
integrity sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==
|
| 228 |
+
|
| 229 |
+
"@radix-ui/react-context@1.1.2":
|
| 230 |
+
version "1.1.2"
|
| 231 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz"
|
| 232 |
+
integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==
|
| 233 |
+
|
| 234 |
+
"@radix-ui/react-label@^2.1.8":
|
| 235 |
+
version "2.1.8"
|
| 236 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz"
|
| 237 |
+
integrity sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==
|
| 238 |
+
dependencies:
|
| 239 |
+
"@radix-ui/react-primitive" "2.1.4"
|
| 240 |
+
|
| 241 |
+
"@radix-ui/react-primitive@2.1.3":
|
| 242 |
+
version "2.1.3"
|
| 243 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz"
|
| 244 |
+
integrity sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==
|
| 245 |
+
dependencies:
|
| 246 |
+
"@radix-ui/react-slot" "1.2.3"
|
| 247 |
+
|
| 248 |
+
"@radix-ui/react-primitive@2.1.4":
|
| 249 |
+
version "2.1.4"
|
| 250 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz"
|
| 251 |
+
integrity sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==
|
| 252 |
+
dependencies:
|
| 253 |
+
"@radix-ui/react-slot" "1.2.4"
|
| 254 |
+
|
| 255 |
+
"@radix-ui/react-slot@^1.2.4", "@radix-ui/react-slot@1.2.4":
|
| 256 |
+
version "1.2.4"
|
| 257 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz"
|
| 258 |
+
integrity sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==
|
| 259 |
+
dependencies:
|
| 260 |
+
"@radix-ui/react-compose-refs" "1.1.2"
|
| 261 |
+
|
| 262 |
+
"@radix-ui/react-slot@1.2.3":
|
| 263 |
+
version "1.2.3"
|
| 264 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz"
|
| 265 |
+
integrity sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==
|
| 266 |
+
dependencies:
|
| 267 |
+
"@radix-ui/react-compose-refs" "1.1.2"
|
| 268 |
+
|
| 269 |
+
"@radix-ui/react-switch@^1.2.6":
|
| 270 |
+
version "1.2.6"
|
| 271 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz"
|
| 272 |
+
integrity sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==
|
| 273 |
+
dependencies:
|
| 274 |
+
"@radix-ui/primitive" "1.1.3"
|
| 275 |
+
"@radix-ui/react-compose-refs" "1.1.2"
|
| 276 |
+
"@radix-ui/react-context" "1.1.2"
|
| 277 |
+
"@radix-ui/react-primitive" "2.1.3"
|
| 278 |
+
"@radix-ui/react-use-controllable-state" "1.2.2"
|
| 279 |
+
"@radix-ui/react-use-previous" "1.1.1"
|
| 280 |
+
"@radix-ui/react-use-size" "1.1.1"
|
| 281 |
+
|
| 282 |
+
"@radix-ui/react-use-controllable-state@1.2.2":
|
| 283 |
+
version "1.2.2"
|
| 284 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz"
|
| 285 |
+
integrity sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==
|
| 286 |
+
dependencies:
|
| 287 |
+
"@radix-ui/react-use-effect-event" "0.0.2"
|
| 288 |
+
"@radix-ui/react-use-layout-effect" "1.1.1"
|
| 289 |
+
|
| 290 |
+
"@radix-ui/react-use-effect-event@0.0.2":
|
| 291 |
+
version "0.0.2"
|
| 292 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz"
|
| 293 |
+
integrity sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==
|
| 294 |
+
dependencies:
|
| 295 |
+
"@radix-ui/react-use-layout-effect" "1.1.1"
|
| 296 |
+
|
| 297 |
+
"@radix-ui/react-use-layout-effect@1.1.1":
|
| 298 |
+
version "1.1.1"
|
| 299 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz"
|
| 300 |
+
integrity sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==
|
| 301 |
+
|
| 302 |
+
"@radix-ui/react-use-previous@1.1.1":
|
| 303 |
+
version "1.1.1"
|
| 304 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz"
|
| 305 |
+
integrity sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==
|
| 306 |
+
|
| 307 |
+
"@radix-ui/react-use-size@1.1.1":
|
| 308 |
+
version "1.1.1"
|
| 309 |
+
resolved "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz"
|
| 310 |
+
integrity sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==
|
| 311 |
+
dependencies:
|
| 312 |
+
"@radix-ui/react-use-layout-effect" "1.1.1"
|
| 313 |
+
|
| 314 |
"@rushstack/eslint-patch@^1.3.3":
|
| 315 |
version "1.5.1"
|
| 316 |
resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz"
|
|
|
|
| 448 |
dependencies:
|
| 449 |
"@types/react" "*"
|
| 450 |
|
| 451 |
+
"@types/react-dom@*", "@types/react-dom@^18.2.18":
|
| 452 |
version "18.2.18"
|
| 453 |
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz"
|
| 454 |
integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==
|
|
|
|
| 846 |
optionalDependencies:
|
| 847 |
fsevents "~2.3.2"
|
| 848 |
|
| 849 |
+
class-variance-authority@^0.7.1:
|
| 850 |
+
version "0.7.1"
|
| 851 |
+
resolved "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz"
|
| 852 |
+
integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==
|
| 853 |
+
dependencies:
|
| 854 |
+
clsx "^2.1.1"
|
| 855 |
+
|
| 856 |
classnames@^2.3.0, classnames@^2.5.0:
|
| 857 |
version "2.5.0"
|
| 858 |
resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz"
|
|
|
|
| 863 |
resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz"
|
| 864 |
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
| 865 |
|
| 866 |
+
clsx@^2.1.1:
|
| 867 |
+
version "2.1.1"
|
| 868 |
+
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
|
| 869 |
+
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
|
| 870 |
+
|
| 871 |
color-convert@^2.0.1:
|
| 872 |
version "2.0.1"
|
| 873 |
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
|
|
|
|
| 2094 |
dependencies:
|
| 2095 |
yallist "^4.0.0"
|
| 2096 |
|
| 2097 |
+
lucide-react@^0.561.0:
|
| 2098 |
+
version "0.561.0"
|
| 2099 |
+
resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.561.0.tgz"
|
| 2100 |
+
integrity sha512-Y59gMY38tl4/i0qewcqohPdEbieBy7SovpBL9IFebhc2mDd8x4PZSOsiFRkpPcOq6bj1r/mjH/Rk73gSlIJP2A==
|
| 2101 |
+
|
| 2102 |
make-error@^1.1.1:
|
| 2103 |
version "1.3.6"
|
| 2104 |
resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz"
|
|
|
|
| 2499 |
redux "^4.0.4"
|
| 2500 |
use-memo-one "^1.1.1"
|
| 2501 |
|
| 2502 |
+
"react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom@^16.8.5 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0, react-dom@>=16.14.0:
|
| 2503 |
version "18.2.0"
|
| 2504 |
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
|
| 2505 |
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
|
|
|
| 2560 |
"@floating-ui/dom" "^1.0.0"
|
| 2561 |
classnames "^2.3.0"
|
| 2562 |
|
| 2563 |
+
"react@^16.11.0 || ^17.0.0 || ^18.0.0", "react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.3 || ^17 || ^18", "react@^16.8.5 || ^17.0.0 || ^18.0.0", react@^18.2.0, "react@>= 16.8.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16.14.0, react@>=16.6.0:
|
| 2564 |
version "18.2.0"
|
| 2565 |
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
| 2566 |
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
|
|
|
| 2946 |
"@pkgr/utils" "^2.3.1"
|
| 2947 |
tslib "^2.4.0"
|
| 2948 |
|
| 2949 |
+
tailwind-merge@^3.4.0:
|
| 2950 |
+
version "3.4.0"
|
| 2951 |
+
resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz"
|
| 2952 |
+
integrity sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==
|
| 2953 |
+
|
| 2954 |
tailwindcss@^3.4.0:
|
| 2955 |
version "3.4.0"
|
| 2956 |
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz"
|