Show participated polls on polls page + UI refresh (#1089)

This commit is contained in:
Luke Vella 2024-05-12 13:20:00 +08:00 committed by GitHub
parent bd9e9fe95b
commit f8a217ae75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
125 changed files with 3007 additions and 2363 deletions

View file

@ -32,7 +32,9 @@ const Alert = React.forwardRef<
className={cn(alertVariants({ variant }), className)}
{...props}
>
{Icon ? <Icon className="text-muted-foreground -mt-1 mb-2 size-6" /> : null}
{Icon ? (
<Icon className="text-muted-foreground -mt-0.5 mb-2 size-5" />
) : null}
<div>{children}</div>
</div>
));
@ -60,7 +62,10 @@ const AlertDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-sm [&_p]:leading-relaxed", className)}
className={cn(
"text-muted-foreground text-sm [&_p]:leading-relaxed",
className,
)}
{...props}
/>
));

View file

@ -4,18 +4,24 @@ import * as React from "react";
import { cn } from "./lib/utils";
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
"inline-flex group items-center rounded-full border justify-center text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default: "border-transparent bg-primary text-primary-50",
secondary: "border-transparent bg-secondary text-secondary-foreground",
primary: "border-transparent bg-primary text-primary-50",
default: "bg-gray-50 text-secondary-foreground",
destructive:
"border-transparent bg-destructive text-destructive-foreground",
outline: "text-foreground",
green: "border-transparent bg-green-500 text-green-50",
},
size: {
md: "h-5 min-w-5 text-xs px-1.5",
lg: "h-7 min-w-7 px-2.5",
},
},
defaultVariants: {
size: "md",
variant: "default",
},
},
@ -25,9 +31,12 @@ export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
function Badge({ className, variant, size, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
<div
className={cn(badgeVariants({ variant, size }), className)}
{...props}
/>
);
}

View file

