This commit is contained in:
Luke Vella 2024-10-04 17:43:33 +01:00
parent 9928260436
commit 4c61e70506
No known key found for this signature in database
GPG key ID: 469CAD687F0D784C
21 changed files with 241 additions and 109 deletions

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg xmlns="http://www.w3.org/2000/svg"
aria-label="Zoom" role="img"
viewBox="0 0 512 512"><rect
width="512" height="512"
rx="15%"
fill="#2D8CFF"/><path fill="#ffffff" d="M428 357c8 2 15-2 19-8 2-3 2-8 2-19V179c0-11 0-15-2-19-3-8-11-11-19-8-21 14-67 55-68 72-.8 3-.8 8-.8 15v38c0 8 0 11 .8 15 1 8 4 15 8 19 12 9 52 45 61 45zM64 187c0-15 0-23 3-27 2-4 8-8 11-11 4-3 11-3 27-3h129c38 0 57 0 72 8 11 8 23 15 30 30 8 15 8 34 8 72v68c0 15 0 23-3 27-2 4-8 8-11 11-4 3-11 3-27 3H174c-38 0-57 0-72-8-11-8-23-15-30-30-8-15-8-34-8-72z"/></svg>

After

Width:  |  Height:  |  Size: 652 B

View file

@ -0,0 +1,48 @@
import { cn } from "@rallly/ui";
import { cva, VariantProps } from "class-variance-authority";
import { PlusIcon } from "lucide-react";
import Link from "next/link";
const variants = cva(
"inline-flex items-start w-48 justify-between gap-2 rounded-lg p-3 text-sm font-medium",
{
variants: {
variant: {
purple:
"bg-purple-50 text-purple-600 hover:bg-purple-100 active:bg-purple-200",
indigo:
"bg-indigo-50 text-indigo-600 hover:bg-indigo-100 active:bg-indigo-200",
pink: "bg-pink-50 text-pink-600 hover:bg-pink-100 active:bg-pink-200",
violet:
"bg-violet-50 text-violet-600 hover:bg-violet-100 active:bg-violet-200",
},
},
defaultVariants: {
variant: "indigo",
},
},
);
export function CreateButton({
href,
icon,
label,
variant,
}: {
href: string;
icon: React.ReactNode;
label: React.ReactNode;
variant?: VariantProps<typeof variants>["variant"];
}) {
return (
<Link href={href} className={cn(variants({ variant }))}>
<span className="flex flex-col gap-4">
{icon}
{label}
</span>
<span>
<PlusIcon className="size-5" />
</span>
</Link>
);
}

View file

