Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions client/src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import type * as React from "react";
import { cn } from "@/lib/utils";

const badgeVariants = cva(
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-ring",
{
variants: {
variant: {
default: "border-transparent bg-primary text-primary-foreground",
secondary: "border-transparent bg-secondary text-secondary-foreground",
destructive: "border-transparent bg-destructive text-destructive-foreground",
outline: "text-foreground",
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/90",
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/90",
success: "border-transparent bg-success text-success-foreground hover:bg-success/90",
warning: "border-transparent bg-warning text-warning-foreground hover:bg-warning/90",
outline: "text-foreground hover:bg-accent hover:text-accent-foreground",
},
},
defaultVariants: {
Expand Down
13 changes: 7 additions & 6 deletions client/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";

const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[colors,shadow,transform] duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 active:scale-[0.98] disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
default: "bg-primary text-primary-foreground shadow-md shadow-primary/20 hover:bg-primary/90 hover:shadow-lg hover:shadow-primary/25",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
outline: "border-2 border-input bg-background hover:bg-accent hover:text-accent-foreground",
ghost: "hover:bg-accent hover:text-accent-foreground",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
destructive: "bg-destructive text-destructive-foreground shadow-md shadow-destructive/20 hover:bg-destructive/90",
success: "bg-success text-success-foreground shadow-md shadow-success/20 hover:bg-success/90",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
sm: "h-9 rounded-md px-3 text-xs",
lg: "h-12 rounded-md px-8 text-base",
icon: "h-10 w-10",
},
},
Expand Down
26 changes: 20 additions & 6 deletions client/src/components/ui/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,49 @@ import { cn } from "@/lib/utils";

const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div ref={ref} className={cn("rounded-xl border bg-card text-card-foreground shadow-sm", className)} {...props} />
<div
ref={ref}
className={cn("rounded-xl border bg-card text-card-foreground shadow-sm transition-[border,shadow] duration-150", className)}
{...props}
/>
),
);
Card.displayName = "Card";

const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => <div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />,
({ className, ...props }, ref) => (
<div ref={ref} className={cn("flex flex-col space-y-1.5 p-6 pb-4", className)} {...props} />
),
);
CardHeader.displayName = "CardHeader";

const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
({ className, ...props }, ref) => (
<h3 ref={ref} className={cn("text-2xl font-semibold leading-none tracking-tight", className)} {...props} />
<h3
ref={ref}
className={cn("text-xl font-semibold leading-snug tracking-tight", className)}
{...props}
/>
),
);
CardTitle.displayName = "CardTitle";

const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
({ className, ...props }, ref) => <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />,
({ className, ...props }, ref) => (
<p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
),
);
CardDescription.displayName = "CardDescription";

const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />,
({ className, ...props }, ref) => <div ref={ref} className={cn("p-6", className)} {...props} />,
);
CardContent.displayName = "CardContent";

const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => <div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />,
({ className, ...props }, ref) => (
<div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />
),
);
CardFooter.displayName = "CardFooter";

Expand Down
37 changes: 37 additions & 0 deletions client/src/components/ui/theme-toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use client";

import { Moon, Sun } from "lucide-react";
import { Button } from "./button";
import { useEffect, useState } from "react";

export function ThemeToggle() {
const [theme, setTheme] = useState<"light" | "dark">("light");

useEffect(() => {
const isDark = document.documentElement.classList.contains("dark");
setTheme(isDark ? "dark" : "light");

const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const handleChange = (e: MediaQueryListEvent) => {
if (!localStorage.getItem("theme")) {
document.documentElement.classList.toggle("dark", e.matches);
setTheme(e.matches ? "dark" : "light");
}
};
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}, []);

const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
document.documentElement.classList.toggle("dark");
setTheme(newTheme);
localStorage.setItem("theme", newTheme);
};

return (
<Button variant="ghost" size="icon" onClick={toggleTheme}>
{theme === "light" ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />}
</Button>
);
}
48 changes: 39 additions & 9 deletions client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,52 @@
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--primary: 221 83% 53%;
--primary-foreground: 0 0% 100%;
--secondary: 220 14% 96%;
--secondary-foreground: 222 47% 11%;
--muted: 220 9% 98%;
--muted-foreground: 220 9% 46%;
--accent: 221 83% 96%;
--accent-foreground: 221 83% 53%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--success: 142 76% 36%;
--success-foreground: 0 0% 100%;
--warning: 38 92% 50%;
--warning-foreground: 0 0% 100%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--ring: 221 83% 53%;
--radius: 0.75rem;
}

.dark {
--background: 222.2 84% 6%;
--foreground: 210 40% 98%;
--card: 222.2 40% 10%;
--card-foreground: 210 40% 98%;
--popover: 222.2 40% 10%;
--popover-foreground: 210 40% 98%;
--primary: 210 100% 60%;
--primary-foreground: 222.2 84% 6%;
--secondary: 222.2 30% 18%;
--secondary-foreground: 210 40% 98%;
--muted: 222.2 30% 15%;
--muted-foreground: 215 20% 55%;
--accent: 222.2 30% 18%;
--accent-foreground: 210 40% 98%;
--destructive: 0 72% 55%;
--destructive-foreground: 210 40% 98%;
--success: 142 70% 45%;
--success-foreground: 0 0% 100%;
--warning: 38 92% 50%;
--warning-foreground: 0 0% 100%;
--border: 222.2 30% 22%;
--input: 222.2 30% 22%;
--ring: 210 100% 60%;
}

* {
@apply border-border;
}
Expand Down
22 changes: 22 additions & 0 deletions client/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ const config: Config = {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
success: {
DEFAULT: "hsl(var(--success))",
foreground: "hsl(var(--success-foreground))",
},
warning: {
DEFAULT: "hsl(var(--warning))",
foreground: "hsl(var(--warning-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
Expand All @@ -45,6 +53,20 @@ const config: Config = {
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
spacing: {
"card-padding": "var(--space-6)",
"section-gap": "var(--space-8)",
},
transitionDuration: {
150: "150ms",
200: "200ms",
300: "300ms",
},
transitionTimingFunction: {
hover: "cubic-bezier(0.4, 0, 0.2, 1)",
"ease-out": "cubic-bezier(0, 0, 0.2, 1)",
"ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
},
},
},
plugins: [],
Expand Down
Loading