@ -9,7 +9,7 @@ export const BillingPlan = ({
return (
<div
className={cn(
"space-y-4 rounded-md border bg-gradient-to-b from-white to-white/75 px-5 py-4 backdrop-blur-sm",
"space-y-4 rounded-md border bg-white px-5 py-4 shadow-sm backdrop-blur-sm",
className,
)}
>
@ -75,7 +75,7 @@ export const BillingPlanPerk = ({
!pro ? "text-gray-500" : "text-primary",
)}
/>
<div className="text-sm">{children}</div>
<div className="text-muted-foreground text-sm">{children}</div>
</li>
);
};

View file

@ -1,34 +1,35 @@
"use client";
import { Slot } from "@radix-ui/react-slot";
import { Loader2Icon } from "lucide-react";
import { cva, VariantProps } from "class-variance-authority";
import * as React from "react";
import { Loader2Icon } from "lucide-react";
import { cn } from "./lib/utils";
const buttonVariants = cva(
cn(
"inline-flex border font-medium disabled:pointer-events-none select-none disabled:opacity-50 items-center justify-center whitespace-nowrap rounded-md border",
"focus:ring-offset-input-background focus:border-primary-400 focus:ring-2 focus:ring-indigo-100",
"focus-visible:ring-offset-input-background focus-visible:ring-offset-1 focus-visible:ring-2 focus-visible:ring-gray-200",
"active:shadow-none",
),
{
variants: {
variant: {
primary:
"border-primary-700 bg-primary disabled:bg-gray-400 disabled:border-transparent text-primary-foreground shadow-sm hover:bg-primary-500 active:bg-primary-700",
"border-primary-700 shadow-sm bg-primary disabled:bg-gray-400 disabled:border-transparent text-primary-foreground shadow-sm hover:bg-primary-500 active:bg-primary-700",
destructive:
"bg-destructive text-destructive-foreground focus:ring-offset-1 active:bg-destructive border-destructive hover:bg-destructive/90",
"bg-destructive shadow-sm text-destructive-foreground focus-visible:ring-offset-1 active:bg-destructive border-destructive hover:bg-destructive/90",
default:
"rounded-md px-3.5 py-2.5 data-[state=open]:shadow-none data-[state=open]:bg-gray-100 active:bg-gray-200 hover:bg-gray-100 bg-gray-50",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "border-transparent hover:bg-gray-200 active:bg-gray-300",
link: "underline-offset-4 hover:underline text-primary",
ghost:
"border-transparent bg-transparent hover:bg-gray-200 active:bg-gray-300",
link: "underline-offset-4 border-transparent hover:text-primary-700 text-primary",
},
size: {
default: "h-9 px-2.5 gap-x-2.5 text-sm",
sm: "h-7 text-xs px-1.5 gap-x-1.5 rounded-md",
lg: "h-11 text-base gap-x-3 px-4 rounded-md",
sm: "h-7 text-sm px-1.5 gap-x-1.5 rounded-md",
lg: "h-11 text-sm gap-x-3 px-4 rounded-md",
},
},
defaultVariants: {
@ -42,7 +43,6 @@ export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
icon?: React.ComponentType<{ className?: string }>;
loading?: boolean;
}
@ -50,7 +50,6 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{
className,
icon: Icon,
loading,
children,
variant,
@ -76,17 +75,10 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
type={type}
{...props}
>
{asChild ? (
children
{loading ? (
<Loader2Icon className="size-4 animate-spin opacity-75" />
) : (
<>
{loading ? (
<Loader2Icon className="size-4 animate-spin" />
) : Icon ? (
<Icon className={cn("-ml-0.5 size-4")} />
) : null}
{children}
</>
children
)}
</Comp>
);

View file

@ -23,7 +23,10 @@ const CardHeader = React.forwardRef<
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("grid rounded-t-md border-b p-2 py-3 sm:px-5", className)}
className={cn(
"grid rounded-t-md border-b bg-gray-50 p-3 sm:px-4 sm:py-3",
className,
)}
{...props}
/>
));
@ -35,7 +38,10 @@ const CardTitle = React.forwardRef<
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn("font-semibold tracking-tight sm:leading-tight", className)}
className={cn(
"flex items-center gap-x-2.5 text-sm font-semibold sm:text-base",
className,
)}
{...props}
/>
));
@ -68,7 +74,7 @@ const CardFooter = React.forwardRef<
<div
ref={ref}
className={cn(
"flex items-center gap-x-2 rounded-b-md border-t bg-gray-50 p-3 sm:px-4",
"flex items-center gap-x-2 rounded-b-md border-t bg-gray-50 p-3 sm:px-4 sm:py-3",
className,
)}
{...props}

View file

