Files
game-scoreboard/src/components/ui/button.tsx
T
joshuaandClaude Opus 5.5 b60c9db4f4 Phase 3: admin magic-link auth and event setup screens
- /login sends a Supabase magic link (admin emails only); /auth/confirm
  completes sign-in; proxy.ts guards /admin and every server action
  re-checks with requireAdmin(), since actions are plain POST endpoints.
- /admin lists, creates, duplicates and deletes events.
- /admin/events/[eventId] edits teams (colour, order) and games with
  criteria, presets and notes. All input goes through zod schemas that
  mirror the database constraints so errors read as plain sentences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 13:47:36 +02:00

29 lines
1.0 KiB
TypeScript

import type { ButtonHTMLAttributes } from "react";
const variants = {
primary: "bg-ink text-white hover:bg-ink/90",
secondary: "border border-ink/25 bg-white text-ink hover:bg-ink/5",
danger: "border border-alert/50 bg-white text-alert hover:bg-alert/10",
} as const;
const sizes = {
// min-h-11 = 44px tap target
md: "min-h-11 px-4 text-base",
sm: "min-h-11 min-w-11 px-3 text-sm",
} as const;
export type ButtonVariant = keyof typeof variants;
export function buttonClass(variant: ButtonVariant = "primary", size: keyof typeof sizes = "md") {
return `inline-flex items-center justify-center gap-2 rounded-md font-bold transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${variants[variant]} ${sizes[size]}`;
}
type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
variant?: ButtonVariant;
size?: keyof typeof sizes;
};
export function Button({ variant, size, className = "", type = "button", ...props }: ButtonProps) {
return <button type={type} className={`${buttonClass(variant, size)} ${className}`} {...props} />;
}