fix: bookings request reschedule UI badge (#7436)
* feat: update badge component * fix: use the camel cased startIcon prop * fix: reschedule request badge * fix: use the camel cased startIcon prop * fix: remove bold prop * Removed extra whitespace in HTML --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com>pull/7723/head
parent
ed750c8df1
commit
c0f4c8e035
|
@ -189,10 +189,9 @@ function BookingListItem(booking: BookingItemProps) {
|
|||
|
||||
const RequestSentMessage = () => {
|
||||
return (
|
||||
<div className="ml-1 mr-8 flex text-gray-500" data-testid="request_reschedule_sent">
|
||||
<FiSend className="-mt-[1px] w-4 rotate-45" />
|
||||
<p className="ml-2 ">{t("reschedule_request_sent")}</p>
|
||||
</div>
|
||||
<Badge startIcon={FiSend} size="md" variant="gray" data-testid="request_reschedule_sent">
|
||||
{t("reschedule_request_sent")}
|
||||
</Badge>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -396,13 +395,13 @@ function BookingListItem(booking: BookingItemProps) {
|
|||
/>
|
||||
)}
|
||||
{isCancelled && booking.rescheduled && (
|
||||
<div className="mt-2 inline-block text-left text-sm md:hidden">
|
||||
<div className="mt-2 inline-block md:hidden">
|
||||
<RequestSentMessage />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-4 pl-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4 sm:pl-0">
|
||||
<td className="flex w-full justify-end py-4 pl-4 text-right text-sm font-medium ltr:pr-4 rtl:pl-4 sm:pl-0">
|
||||
{isUpcoming && !isCancelled ? (
|
||||
<>
|
||||
{isPending && user?.id === booking.user?.id && <TableActions actions={pendingActions} />}
|
||||
|
|
|
@ -519,9 +519,7 @@ export default function Success(props: SuccessProps) {
|
|||
<div className="mb-3">
|
||||
<p>
|
||||
<span className="mr-2">{bookingInfo.user.name}</span>
|
||||
<Badge variant="blue" bold>
|
||||
{t("Host")}
|
||||
</Badge>
|
||||
<Badge variant="blue">{t("Host")}</Badge>
|
||||
</p>
|
||||
<p className="text-bookinglight">{bookingInfo.user.email}</p>
|
||||
</div>
|
||||
|
|
|
@ -233,13 +233,13 @@ export default function RoutingForms({
|
|||
</>
|
||||
}>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
<Badge variant="gray" StartIcon={FiMenu}>
|
||||
<Badge variant="gray" startIcon={FiMenu}>
|
||||
{fields.length} {fields.length === 1 ? "field" : "fields"}
|
||||
</Badge>
|
||||
<Badge variant="gray" StartIcon={FiGitMerge}>
|
||||
<Badge variant="gray" startIcon={FiGitMerge}>
|
||||
{form.routes.length} {form.routes.length === 1 ? "route" : "routes"}
|
||||
</Badge>
|
||||
<Badge variant="gray" StartIcon={FiMessageCircle}>
|
||||
<Badge variant="gray" startIcon={FiMessageCircle}>
|
||||
{form._count.responses} {form._count.responses === 1 ? "response" : "responses"}
|
||||
</Badge>
|
||||
</div>
|
||||
|
|
|
@ -65,21 +65,21 @@ export const EventTypeDescription = ({
|
|||
{eventType.metadata?.multipleDuration ? (
|
||||
eventType.metadata.multipleDuration.map((dur, idx) => (
|
||||
<li key={idx}>
|
||||
<Badge variant="gray" size="lg" StartIcon={FiClock}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiClock}>
|
||||
{dur}m
|
||||
</Badge>
|
||||
</li>
|
||||
))
|
||||
) : (
|
||||
<li>
|
||||
<Badge variant="gray" size="lg" StartIcon={FiClock}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiClock}>
|
||||
{eventType.length}m
|
||||
</Badge>
|
||||
</li>
|
||||
)}
|
||||
{eventType.schedulingType && (
|
||||
<li>
|
||||
<Badge variant="gray" size="lg" StartIcon={FiUsers}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiUsers}>
|
||||
{eventType.schedulingType === SchedulingType.ROUND_ROBIN && t("round_robin")}
|
||||
{eventType.schedulingType === SchedulingType.COLLECTIVE && t("collective")}
|
||||
</Badge>
|
||||
|
@ -87,7 +87,7 @@ export const EventTypeDescription = ({
|
|||
)}
|
||||
{recurringEvent?.count && recurringEvent.count > 0 && (
|
||||
<li className="hidden xl:block">
|
||||
<Badge variant="gray" size="lg" StartIcon={FiRefreshCw}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiRefreshCw}>
|
||||
{t("repeats_up_to", {
|
||||
count: recurringEvent.count,
|
||||
})}
|
||||
|
@ -96,7 +96,7 @@ export const EventTypeDescription = ({
|
|||
)}
|
||||
{stripeAppData.price > 0 && (
|
||||
<li>
|
||||
<Badge variant="gray" size="lg" StartIcon={FiCreditCard}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiCreditCard}>
|
||||
<IntlProvider locale="en">
|
||||
<FormattedNumber
|
||||
value={stripeAppData.price / 100.0}
|
||||
|
@ -109,7 +109,7 @@ export const EventTypeDescription = ({
|
|||
)}
|
||||
{eventType.requiresConfirmation && (
|
||||
<li className="hidden xl:block">
|
||||
<Badge variant="gray" size="lg" StartIcon={FiClipboard}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiClipboard}>
|
||||
{eventType.metadata?.requiresConfirmationThreshold
|
||||
? t("may_require_confirmation")
|
||||
: t("requires_confirmation")}
|
||||
|
@ -119,7 +119,7 @@ export const EventTypeDescription = ({
|
|||
{/* TODO: Maybe add a tool tip to this? */}
|
||||
{eventType.requiresConfirmation || (recurringEvent?.count && recurringEvent.count) ? (
|
||||
<li className="block xl:hidden">
|
||||
<Badge variant="gray" size="lg" StartIcon={FiPlus}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiPlus}>
|
||||
<p>{[eventType.requiresConfirmation, recurringEvent?.count].filter(Boolean).length}</p>
|
||||
</Badge>
|
||||
</li>
|
||||
|
@ -128,7 +128,7 @@ export const EventTypeDescription = ({
|
|||
)}
|
||||
{eventType?.seatsPerTimeSlot ? (
|
||||
<li>
|
||||
<Badge variant="gray" size="lg" StartIcon={FiUser}>
|
||||
<Badge variant="gray" size="lg" startIcon={FiUser}>
|
||||
<p>{t("event_type_seats", { numberOfSeats: eventType.seatsPerTimeSlot })} </p>
|
||||
</Badge>
|
||||
</li>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { WebhookTriggerEvents } from "@prisma/client";
|
||||
import type { WebhookTriggerEvents } from "@prisma/client";
|
||||
|
||||
import classNames from "@calcom/lib/classNames";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
|
@ -46,12 +46,7 @@ export default function WebhookListItem(props: {
|
|||
<Tooltip content={t("triggers_when")}>
|
||||
<div className="mt-2.5 w-4/5">
|
||||
{webhook.eventTriggers.map((trigger) => (
|
||||
<Badge
|
||||
key={trigger}
|
||||
className="ltr:mr-2 rtl:ml-2"
|
||||
variant="gray"
|
||||
bold
|
||||
StartIcon={FiAlertCircle}>
|
||||
<Badge key={trigger} className="ltr:mr-2 rtl:ml-2" variant="gray" startIcon={FiAlertCircle}>
|
||||
{t(`${trigger.toLowerCase()}`)}
|
||||
</Badge>
|
||||
))}
|
||||
|
|
|
@ -1,62 +1,58 @@
|
|||
import type { VariantProps } from "class-variance-authority";
|
||||
import { cva } from "class-variance-authority";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { GoPrimitiveDot } from "react-icons/go";
|
||||
|
||||
import classNames from "@calcom/lib/classNames";
|
||||
import type { SVGComponent } from "@calcom/types/SVGComponent";
|
||||
|
||||
const badgeClassNameByVariant = {
|
||||
default: "bg-orange-100 text-orange-800",
|
||||
warning: "bg-orange-100 text-orange-800",
|
||||
orange: "bg-orange-100 text-orange-800",
|
||||
success: "bg-green-100 text-green-800",
|
||||
green: "bg-green-100 text-green-800",
|
||||
gray: "bg-gray-100 text-gray-800 dark:bg-darkgray-200 dark:text-darkgray-800 group-hover:bg-gray-200 dark:group-hover:bg-darkgray-300",
|
||||
blue: "bg-blue-100 text-blue-800",
|
||||
red: "bg-red-100 text-red-800",
|
||||
error: "bg-red-100 text-red-800",
|
||||
};
|
||||
const badgeStyles = cva("font-medium inline-flex items-center justify-center rounded gap-x-1", {
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-orange-100 text-orange-800",
|
||||
warning: "bg-orange-100 text-orange-800",
|
||||
orange: "bg-orange-100 text-orange-800",
|
||||
success: "bg-green-100 text-green-800",
|
||||
green: "bg-green-100 text-green-800",
|
||||
gray: "bg-gray-100 text-gray-800 dark:bg-darkgray-200 dark:text-darkgray-800 group-hover:bg-gray-200 dark:group-hover:bg-darkgray-300",
|
||||
blue: "bg-blue-100 text-blue-800",
|
||||
red: "bg-red-100 text-red-800",
|
||||
error: "bg-red-100 text-red-800",
|
||||
},
|
||||
size: {
|
||||
sm: "px-1 py-0.5 text-xs",
|
||||
md: "py-1 px-1.5 text-xs",
|
||||
lg: "py-1 px-2 text-sm",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "sm",
|
||||
},
|
||||
});
|
||||
|
||||
const classNameBySize = {
|
||||
default: "h-5",
|
||||
lg: "h-6",
|
||||
};
|
||||
type InferredBadgeStyles = VariantProps<typeof badgeStyles>;
|
||||
|
||||
export type BadgeProps = {
|
||||
variant: keyof typeof badgeClassNameByVariant;
|
||||
size?: keyof typeof classNameBySize;
|
||||
StartIcon?: SVGComponent;
|
||||
bold?: boolean;
|
||||
withDot?: boolean;
|
||||
rounded?: boolean;
|
||||
} & JSX.IntrinsicElements["div"];
|
||||
type IconOrDot =
|
||||
| {
|
||||
startIcon?: SVGComponent;
|
||||
withDot?: unknown;
|
||||
}
|
||||
| { startIcon?: unknown; withDot?: boolean };
|
||||
|
||||
export type BadgeProps = InferredBadgeStyles &
|
||||
ComponentProps<"div"> & { children: ReactNode; rounded?: boolean } & IconOrDot;
|
||||
|
||||
export const Badge = function Badge(props: BadgeProps) {
|
||||
const {
|
||||
variant = "default",
|
||||
className,
|
||||
size = "default",
|
||||
rounded,
|
||||
StartIcon,
|
||||
withDot,
|
||||
bold,
|
||||
...passThroughProps
|
||||
} = props;
|
||||
const hasIconOrDot = StartIcon || withDot;
|
||||
const { variant, className, size, startIcon, withDot, children, rounded, ...passThroughProps } = props;
|
||||
const StartIcon = startIcon ? (startIcon as SVGComponent) : undefined;
|
||||
return (
|
||||
<div
|
||||
{...passThroughProps}
|
||||
className={classNames(
|
||||
"inline-flex items-center justify-center py-0.5 px-[6px] text-xs",
|
||||
bold ? "font-semibold" : "font-normal",
|
||||
rounded ? "min-w-5 min-h-5 rounded-full pt-1" : "rounded-md",
|
||||
!hasIconOrDot ? classNameBySize[size] : "",
|
||||
badgeClassNameByVariant[variant],
|
||||
className
|
||||
)}>
|
||||
<>
|
||||
{StartIcon && <StartIcon className="h-3 w-3 stroke-[3px] ltr:mr-1 rtl:ml-1" />}
|
||||
{withDot && <GoPrimitiveDot className="h-3 w-3 stroke-[3px] ltr:mr-1 rtl:ml-1" />}
|
||||
{props.children}
|
||||
</>
|
||||
className={classNames(badgeStyles({ variant, size }), rounded && "h-5 w-5 rounded-full p-0", className)}
|
||||
{...passThroughProps}>
|
||||
{withDot ? <GoPrimitiveDot className="h-3 w-3 stroke-[3px]" /> : null}
|
||||
{StartIcon ? <StartIcon className="h-3 w-3 stroke-[3px]" /> : null}
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ Status badge communicate status information. It is generally used within a cont
|
|||
<Badge withDot>Button Text</Badge>
|
||||
</Example>
|
||||
<Example title="With Icon">
|
||||
<Badge StartIcon={FiPlus}>Button Text</Badge>
|
||||
<Badge startIcon={FiPlus}>Button Text</Badge>
|
||||
</Example>
|
||||
</Examples>
|
||||
|
||||
|
@ -61,22 +61,22 @@ Alet badge is used in conjunction with an item, profile or label to indicate num
|
|||
<VariantRow variant="Default">
|
||||
<Badge variant="default" >Badge text</Badge>
|
||||
<Badge variant="default" withDot>Badge text</Badge>
|
||||
<Badge variant="default" StartIcon={FiPlus}>Badge text</Badge>
|
||||
<Badge variant="default" startIcon={FiPlus}>Badge text</Badge>
|
||||
</VariantRow>
|
||||
<VariantRow variant="Success">
|
||||
<Badge variant="success" >Badge text</Badge>
|
||||
<Badge variant="success" withDot>Badge text</Badge>
|
||||
<Badge variant="success" StartIcon={FiPlus}>Badge text</Badge>
|
||||
<Badge variant="success" startIcon={FiPlus}>Badge text</Badge>
|
||||
</VariantRow>
|
||||
<VariantRow variant="gray">
|
||||
<Badge variant="gray" >Badge text</Badge>
|
||||
<Badge variant="gray" withDot>Badge text</Badge>
|
||||
<Badge variant="gray" StartIcon={FiPlus}>Badge text</Badge>
|
||||
<Badge variant="gray" startIcon={FiPlus}>Badge text</Badge>
|
||||
</VariantRow>
|
||||
<VariantRow variant="error">
|
||||
<Badge variant="error" >Badge text</Badge>
|
||||
<Badge variant="error" withDot>Badge text</Badge>
|
||||
<Badge variant="error" StartIcon={FiPlus}>Badge text</Badge>
|
||||
<Badge variant="error" startIcon={FiPlus}>Badge text</Badge>
|
||||
</VariantRow>
|
||||
</VariantsTable>
|
||||
</Story>
|
||||
|
|
Loading…
Reference in New Issue