+>(({ className, ...props }, ref) => (
(
));
CardDescription.displayName = "CardDescription";
-const CardContent = React.forwardRef(({ className, ...props }, ref) => (
+const CardContent = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
));
CardContent.displayName = "CardContent";
-const CardFooter = React.forwardRef(({ className, ...props }, ref) => (
+const CardFooter = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
}
+ );
+};
+
+type ChartContextProps = {
+ config: ChartConfig;
};
-const ChartContext = React.createContext(null);
+const ChartContext = React.createContext
(null);
function useChart() {
const context = React.useContext(ChartContext);
@@ -22,34 +35,40 @@ function useChart() {
return context;
}
-const ChartContainer = React.forwardRef(
- ({ id, className, children, config, ...props }, ref) => {
- const uniqueId = React.useId();
- const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
+const ChartContainer = React.forwardRef<
+ HTMLDivElement,
+ React.ComponentProps<"div"> & {
+ config: ChartConfig;
+ children: React.ComponentProps<
+ typeof RechartsPrimitive.ResponsiveContainer
+ >["children"];
+ }
+>(({ id, className, children, config, ...props }, ref) => {
+ const uniqueId = React.useId();
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
- return (
-
-
-
-
- {children}
-
-
-
- );
- },
-);
+ return (
+
+
+
+
+ {children}
+
+
+
+ );
+});
ChartContainer.displayName = "Chart";
-const ChartStyle = ({ id, config }) => {
+const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
const colorConfig = Object.entries(config).filter(
([_, config]) => config.theme || config.color,
);
@@ -67,7 +86,9 @@ const ChartStyle = ({ id, config }) => {
${prefix} [data-chart=${id}] {
${colorConfig
.map(([key, itemConfig]) => {
- const color = itemConfig.theme?.[theme] || itemConfig.color;
+ const color =
+ itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
+ itemConfig.color;
return color ? ` --color-${key}: ${color};` : null;
})
.join("\n")}
@@ -82,7 +103,17 @@ ${colorConfig
const ChartTooltip = RechartsPrimitive.Tooltip;
-const ChartTooltipContent = React.forwardRef(
+const ChartTooltipContent = React.forwardRef<
+ HTMLDivElement,
+ React.ComponentProps &
+ React.ComponentProps<"div"> & {
+ hideLabel?: boolean;
+ hideIndicator?: boolean;
+ indicator?: "line" | "dot" | "dashed";
+ nameKey?: string;
+ labelKey?: string;
+ }
+>(
(
{
active,
@@ -113,12 +144,12 @@ const ChartTooltipContent = React.forwardRef(
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const value =
!labelKey && typeof label === "string"
- ? config[label]?.label || label
+ ? config[label as keyof typeof config]?.label || label
: itemConfig?.label;
if (labelFormatter) {
return (
-
+
{labelFormatter(value, payload)}
);
@@ -128,7 +159,9 @@ const ChartTooltipContent = React.forwardRef(
return null;
}
- return
{value}
;
+ return (
+
{value}
+ );
}, [
label,
labelFormatter,
@@ -150,7 +183,7 @@ const ChartTooltipContent = React.forwardRef(
ref={ref}
className={cn(
"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-slate-200 border-slate-200/50 bg-white px-2.5 py-1.5 text-xs shadow-xl dark:border-slate-800 dark:border-slate-800/50 dark:bg-slate-950",
- className,
+ className ?? "",
)}
>
{!nestLabel ? tooltipLabel : null}
@@ -164,8 +197,8 @@ const ChartTooltipContent = React.forwardRef(
svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-slate-500 dark:[&>svg]:text-slate-400",
- indicator === "dot" && "items-center",
+ "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-slate-500 dark:[&>svg]:text-slate-400",
+ indicator === "dot" ? "items-center" : "",
)}
>
{formatter && item?.value !== undefined && item.name ? (
@@ -178,7 +211,7 @@ const ChartTooltipContent = React.forwardRef(
!hideIndicator && (
)
)}
@@ -226,7 +261,14 @@ ChartTooltipContent.displayName = "ChartTooltip";
const ChartLegend = RechartsPrimitive.Legend;
-const ChartLegendContent = React.forwardRef(
+const ChartLegendContent = React.forwardRef<
+ HTMLDivElement,
+ React.ComponentProps<"div"> &
+ Pick
& {
+ hideIcon?: boolean;
+ nameKey?: string;
+ }
+>(
(
{ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
ref,
@@ -243,7 +285,7 @@ const ChartLegendContent = React.forwardRef(
className={cn(
"flex items-center justify-center gap-4",
verticalAlign === "top" ? "pb-3" : "pt-3",
- className,
+ className ?? "",
)}
>
{payload.map((item) => {
@@ -278,7 +320,11 @@ const ChartLegendContent = React.forwardRef(
ChartLegendContent.displayName = "ChartLegend";
// Helper to extract item config from a payload.
-function getPayloadConfigFromPayload(config, payload, key) {
+function getPayloadConfigFromPayload(
+ config: ChartConfig,
+ payload: unknown,
+ key: string,
+) {
if (typeof payload !== "object" || payload === null) {
return undefined;
}
@@ -290,19 +336,26 @@ function getPayloadConfigFromPayload(config, payload, key) {
? payload.payload
: undefined;
- let configLabelKey = key;
+ let configLabelKey: string = key;
- if (key in payload && typeof payload[key] === "string") {
- configLabelKey = payload[key];
+ if (
+ key in payload &&
+ typeof payload[key as keyof typeof payload] === "string"
+ ) {
+ configLabelKey = payload[key as keyof typeof payload] as string;
} else if (
payloadPayload &&
key in payloadPayload &&
- typeof payloadPayload[key] === "string"
+ typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
) {
- configLabelKey = payloadPayload[key];
+ configLabelKey = payloadPayload[
+ key as keyof typeof payloadPayload
+ ] as string;
}
- return configLabelKey in config ? config[configLabelKey] : config[key];
+ return configLabelKey in config
+ ? config[configLabelKey]
+ : config[key as keyof typeof config];
}
export {
diff --git a/src/components/ui/checkbox.jsx b/src/components/ui/checkbox.jsx
deleted file mode 100644
index e2be3c27a..000000000
--- a/src/components/ui/checkbox.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-"use client";
-import * as React from "react";
-import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
-import { Check } from "lucide-react";
-
-import { cn } from "@/utils/tailwind";
-
-const Checkbox = React.forwardRef(({ className, ...props }, ref) => (
-
-
-
-
-
-));
-Checkbox.displayName = CheckboxPrimitive.Root.displayName;
-
-export { Checkbox };
diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx
new file mode 100644
index 000000000..2c029e3c5
--- /dev/null
+++ b/src/components/ui/checkbox.tsx
@@ -0,0 +1,30 @@
+"use client";
+
+import * as React from "react";
+import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
+import { Check } from "lucide-react";
+
+import { cn } from "@/utils/tailwind";
+
+const Checkbox = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+
+));
+Checkbox.displayName = CheckboxPrimitive.Root.displayName;
+
+export { Checkbox };
diff --git a/src/components/ui/input-otp.tsx b/src/components/ui/input-otp.tsx
new file mode 100644
index 000000000..7d98a42b0
--- /dev/null
+++ b/src/components/ui/input-otp.tsx
@@ -0,0 +1,72 @@
+"use client";
+
+import * as React from "react";
+import { OTPInput, OTPInputContext } from "input-otp";
+import { Dot } from "lucide-react";
+
+import { cn } from "@/utils/tailwind";
+
+const InputOTP = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, containerClassName, ...props }, ref) => (
+
+));
+InputOTP.displayName = "InputOTP";
+
+const InputOTPGroup = React.forwardRef<
+ React.ElementRef<"div">,
+ React.ComponentPropsWithoutRef<"div">
+>(({ className, ...props }, ref) => (
+
+));
+InputOTPGroup.displayName = "InputOTPGroup";
+
+const InputOTPSlot = React.forwardRef<
+ React.ElementRef<"div">,
+ React.ComponentPropsWithoutRef<"div"> & { index: number }
+>(({ index, className, ...props }, ref) => {
+ const inputOTPContext = React.useContext(OTPInputContext);
+ const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];
+
+ return (
+
+ {char}
+ {hasFakeCaret && (
+
+ )}
+
+ );
+});
+InputOTPSlot.displayName = "InputOTPSlot";
+
+const InputOTPSeparator = React.forwardRef<
+ React.ElementRef<"div">,
+ React.ComponentPropsWithoutRef<"div">
+>(({ ...props }, ref) => (
+
+
+
+));
+InputOTPSeparator.displayName = "InputOTPSeparator";
+
+export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
diff --git a/src/components/ui/input.jsx b/src/components/ui/input.jsx
deleted file mode 100644
index c93d82d34..000000000
--- a/src/components/ui/input.jsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import * as React from "react";
-
-import { cn } from "@/utils/tailwind";
-
-const Input = React.forwardRef(({ className, type, ...props }, ref) => {
- return (
-
- );
-});
-Input.displayName = "Input";
-
-export { Input };
diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx
new file mode 100644
index 000000000..2f0d9f3b4
--- /dev/null
+++ b/src/components/ui/input.tsx
@@ -0,0 +1,25 @@
+import * as React from "react";
+
+import { cn } from "@/utils/tailwind";
+
+export interface InputProps
+ extends React.InputHTMLAttributes {}
+
+const Input = React.forwardRef(
+ ({ className, type, ...props }, ref) => {
+ return (
+
+ );
+ },
+);
+Input.displayName = "Input";
+
+export { Input };
diff --git a/src/components/ui/label.jsx b/src/components/ui/label.tsx
similarity index 61%
rename from src/components/ui/label.jsx
rename to src/components/ui/label.tsx
index e83a65957..47a250e12 100644
--- a/src/components/ui/label.jsx
+++ b/src/components/ui/label.tsx
@@ -2,7 +2,7 @@
import * as React from "react";
import * as LabelPrimitive from "@radix-ui/react-label";
-import { cva } from "class-variance-authority";
+import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/utils/tailwind";
@@ -10,7 +10,11 @@ const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
);
-const Label = React.forwardRef(({ className, ...props }, ref) => (
+const Label = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef &
+ VariantProps
+>(({ className, ...props }, ref) => (
,
+ React.ComponentPropsWithoutRef
+>(({ className, value, ...props }, ref) => (
+
+
+
+));
+Progress.displayName = ProgressPrimitive.Root.displayName;
+
+export { Progress };
diff --git a/src/components/ui/tabs.jsx b/src/components/ui/tabs.tsx
similarity index 73%
rename from src/components/ui/tabs.jsx
rename to src/components/ui/tabs.tsx
index 28a5a5680..c17cb8c5b 100644
--- a/src/components/ui/tabs.jsx
+++ b/src/components/ui/tabs.tsx
@@ -7,7 +7,10 @@ import { cn } from "@/utils/tailwind";
const Tabs = TabsPrimitive.Root;
-const TabsList = React.forwardRef(({ className, ...props }, ref) => (
+const TabsList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
(
));
TabsList.displayName = TabsPrimitive.List.displayName;
-const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
+const TabsTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
(
));
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
-const TabsContent = React.forwardRef(({ className, ...props }, ref) => (
+const TabsContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
{
- return (
-
-
- {title}
- {required && *}
-
-
-
- );
- },
-);
-Textarea.displayName = "Textarea";
-
-export { Textarea };
diff --git a/src/components/ui/textarea.tsx b/src/components/ui/textarea.tsx
new file mode 100644
index 000000000..ae54d70f5
--- /dev/null
+++ b/src/components/ui/textarea.tsx
@@ -0,0 +1,24 @@
+import * as React from "react";
+
+import { cn } from "@/utils/tailwind";
+
+export interface TextareaProps
+ extends React.TextareaHTMLAttributes {}
+
+const Textarea = React.forwardRef(
+ ({ className, ...props }, ref) => {
+ return (
+
+ );
+ },
+);
+Textarea.displayName = "Textarea";
+
+export { Textarea };
diff --git a/src/components/user/team/Details.jsx b/src/components/user/team/Details.jsx
index 7f48be767..9044aabd4 100644
--- a/src/components/user/team/Details.jsx
+++ b/src/components/user/team/Details.jsx
@@ -40,8 +40,6 @@ const Details = ({ team }) => {
};
const handleSave = async () => {
- console.log(details);
-
if (
!(
details.links.github === "" ||
diff --git a/src/data/Navigation.js b/src/data/Navigation.js
index 44bebb414..028109b10 100644
--- a/src/data/Navigation.js
+++ b/src/data/Navigation.js
@@ -16,6 +16,7 @@ import {
QrCode,
CircleHelp,
Presentation,
+ Timer,
Newspaper,
} from "lucide-react";
@@ -123,6 +124,11 @@ export const TABS = {
link: "/admin/settings",
icon: ,
},
+ {
+ name: "timer",
+ link: "/admin/timer",
+ icon: ,
+ },
],
},
},
diff --git a/src/data/admin/Judges.js b/src/data/admin/Judges.js
index 2e1958e42..b94bb8ef7 100644
--- a/src/data/admin/Judges.js
+++ b/src/data/admin/Judges.js
@@ -60,8 +60,6 @@ export const COLUMNS = [
name,
}));
- console.log(photos);
-
const zip = new JSZip();
const folder = zip.folder();
diff --git a/src/utils/tailwind.ts b/src/utils/tailwind.ts
index f98ee5e48..c3948e569 100644
--- a/src/utils/tailwind.ts
+++ b/src/utils/tailwind.ts
@@ -1,4 +1,4 @@
-import { clsx } from "clsx";
+import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
-export const cn = (...inputs: string[]): string => twMerge(clsx(inputs));
+export const cn = (...inputs: ClassValue[]): string => twMerge(clsx(inputs));
diff --git a/tailwind.config.js b/tailwind.config.js
index 4a4d6ade7..a4273d34e 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -60,10 +60,15 @@ module.exports = {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
+ "caret-blink": {
+ "0%,70%,100%": { opacity: "1" },
+ "20%,50%": { opacity: "0" },
+ },
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
+ "caret-blink": "caret-blink 1.25s ease-out infinite",
},
},
},