@ -1,9 +1,18 @@
"use client"; "use client";
import { Button } from "@rallly/ui/button"; import { Button } from "@rallly/ui/button";
import { CalendarIcon } from "lucide-react"; import { Icon } from "@rallly/ui/icon";
import {
BarChart2Icon,
BookIcon,
CalendarIcon,
PlusIcon,
TableIcon,
UserIcon,
} from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { CreateButton } from "@/app/[locale]/(admin)/create-button";
import { GridCard, GridCardHeader } from "@/components/grid-card"; import { GridCard, GridCardHeader } from "@/components/grid-card";
import { GroupPollCard } from "@/components/group-poll-card"; import { GroupPollCard } from "@/components/group-poll-card";
import { Subheading } from "@/components/heading"; import { Subheading } from "@/components/heading";
@ -19,6 +28,37 @@ const SectionHeading = ({ children }: React.PropsWithChildren) => {
export default function Dashboard() { export default function Dashboard() {
return ( return (
<div className="space-y-6"> <div className="space-y-6">
<div className="space-y-4">
<Subheading>
<Trans i18nKey="create" defaults="Create" />
</Subheading>
<div className="scrollbar-none -mx-6 flex gap-2 overflow-x-auto whitespace-nowrap px-6">
<CreateButton
variant="purple"
href="/new"
icon={<BarChart2Icon className="size-5" />}
label={<Trans i18nKey="groupPoll" defaults="Group Poll" />}
/>
<CreateButton
variant="violet"
href="/new"
icon={<UserIcon className="size-5" />}
label={<Trans i18nKey="oneOnOne" defaults="One-on-One" />}
/>
<CreateButton
variant="indigo"
href="/new"
icon={<BookIcon className="size-5" />}
label={<Trans i18nKey="bookingPage" defaults="Booking Page" />}
/>
<CreateButton
variant="pink"
href="/new"
icon={<TableIcon className="size-5" />}
label={<Trans i18nKey="signUpSheet" defaults="Sign Up Sheet" />}
/>
</div>
</div>
<div className="space-y-4"> <div className="space-y-4">
<SectionHeading> <SectionHeading>
<Subheading> <Subheading>
@ -54,12 +94,8 @@ function PendingPolls() {
suspense: true, suspense: true,
}); });
if (!data) {
return <Spinner />;
}
return ( return (
<div className="grid gap-4 md:grid-cols-2"> <div className="grid gap-2 md:grid-cols-3">
{data.map((poll) => { {data.map((poll) => {
return ( return (
<GroupPollCard <GroupPollCard
@ -90,20 +126,23 @@ function UpcomingEvents() {
return <Spinner />; return <Spinner />;
} }
if (data.length === 0) {
return ( return (
<div className="grid gap-4 md:grid-cols-2">
{data.length === 0 ? (
<div className="text-muted-foreground"> <div className="text-muted-foreground">
<Trans i18nKey="noUpcomingEvents" defaults="No upcoming events" /> <Trans i18nKey="noUpcomingEvents" defaults="No upcoming events" />
</div> </div>
) : null} );
}
return (
<div className="grid gap-4 md:grid-cols-3">
{data.map((event) => { {data.map((event) => {
return ( return (
<GridCard key={event.id}> <GridCard key={event.id}>
<GridCardHeader className="flex gap-2"> <GridCardHeader className="flex gap-2">
<div> <div>
<div className="bg-primary-600 text-primary-100 inline-flex items-center justify-center rounded-md p-1.5"> <div className="bg-primary-600 text-primary-100 inline-flex items-center justify-center rounded-md p-1.5">
<CalendarIcon className="size-4" /> <CalendarIcon className="size-5" />
</div> </div>
</div> </div>
<div className="min-w-0"> <div className="min-w-0">

View file

@ -30,15 +30,18 @@ export default async function Layout({
<Sidebar /> <Sidebar />
</div> </div>
<div className={cn("pb-16 lg:min-w-0 lg:pb-0 lg:pl-72")}> <div className={cn("pb-16 lg:min-w-0 lg:pb-0 lg:pl-72")}>
<div className="mx-auto max-w-7xl p-6 xl:pr-12"> <div className="mx-auto max-w-7xl p-3 sm:p-6 xl:pr-12">
<div className="mb-6 flex justify-end gap-2"> <div className="mb-6 flex justify-end gap-2">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<Button variant="primary" asChild> <Button
className="hidden sm:inline-flex"
variant="primary"
asChild
>
<Link href="/new"> <Link href="/new">
<Icon> <Icon>
<PlusIcon /> <PlusIcon />
</Icon> </Icon>
Create
</Link> </Link>
</Button> </Button>
<UserDropdown /> <UserDropdown />

View file

@ -1,13 +1,12 @@
import { HomeIcon } from "lucide-react";
import { Trans } from "react-i18next/TransWithoutContext"; import { Trans } from "react-i18next/TransWithoutContext";
import Dashboard from "@/app/[locale]/(admin)/dashboard"; import Dashboard from "@/app/[locale]/(admin)/dashboard";
import WelcomeMessage from "@/app/[locale]/(admin)/welcome-message";
import { Params } from "@/app/[locale]/types"; import { Params } from "@/app/[locale]/types";
import { import {
PageContainer, PageContainer,
PageContent, PageContent,
PageHeader, PageHeader,
PageIcon,
PageTitle, PageTitle,
} from "@/app/components/page-layout"; } from "@/app/components/page-layout";
import { getTranslation } from "@/app/i18n"; import { getTranslation } from "@/app/i18n";
@ -17,13 +16,13 @@ export default async function Page({ params }: { params: Params }) {
return ( return (
<div> <div>
<PageContainer> <PageContainer>
<PageHeader> <PageHeader className="space-y-2">
<PageIcon>
<HomeIcon />
</PageIcon>
<PageTitle> <PageTitle>
<Trans t={t} i18nKey="home" defaults="Home" /> <Trans t={t} i18nKey="home" defaults="Home" />
</PageTitle> </PageTitle>
<p className="text-muted-foreground">
<WelcomeMessage />
</p>
</PageHeader> </PageHeader>
<PageContent> <PageContent>
<Dashboard /> <Dashboard />

View file

@ -59,7 +59,7 @@ function FilteredPolls({ status }: { status: PollStatus }) {
<ol className="space-y-4"> <ol className="space-y-4">
{data.pages.map((page, i) => ( {data.pages.map((page, i) => (
<li key={i}> <li key={i}>
<div className="grid gap-4 md:grid-cols-2"> <div className="grid gap-2 sm:gap-4 md:grid-cols-3">
{page.polls.map((poll) => ( {page.polls.map((poll) => (
<GroupPollCard <GroupPollCard
key={poll.id} key={poll.id}
@ -141,7 +141,7 @@ export function UserPolls() {
const parsedPollStatus = pollStatusSchema.parse(pollStatus); const parsedPollStatus = pollStatusSchema.parse(pollStatus);
return ( return (
<div className="space-y-4"> <div className="space-y-6">
<PollStatusMenu <PollStatusMenu
status={parsedPollStatus} status={parsedPollStatus}
onStatusChange={setPollStatus} onStatusChange={setPollStatus}

View file

@ -22,10 +22,8 @@ export default async function ProfileLayout({
<PageHeader> <PageHeader>
<PageTitle>{t("settings")}</PageTitle> <PageTitle>{t("settings")}</PageTitle>
</PageHeader> </PageHeader>
<PageContent className="space-y-3 sm:space-y-6"> <PageContent className="space-y-6">
<div className="scrollbar-none -mx-3 overflow-auto px-3 sm:mx-0 sm:px-0">
<SettingsMenu /> <SettingsMenu />
</div>
<div>{children}</div> <div>{children}</div>
</PageContent> </PageContent>
</PageContainer> </PageContainer>

View file

@ -1,6 +1,5 @@
"use client"; "use client";
import { Icon } from "@rallly/ui/icon";
import { CreditCardIcon, Settings2Icon, UserIcon } from "lucide-react"; import { CreditCardIcon, Settings2Icon, UserIcon } from "lucide-react";
import { Trans } from "react-i18next"; import { Trans } from "react-i18next";
@ -11,22 +10,16 @@ export function SettingsMenu() {
return ( return (
<TabMenu> <TabMenu>
<TabMenuItem href="/settings/profile"> <TabMenuItem href="/settings/profile">
<Icon> <UserIcon className="size-4" />
<UserIcon />
</Icon>
<Trans i18nKey="profile" /> <Trans i18nKey="profile" />
</TabMenuItem> </TabMenuItem>
<TabMenuItem href="/settings/preferences"> <TabMenuItem href="/settings/preferences">
<Icon> <Settings2Icon className="size-4" />
<Settings2Icon />
</Icon>
<Trans i18nKey="preferences" /> <Trans i18nKey="preferences" />
</TabMenuItem> </TabMenuItem>
<IfCloudHosted> <IfCloudHosted>
<TabMenuItem href="/settings/billing"> <TabMenuItem href="/settings/billing">
<Icon> <CreditCardIcon className="size-4" />
<CreditCardIcon />
</Icon>
<Trans i18nKey="billing" /> <Trans i18nKey="billing" />
</TabMenuItem> </TabMenuItem>
</IfCloudHosted> </IfCloudHosted>

View file

@ -46,8 +46,8 @@ function NavItem({
target={target} target={target}
className={cn( className={cn(
current current
? "text-foreground bg-gray-200" ? "text-foreground bg-gray-100"
: "text-muted-foreground border-transparent hover:bg-gray-200 focus:bg-gray-300", : "text-muted-foreground hover:text-foreground border-transparent hover:bg-gray-100 focus:bg-gray-200",
"group flex items-center gap-x-3 rounded-md px-3 py-2 text-sm font-semibold leading-6", "group flex items-center gap-x-3 rounded-md px-3 py-2 text-sm font-semibold leading-6",
)} )}
> >
@ -102,15 +102,15 @@ export function Sidebar() {
} }
asChild asChild
> >
<button className="mb-4 flex w-full flex-col rounded-md border bg-gray-50 px-4 py-3 focus:border-gray-300 focus:bg-gray-200"> <button className="bg-primary-50 text-primary hover:bg-primary-100 focus:bg-primary-200 mb-4 flex w-full flex-col rounded-lg px-4 py-3">
<span className="mb-2 flex items-center gap-x-2"> <span className="mb-2 flex items-center gap-x-2">
<SparklesIcon className="size-5 text-gray-400" /> <SparklesIcon className="size-5 opacity-50" />
<span className="text-sm font-bold"> <span className="text-sm font-bold">
<Trans i18nKey="upgrade" /> <Trans i18nKey="upgrade" />
</span> </span>
<ProBadge /> <ProBadge />
</span> </span>
<span className="text-sm leading-relaxed text-gray-500"> <span className="text-sm leading-relaxed opacity-75">
<Trans <Trans
i18nKey="unlockFeatures" i18nKey="unlockFeatures"
defaults="Unlock all Pro features." defaults="Unlock all Pro features."

View file

@ -0,0 +1,47 @@
"use client";
import { Trans } from "@/components/trans";
import { useUser } from "@/components/user-provider";
function getTimeOfDay(): "morning" | "afternoon" | "evening" {
const hours = new Date().getHours();
if (hours < 12) {
return "morning";
} else if (hours < 18) {
return "afternoon";
} else {
return "evening";
}
}
export default function WelcomeMessage() {
const { user } = useUser();
const timeOfDay = getTimeOfDay();
switch (timeOfDay) {
case "morning":
return (
<Trans
i18nKey="goodMorning"
defaults="Good morning, {name}!"
values={{ name: user.name }}
/>
);
case "afternoon":
return (
<Trans
i18nKey="goodAfternoon"
defaults="Good afternoon, {name}!"
values={{ name: user.name }}
/>
);
case "evening":
return (
<Trans
i18nKey="goodEvening"
defaults="Good evening, {name}!"
values={{ name: user.name }}
/>
);
}
}

View file

@ -11,7 +11,7 @@ export default async function Page({ params }: { params: Params }) {
const { t } = await getTranslation(params.locale); const { t } = await getTranslation(params.locale);
return ( return (
<div> <div>
<div className="sticky top-0 z-20 flex items-center justify-between border-b bg-gray-100/90 p-3 backdrop-blur-md sm:grid-cols-3"> <div className="sticky top-0 z-20 flex items-center justify-between p-3 backdrop-blur-md sm:grid-cols-3">
<div className="flex items-center justify-center gap-x-4"> <div className="flex items-center justify-center gap-x-4">
<BackButton /> <BackButton />
<GroupPollIcon size="xs" /> <GroupPollIcon size="xs" />

View file

@ -43,9 +43,7 @@ export function PageHeader({
className?: string; className?: string;
variant?: "default" | "ghost"; variant?: "default" | "ghost";
}) { }) {
return ( return <div className={cn(className)}>{children}</div>;
<div className={cn("flex items-center gap-x-4", className)}>{children}</div>
);
} }
export function PageSection({ children }: { children?: React.ReactNode }) { export function PageSection({ children }: { children?: React.ReactNode }) {

View file

@ -18,8 +18,8 @@ export function TabMenuItem({
className={cn( className={cn(
"flex h-9 min-w-0 grow items-center gap-x-2.5 rounded-md px-2.5 text-sm font-medium", "flex h-9 min-w-0 grow items-center gap-x-2.5 rounded-md px-2.5 text-sm font-medium",
pathname === href pathname === href
? "text-foreground bg-gray-200" ? "text-foreground bg-gray-100"
: "hover:text-foreground focus:text-foreground border-transparent text-gray-500 focus:bg-gray-200", : "hover:text-foreground focus:text-foreground border-transparent text-gray-500 hover:bg-gray-100 focus:bg-gray-200",
)} )}
href={href} href={href}
> >
@ -30,5 +30,7 @@ export function TabMenuItem({
} }
export function TabMenu({ children }: { children: React.ReactNode }) { export function TabMenu({ children }: { children: React.ReactNode }) {
return <ul className="flex gap-2.5">{children}</ul>; return (
<ul className="scrollbar-none flex gap-1 overflow-auto">{children}</ul>
);
} }

View file

@ -16,7 +16,7 @@ export function GridCardHeader({
export const GridCard = ({ children }: { children: React.ReactNode }) => { export const GridCard = ({ children }: { children: React.ReactNode }) => {
return ( return (
<div className="relative rounded-lg border bg-white p-3 shadow-sm"> <div className="relative flex h-48 flex-col rounded-lg bg-gray-100 p-4">
{children} {children}
</div> </div>
); );

View file

@ -12,8 +12,6 @@ import {
import { Icon } from "@rallly/ui/icon"; import { Icon } from "@rallly/ui/icon";
import { Tooltip, TooltipContent, TooltipTrigger } from "@rallly/ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "@rallly/ui/tooltip";
import { import {
BarChart2Icon,
CalendarSearchIcon,
CheckIcon, CheckIcon,
Link2Icon, Link2Icon,
MoreHorizontalIcon, MoreHorizontalIcon,
@ -25,7 +23,11 @@ import Link from "next/link";
import React from "react"; import React from "react";
import { useCopyToClipboard } from "react-use"; import { useCopyToClipboard } from "react-use";
import { GridCard, GridCardHeader } from "@/components/grid-card"; import {
GridCard,
GridCardFooter,
GridCardHeader,
} from "@/components/grid-card";
import { GroupPollIcon } from "@/components/group-poll-icon"; import { GroupPollIcon } from "@/components/group-poll-icon";
import { Pill, PillList } from "@/components/pill"; import { Pill, PillList } from "@/components/pill";
import { Trans } from "@/components/trans"; import { Trans } from "@/components/trans";
@ -40,6 +42,7 @@ function CopyLinkButton({ link, ...forwardProps }: { link: string }) {
<Tooltip open={isCopied ? true : undefined}> <Tooltip open={isCopied ? true : undefined}>
<TooltipTrigger onMouseLeave={() => setIsCopied(false)} asChild> <TooltipTrigger onMouseLeave={() => setIsCopied(false)} asChild>
<Button <Button
variant="ghost"
size="sm" size="sm"
{...forwardProps} {...forwardProps}
onClick={() => { onClick={() => {
@ -94,36 +97,15 @@ export function GroupPollCard({
return ( return (
<GridCard key={pollId}> <GridCard key={pollId}>
<GridCardHeader className="flex flex-col justify-between gap-4 sm:flex-row"> <GridCardHeader className="flex items-start justify-between gap-4">
<div className="flex items-center gap-2">
<div> <div>
<GroupPollIcon size="xs" /> <GroupPollIcon size="xs" />
</div> </div>
<h3 className="font-medium">
<Link className="truncate hover:underline" href={`/poll/${pollId}`}>
{title}
</Link>
</h3>
</div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<CopyLinkButton link={inviteLink} /> <CopyLinkButton link={inviteLink} />
<Tooltip>
<TooltipTrigger asChild>
<Button size="sm" asChild>
<Link href={`/poll/${pollId}`}>
<Icon>
<BarChart2Icon />
</Icon>
</Link>
</Button>
</TooltipTrigger>
<TooltipContent>
<Trans i18nKey="viewResults" defaults="View results" />
</TooltipContent>
</Tooltip>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button size="sm"> <Button variant="ghost" size="sm">
<Icon> <Icon>
<MoreHorizontalIcon /> <MoreHorizontalIcon />
</Icon> </Icon>
@ -147,16 +129,22 @@ export function GroupPollCard({
</DropdownMenu> </DropdownMenu>
</div> </div>
</GridCardHeader> </GridCardHeader>
<PillList> <div className="grow space-y-1">
<Pill> <h3 className="font-medium">
<Icon> <Link className="truncate hover:underline" href={`/poll/${pollId}`}>
<CalendarSearchIcon /> {title}
</Icon> </Link>
</h3>
<p className="text-muted-foreground text-sm">
{getRange( {getRange(
localizeTime(dateStart, !timeZone).toDate(), localizeTime(dateStart, !timeZone).toDate(),
localizeTime(dateEnd, !timeZone).toDate(), localizeTime(dateEnd, !timeZone).toDate(),
)} )}
</Pill> </p>
</div>
<GridCardFooter>
<PillList>
<Pill></Pill>
<Pill> <Pill>
<Icon> <Icon>
<User2Icon /> <User2Icon />
@ -168,6 +156,7 @@ export function GroupPollCard({
/> />
</Pill> </Pill>
</PillList> </PillList>
</GridCardFooter>
</GridCard> </GridCard>
); );
} }

View file

@ -11,7 +11,7 @@ export function GroupPollIcon({
role="img" role="img"
aria-label="Group Poll Icon" aria-label="Group Poll Icon"
className={cn( className={cn(
"inline-flex items-center justify-center bg-gradient-to-br from-purple-500 to-violet-500 text-purple-100", "inline-flex items-center justify-center bg-purple-600 text-purple-50",
{ {
"size-6 rounded": size === "xs", "size-6 rounded": size === "xs",
"size-8 rounded-md": size === "sm", "size-8 rounded-md": size === "sm",

View file

@ -1,10 +1,10 @@
export function PillList({ children }: React.PropsWithChildren) { export function PillList({ children }: React.PropsWithChildren) {
return <ul className="flex gap-2">{children}</ul>; return <ul className="flex flex-col gap-2">{children}</ul>;
} }
export function Pill({ children }: React.PropsWithChildren) { export function Pill({ children }: React.PropsWithChildren) {
return ( return (
<span className="text-muted-foreground inline-flex items-center gap-2 rounded-md border bg-gray-50 p-1 text-sm"> <span className="inline-flex items-center gap-2 rounded-md text-sm">
{children} {children}
</span> </span>
); );

View file

@ -7,7 +7,7 @@
@apply border-border; @apply border-border;
} }
body { body {
@apply text-foreground bg-gray-100; @apply text-foreground bg-white;
font-feature-settings: font-feature-settings:
"rlig" 1, "rlig" 1,
"calt" 1; "calt" 1;

View file

@ -42,7 +42,7 @@ export const dashboard = router({
}, },
}, },
}, },
take: 4, take: 3,
}); });
return polls.map((poll) => { return polls.map((poll) => {

View file

@ -3,15 +3,24 @@ import dayjs from "dayjs";
/** /**
* Get a range of dates in a human readable format * Get a range of dates in a human readable format
* If the start and end date are the same, return the start date * If the start and end date are the same, return the start date
* If either the end date is in a different year, include the year
* @param start The start date * @param start The start date
* @param end The end date * @param end The end date
* @returns A human readable range of dates * @returns A human readable range of dates
*/ */
export function getRange(start: Date, end: Date) { export function getRange(start: Date, end: Date) {
const startDay = dayjs(start).format("DD MMM"); const startDay = dayjs(start).format("D MMM");
const endDay = dayjs(end).format("DD MMM"); const endDay = dayjs(end).format("D MMM");
const startYear = dayjs(start).format("YYYY");
const endYear = dayjs(end).format("YYYY");
if (startDay === endDay) { if (startDay === endDay) {
return startDay; return `${startDay} ${startYear}`;
} }
return `${startDay} - ${endDay}`;
if (startYear !== endYear) {
return `${startDay} ${startYear} - ${endDay} ${endYear}`;
}
return `${startDay} - ${endDay} ${startYear}`;
} }

View file

@ -7,15 +7,15 @@ import { cn } from "./lib/utils";
const buttonVariants = cva( const buttonVariants = cva(
cn( cn(
"inline-flex border transition-colors font-medium disabled:pointer-events-none select-none disabled:opacity-50 items-center justify-center whitespace-nowrap border", "inline-flex border active:shadow-none hover:shadow-sm transition-colors font-medium disabled:pointer-events-none select-none disabled:opacity-50 items-center justify-center whitespace-nowrap border",
), ),
{ {
variants: { variants: {
variant: { variant: {
primary: primary:
"bg-primary disabled:bg-gray-400 disabled:border-transparent text-primary-foreground hover:bg-primary-700 active:bg-primary-800 shadow-sm", "bg-primary disabled:bg-gray-400 disabled:border-transparent text-primary-foreground hover:bg-primary-700 active:bg-primary-800",
destructive: destructive:
"bg-destructive shadow-sm text-destructive-foreground active:bg-destructive border-destructive hover:bg-destructive/90", "bg-destructive text-destructive-foreground active:bg-destructive border-destructive hover:bg-destructive/90",
default: default:
"data-[state=open]:bg-gray-100 hover:bg-gray-100 active:bg-gray-200 bg-white", "data-[state=open]:bg-gray-100 hover:bg-gray-100 active:bg-gray-200 bg-white",
secondary: secondary:
@ -27,7 +27,7 @@ const buttonVariants = cva(
size: { size: {
default: "h-8 px-2 gap-x-1.5 text-sm rounded-md", default: "h-8 px-2 gap-x-1.5 text-sm rounded-md",
sm: "h-7 text-sm px-1.5 gap-x-1.5 rounded-md", sm: "h-7 text-sm px-1.5 gap-x-1.5 rounded-md",
lg: "h-11 text-base gap-x-3 px-4 rounded-md", lg: "h-11 text-base gap-x-3 px-4 rounded-xl",
}, },
}, },
defaultVariants: { defaultVariants: {