@ -7,6 +7,7 @@ import * as React from "react";
import { Dialog, DialogContent } from "./dialog";
import { cn } from "./lib/utils";
import { Icon } from "@rallly/ui/icon";
const Command = React.forwardRef<
React.ElementRef<typeof CommandPrimitive>,
@ -41,8 +42,13 @@ const CommandInput = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Input>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
>(({ className, ...props }, ref) => (
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
<SearchIcon className="mr-2 size-4 shrink-0 opacity-50" />
<div
className="flex items-center gap-x-2.5 border-b px-3"
cmdk-input-wrapper=""
>
<Icon>
<SearchIcon className="shrink-0" />
</Icon>
<CommandPrimitive.Input
ref={ref}
className={cn(
@ -75,7 +81,7 @@ const CommandEmpty = React.forwardRef<
>((props, ref) => (
<CommandPrimitive.Empty
ref={ref}
className="py-6 text-center text-sm"
className="text-muted-foreground py-6 text-center text-sm"
{...props}
/>
));
@ -117,7 +123,7 @@ const CommandItem = React.forwardRef<
<CommandPrimitive.Item
ref={ref}
className={cn(
"relative flex h-10 cursor-default select-none items-center rounded-md px-2 text-sm outline-none aria-selected:bg-gray-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex h-9 cursor-default select-none items-center rounded-md px-2 text-sm outline-none aria-selected:bg-gray-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
)}
{...props}

View file

@ -5,6 +5,7 @@ import { XIcon } from "lucide-react";
import * as React from "react";
import { cn } from "./lib/utils";
export type { DialogProps } from "@radix-ui/react-dialog";
const Dialog = DialogPrimitive.Root;
@ -17,7 +18,7 @@ const DialogPortal = ({
...props
}: DialogPrimitive.DialogPortalProps) => (
<DialogPrimitive.Portal className={cn(className)} {...props}>
<div className="fixed inset-0 z-50 flex items-start justify-center sm:items-center">
<div className="fixed inset-0 z-50 flex items-end justify-center pb-4 sm:items-center">
{children}
</div>
</DialogPrimitive.Portal>
@ -43,7 +44,7 @@ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
size?: "sm" | "md" | "lg";
size?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl";
hideCloseButton?: boolean;
}
>(({ className, children, size = "md", hideCloseButton, ...props }, ref) => (
@ -52,11 +53,16 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"animate-in data-[state=open]:fade-in shadow-huge fixed z-50 mx-4 grid translate-y-4 gap-4 overflow-hidden rounded-md bg-white p-5",
"animate-in data-[state=open]:fade-in shadow-huge z-50 grid w-full translate-y-4 gap-4 overflow-hidden bg-gray-50 p-5 sm:rounded-md",
{
"sm:max-w-sm": size === "sm",
"sm:max-w-md": size === "md",
"sm:max-w-lg": size === "lg",
"sm:max-w-xl": size === "xl",
"sm:max-w-2xl": size === "2xl",
"sm:max-w-3xl": size === "3xl",
"sm:max-w-4xl": size === "4xl",
"sm:max-w-5xl": size === "5xl",
},
className,
)}
@ -90,7 +96,7 @@ const DialogFooter = ({
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"bg-muted-background -mx-5 -mb-5 flex flex-col-reverse gap-2 px-5 py-2.5 sm:flex-row sm:justify-end sm:rounded-b-md",
"bg-muted-background -mx-5 -mb-5 flex flex-col-reverse gap-2 border-t px-3 py-2.5 sm:flex-row sm:justify-end sm:rounded-b-md",
className,
)}
{...props}
@ -116,15 +122,42 @@ const DialogDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn(
"text-muted-foreground mt-2 text-sm leading-relaxed tracking-wide",
className,
)}
className={cn("text-muted-foreground mt-2.5 text-sm", className)}
{...props}
/>
));
DialogDescription.displayName = DialogPrimitive.Description.displayName;
function useDialog() {
const [isOpen, setIsOpen] = React.useState(false);
const triggerRef = React.useRef<HTMLButtonElement>();
function trigger() {
setIsOpen(true);
}
function dismiss() {
setIsOpen(false);
triggerRef.current?.focus();
}
return {
triggerProps: {
ref: triggerRef,
onClick: trigger,
},
dialogProps: {
open: isOpen,
onOpenChange: (open: boolean) => {
if (open) trigger();
else dismiss();
},
},
trigger,
dismiss,
};
}
export {
Dialog,
DialogClose,
@ -134,4 +167,5 @@ export {
DialogHeader,
DialogTitle,
DialogTrigger,
useDialog,
};

View file

@ -211,8 +211,8 @@ export const DropdownMenuItemIconLabel = ({
children: React.ReactNode;
}) => {
return (
<span className="flex items-center gap-2">
<Icon className="size-4" />
<span className="flex items-center gap-2.5">
<Icon className="text-muted-foreground size-4" />
{children}
</span>
);

View file

@ -39,13 +39,13 @@ const flexVariants = cva("box-border flex justify-start", {
},
gap: {
none: "gap-0",
sm: "gap-2.5",
md: "gap-4",
md: "gap-2.5",
lg: "gap-4",
},
},
defaultVariants: {
direction: "row",
align: "start",
align: "center",
justify: "start",
wrap: "noWrap",
gap: "md",

View file

@ -156,7 +156,7 @@ const FormMessage = React.forwardRef<
<p
ref={ref}
id={formMessageId}
className={cn("text-destructive text-sm font-medium", className)}
className={cn("text-destructive text-sm", className)}
{...props}
>
{body}

View file

@ -9,11 +9,13 @@ const iconVariants = cva("", {
default: "text-gray-500",
success: "text-green-500",
danger: "text-rose-500",
primary: "text-primary-200",
primary: "text-primary-600",
},
size: {
sm: "w-3 h-3",
md: "w-4 h-4",
lg: "w-5 h-5",
xl: "w-7 h-7",
},
},
defaultVariants: {
@ -31,7 +33,7 @@ export function Icon({ children, size, variant }: IconProps) {
<Slot
className={cn(
iconVariants({ size, variant }),
"group-[.bg-primary]:text-primary-200 group",
"group-[.bg-primary]:text-primary-100 group shrink-0",
)}
>
{children}

View file

@ -7,7 +7,7 @@ import * as React from "react";
import { cn } from "./lib/utils";
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
"text-sm text-muted-foreground leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
);
const Label = React.forwardRef<

View file

@ -1,4 +1,4 @@
import { type ClassValue, clsx } from "clsx";
import clsx, { ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {

View file

@ -5,28 +5,32 @@ import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
import * as React from "react";
import { cn } from "./lib/utils";
import { buttonVariants } from "./button";
import { Icon } from "./icon";
const Select = SelectPrimitive.Root;
const SelectGroup = SelectPrimitive.Group;
const SelectValue = SelectPrimitive.Value;
const SelectValue = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Value>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>
>(({ ...props }, ref) => {
return (
<div className="flex w-full items-center justify-between gap-x-2.5">
<SelectPrimitive.Value {...props} ref={ref} />
<SelectPrimitive.Icon asChild>
<ChevronsUpDownIcon className="size-4 opacity-50" />
</SelectPrimitive.Icon>
</div>
);
});
const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(buttonVariants(), className)}
{...props}
>
<SelectPrimitive.Trigger ref={ref} className={cn(className)} {...props}>
{children}
<SelectPrimitive.Icon asChild>
<ChevronsUpDownIcon className="ml-2 size-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
@ -39,7 +43,7 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content
ref={ref}
className={cn(
"animate-in relative z-50 max-h-[300px] min-w-[8rem] overflow-hidden rounded border bg-white shadow-md",
"animate-in relative z-50 max-h-[300px] min-w-[8rem] overflow-hidden rounded-lg border bg-white shadow-md",
position === "popper" && "translate-y-1",
className,
)}
@ -66,7 +70,10 @@ const SelectLabel = React.forwardRef<
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("py-1.5 pl-8 pr-2 font-semibold", className)}
className={cn(
"text-muted-foreground px-2 py-1.5 text-xs font-semibold",
className,
)}
{...props}
/>
));
@ -79,7 +86,7 @@ const SelectItem = React.forwardRef<
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-2 pl-8 pr-2 text-sm outline-none focus:bg-gray-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex w-full cursor-default select-none items-center rounded-md py-2 pl-8 pr-2 text-sm outline-none focus-visible:bg-gray-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
)}
{...props}

View file

@ -11,6 +11,8 @@ const Tooltip = TooltipPrimitive.Root;
const TooltipTrigger = TooltipPrimitive.Trigger;
const TooltipPortal = TooltipPrimitive.Portal;
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
@ -20,7 +22,7 @@ const TooltipContent = React.forwardRef<
sideOffset={sideOffset}
side={side}
className={cn(
"z-50 overflow-hidden rounded-md bg-gray-800 px-2 py-1.5 text-sm text-gray-50 shadow-md",
"z-50 overflow-hidden rounded-md bg-gray-800 px-2 py-1.5 text-sm text-gray-50 shadow-sm",
className,
)}
{...props}
@ -30,4 +32,10 @@ const TooltipContent = React.forwardRef<
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
export {
Tooltip,
TooltipContent,
TooltipPortal,
TooltipProvider,
TooltipTrigger,
};