diff --git a/public/locale/en.json b/public/locale/en.json index 2a485441d4f..910baca98cf 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -328,6 +328,7 @@ "add_new_patient": "Add New Patient", "add_new_user": "Add New User", "add_notes": "Add notes", + "add_patient_updates": "Add Patient Updates", "add_policy": "Add Insurance Policy", "add_prescription_medication": "Add Prescription Medication", "add_prescription_to_consultation_note": "Add a new prescription to this consultation.", diff --git a/src/CAREUI/display/Callout.tsx b/src/CAREUI/display/Callout.tsx index 0983d66f298..c1d4b05a88f 100644 --- a/src/CAREUI/display/Callout.tsx +++ b/src/CAREUI/display/Callout.tsx @@ -2,10 +2,8 @@ import React from "react"; import { cn } from "@/lib/utils"; -import { ButtonVariant } from "@/components/Common/ButtonV2"; - interface CalloutProps { - variant?: ButtonVariant; + variant?: "primary" | "secondary" | "warning" | "alert" | "danger"; className?: string; badge: string; children: React.ReactNode; diff --git a/src/CAREUI/display/Chip.tsx b/src/CAREUI/display/Chip.tsx deleted file mode 100644 index e501bf26f90..00000000000 --- a/src/CAREUI/display/Chip.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; - -import { ButtonVariant } from "@/components/Common/ButtonV2"; - -import { classNames } from "@/Utils/utils"; - -interface Props { - size?: "small" | "medium" | "large"; - hideBorder?: boolean; - variant?: ButtonVariant | "custom"; - startIcon?: IconName; - endIcon?: IconName; - text: string; - tooltip?: string; - className?: string; - id?: string; -} - -export default function Chip({ - size = "medium", - hideBorder = false, - variant = "primary", - ...props -}: Props) { - return ( - - {props.startIcon && } - {props.text} - {props.endIcon && } - - ); -} diff --git a/src/CAREUI/display/PopupModal.tsx b/src/CAREUI/display/PopupModal.tsx deleted file mode 100644 index 6410addbcc2..00000000000 --- a/src/CAREUI/display/PopupModal.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { ReactNode, useEffect, useRef, useState } from "react"; -import { useTranslation } from "react-i18next"; - -import { Cancel, Submit } from "@/components/Common/ButtonV2"; -import DialogModal from "@/components/Common/Dialog"; - -import useBreakpoints from "@/hooks/useBreakpoints"; - -import { classNames } from "@/Utils/utils"; - -type Props = { - show: boolean; - onHide: () => void; - children: ReactNode; - anchorRef: React.RefObject; - className?: string; - onSubmit?: () => void; -}; - -type Position = - | { left: number; top: number } - | { right: number; bottom: number } - | { left: number; bottom: number } - | { right: number; top: number }; - -export default function PopupModal(props: Props) { - const { t } = useTranslation(); - const isMobile = useBreakpoints({ default: true, lg: false }); - - if (!isMobile) { - return ; - } - - return ( - -
- {props.children} -
- - {props.onSubmit && ( - - )} -
-
-
- ); -} - -const DesktopView = (props: Props) => { - const { t } = useTranslation(); - const [position, setPosition] = useState({ left: 0, top: 0 }); - const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); - const modal = useRef(null); - const [children, setChildren] = useState(props.children); - - useEffect(() => { - // just to make sure the animation runs smoothly - if (props.show) { - setChildren(props.children); - } - }, [props.children, props.show]); - - useEffect(() => { - const handleOutsideClick = (e: MouseEvent) => { - const isModalClicked = - modal.current && modal.current.contains(e.target as Node); - if (!isModalClicked) { - props.onHide(); - } - }; - - if (props.show) { - const currentMousePosition = mousePosition; - const modalHeight = modal.current?.clientHeight || 0; - const modalWidth = modal.current?.clientWidth || 0; - const clickX = currentMousePosition.x; - const clickY = currentMousePosition.y; - const windowHeight = window.innerHeight; - const windowWidth = window.innerWidth; - - const anchorPosition = props.anchorRef.current?.getBoundingClientRect(); - const anchorX = anchorPosition?.x || 0; - const anchorY = anchorPosition?.y || 0; - const verticalCenter = windowHeight / 2; - const horizontalCenter = windowWidth / 2; - const mountLeft = clickX - anchorX; - const mountTop = clickY - anchorY; - - let position; - if (clickX > horizontalCenter) { - position = { left: mountLeft - modalWidth }; - } else { - position = { left: mountLeft }; - } - if (clickY > verticalCenter) { - position = { ...position, top: mountTop - modalHeight }; - } else { - position = { ...position, top: mountTop }; - } - setPosition(position); - } - - document.addEventListener("mousedown", handleOutsideClick); - return () => { - document.removeEventListener("mousedown", handleOutsideClick); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [props.show]); - - useEffect(() => { - const handleMouseMove = (e: MouseEvent) => { - setMousePosition({ x: e.clientX, y: e.clientY }); - }; - document.addEventListener("mousemove", handleMouseMove); - return () => { - document.removeEventListener("mousemove", handleMouseMove); - }; - }, []); - - const positionAttributes = Object.entries(position).reduce( - (acc, [key, value]) => { - return { ...acc, [key]: `${value}px` }; - }, - {}, - ); - - return ( -
- {children} -
- - {props.onSubmit && ( - - )} -
-
- ); -}; diff --git a/src/CAREUI/interactive/FiltersSlideover.tsx b/src/CAREUI/interactive/FiltersSlideover.tsx index 6e4feeaf852..b3c11fcd035 100644 --- a/src/CAREUI/interactive/FiltersSlideover.tsx +++ b/src/CAREUI/interactive/FiltersSlideover.tsx @@ -6,8 +6,6 @@ import SlideOver from "@/CAREUI/interactive/SlideOver"; import { Button } from "@/components/ui/button"; -import ButtonV2 from "@/components/Common/ButtonV2"; - import useFilters from "@/hooks/useFilters"; type AdvancedFilter = ReturnType["advancedFilter"]; @@ -35,18 +33,17 @@ export default function FiltersSlideover({
{t("filters")}
- + +
} diff --git a/src/CAREUI/interactive/Zoom.tsx b/src/CAREUI/interactive/Zoom.tsx index 0d6513efbba..d97300d36cb 100644 --- a/src/CAREUI/interactive/Zoom.tsx +++ b/src/CAREUI/interactive/Zoom.tsx @@ -2,7 +2,7 @@ import { ReactNode, createContext, useContext, useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; type ProviderValue = { scale: number; @@ -69,31 +69,25 @@ export const ZoomControls = (props: { disabled?: boolean }) => { return (
- - + {Math.round(ctx.scale * 100)}% - - +
); }; diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx index 6379b8b7ad8..9cefca73aac 100644 --- a/src/CAREUI/misc/PaginatedList.tsx +++ b/src/CAREUI/misc/PaginatedList.tsx @@ -2,7 +2,8 @@ import { createContext, useContext, useEffect, useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2, { CommonButtonProps } from "@/components/Common/ButtonV2"; +import { Button, ButtonProps } from "@/components/ui/button"; + import Pagination from "@/components/Common/Pagination"; import { PaginatedResponse, QueryRoute } from "@/Utils/request/types"; @@ -118,13 +119,16 @@ const WhenLoading = (props: WhenEmptyProps) => { PaginatedList.WhenLoading = WhenLoading; +interface CommonButtonProps extends ButtonProps { + label?: string; +} + const Refresh = ({ label = "Refresh", ...props }: CommonButtonProps) => { const { loading, refetch } = useContextualized(); return ( - refetch()} disabled={loading} @@ -134,7 +138,7 @@ const Refresh = ({ label = "Refresh", ...props }: CommonButtonProps) => { className={classNames("text-lg", loading && "animate-spin")} /> {label} - + ); }; diff --git a/src/components/Auth/ResetPassword.tsx b/src/components/Auth/ResetPassword.tsx index 95155c1eea6..6986331e6f8 100644 --- a/src/components/Auth/ResetPassword.tsx +++ b/src/components/Auth/ResetPassword.tsx @@ -2,7 +2,8 @@ import { navigate } from "raviger"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import TextFormField from "@/components/Form/FormFields/TextFormField"; import { validateRule } from "@/components/Users/UserFormValidations"; @@ -173,8 +174,20 @@ const ResetPassword = (props: ResetPasswordProps) => { )}
- navigate("/login")} /> - handleSubmit(e)} label="reset" /> + +
diff --git a/src/components/Common/AvatarEditModal.tsx b/src/components/Common/AvatarEditModal.tsx index dc044264c4d..47163532b84 100644 --- a/src/components/Common/AvatarEditModal.tsx +++ b/src/components/Common/AvatarEditModal.tsx @@ -10,7 +10,8 @@ import Webcam from "react-webcam"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2, { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import DialogModal from "@/components/Common/Dialog"; import useDragAndDrop from "@/hooks/useDragAndDrop"; @@ -253,49 +254,56 @@ const AvatarEditModal = ({
- +
- { setConstraint(() => VideoConstraints.user); setIsCameraOpen(true); }} > {`${t("open")} ${t("camera")}`} - +
- { e.stopPropagation(); closeModal(); dragProps.setFileDropError(""); }} disabled={isProcessing} - /> + > + {t("cancel")} + {imageUrl && ( - {t("delete")} - + )} - @@ -310,7 +318,7 @@ const AvatarEditModal = ({ {isProcessing ? `${t("uploading")}...` : `${t("save")}`} - +
) : ( @@ -346,29 +354,35 @@ const AvatarEditModal = ({
{!previewImage ? ( <> - + ) : ( <> - { setPreviewImage(null); }} > {t("retake")} - - + + )}
- { setPreviewImage(null); setIsCameraOpen(false); webRef.current.stopCamera(); }} - label={t("close")} disabled={isProcessing} - /> + > + {t("close")} +
)} diff --git a/src/components/Common/ButtonV2.tsx b/src/components/Common/ButtonV2.tsx deleted file mode 100644 index cf1299d29bf..00000000000 --- a/src/components/Common/ButtonV2.tsx +++ /dev/null @@ -1,237 +0,0 @@ -import { Link } from "raviger"; -import { useTranslation } from "react-i18next"; - -import CareIcon from "@/CAREUI/icons/CareIcon"; -import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild"; - -import { AuthorizedElementProps } from "@/Utils/AuthorizeFor"; -import { classNames } from "@/Utils/utils"; - -export type ButtonSize = "small" | "default" | "large"; -export type ButtonShape = "square" | "circle"; -export type ButtonVariant = - | "primary" - | "secondary" - | "danger" - | "warning" - | "alert"; - -export type RawButtonProps = Omit< - React.DetailedHTMLProps< - React.ButtonHTMLAttributes, - HTMLButtonElement - >, - "style" ->; - -export type ButtonStyleProps = { - /** - * - `"small"` has small text and minimal padding. - * - `"default"` has small text with normal padding. - * - `"large"` has base text size with large padding. - */ - size?: ButtonSize; - /** - * - `"square"` gives a button with minimally rounded corners. - * - `"circle"` gives a button with fully rounded corners. Ideal when only - * icons are present. - */ - circle?: boolean | undefined; - /** - * - `"primary"` is ideal for form submissions, etc. - * - `"secondary"` is ideal for things that have secondary importance. - * - `"danger"` is ideal for destructive or dangerous actions, such as delete. - * - `"warning"` is ideal for actions that require caution such as archive. - * - `"alert"` is ideal for actions that require alert. - */ - variant?: ButtonVariant; - /** If set, gives an elevated button with hover effects. */ - shadow?: boolean | undefined; - /** If set, removes the background to give a simple text button. */ - ghost?: boolean | undefined; - /** - * If set, applies border to the button. - */ - border?: boolean | undefined; -}; - -export type ButtonProps = RawButtonProps & - AuthorizedElementProps & - ButtonStyleProps & { - /** - * Whether the button is disabled or not. - * This is overriden to `true` if `loading` is `true`. - */ - disabled?: boolean | undefined; - /** - * Whether the button should be disabled and show a loading animation. - */ - loading?: boolean | undefined; - /** - * A button will convert to a link if the `href` prop is set. - */ - href?: string | undefined; - /** - * Link target. Only applicable if `href` is set. - */ - target?: string | undefined; - /** - * Whether the button should be having a Id. - */ - id?: string | undefined; - /** - * Tooltip showed when hovered over. - */ - tooltip?: string; - /** - * Class for tooltip - */ - tooltipClassName?: string; - }; - -export const buttonStyles = ({ - size = "default", - circle = false, - variant = "primary", - ghost = false, - border = false, - shadow = !ghost, -}: ButtonStyleProps) => { - return classNames( - "inline-flex h-min cursor-pointer items-center justify-center gap-2 whitespace-pre font-medium outline-offset-1 transition-all duration-200 ease-in-out disabled:cursor-not-allowed disabled:bg-secondary-200 disabled:text-secondary-500", - `button-size-${size}`, - `button-shape-${circle ? "circle" : "square"}`, - ghost ? `button-${variant}-ghost` : `button-${variant}-default`, - border && `button-${variant}-border`, - shadow && "shadow enabled:hover:shadow-md", - ); -}; - -/** - * @deprecated Use `Button` instead. - */ -const ButtonV2 = ({ - authorizeFor, - size, - variant, - circle, - shadow, - ghost, - border, - disabled, - loading, - children, - href, - target, - tooltip, - tooltipClassName, - ...props -}: ButtonProps) => { - shadow ??= !ghost; - - const className = classNames( - buttonStyles({ size, circle, variant, ghost, border, shadow }), - tooltip && "tooltip", - props.className, - ); - - if (tooltip) { - children = ( - <> - {tooltip && ( - - {tooltip} - - )} - {children} - - ); - } - - if (href && !(disabled || loading)) { - return ( - - - - ); - } - - if (authorizeFor) { - return ( - - {({ isAuthorized }) => ( - - )} - - ); - } - - return ( - - ); -}; - -export default ButtonV2; - -// Common buttons - -export type CommonButtonProps = ButtonProps & { label?: string }; - -/** - * @deprecated Use `Button` with the `type="submit"` prop instead. - */ -export const Submit = ({ label = "Submit", ...props }: CommonButtonProps) => { - const { t } = useTranslation(); - return ( - - - {t(label)} - - } - {...props} - className={classNames("w-full md:w-auto", props.className)} - /> - ); -}; - -/** - * @deprecated Use `Button` instead. - */ -export const Cancel = ({ label = "Cancel", ...props }: CommonButtonProps) => { - const { t } = useTranslation(); - return ( - - - {label && {t(label)}} - - } - {...props} - className={classNames("w-full md:w-auto", props.className)} - /> - ); -}; - -export type ButtonWithTimerProps = CommonButtonProps & { - initialInverval?: number; - interval?: number; -}; diff --git a/src/components/Common/ConfirmDialog.tsx b/src/components/Common/ConfirmDialog.tsx index 5fff5d9f8fb..78cebe23f8e 100644 --- a/src/components/Common/ConfirmDialog.tsx +++ b/src/components/Common/ConfirmDialog.tsx @@ -1,4 +1,5 @@ -import { ButtonVariant, Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button, ButtonVariant } from "@/components/ui/button"; + import DialogModal from "@/components/Common/Dialog"; type ConfirmDialogProps = { @@ -30,15 +31,18 @@ const ConfirmDialog = ({ {children}
- - + {cancelLabel} + +
); diff --git a/src/components/Common/ExcelFIleDragAndDrop.tsx b/src/components/Common/ExcelFIleDragAndDrop.tsx index d868e03f2a4..86902a9b189 100644 --- a/src/components/Common/ExcelFIleDragAndDrop.tsx +++ b/src/components/Common/ExcelFIleDragAndDrop.tsx @@ -4,7 +4,8 @@ import * as XLSX from "xlsx"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import ExcelViewer from "@/components/Common/ExcelViewer"; import useDragAndDrop from "@/hooks/useDragAndDrop"; @@ -248,7 +249,9 @@ export default function ExcelFileDragAndDrop({ Upload a file
- { closeModal(); setErrors([]); @@ -257,8 +260,12 @@ export default function ExcelFileDragAndDrop({ dragProps.setFileDropError(""); }} disabled={loading} - /> - + {t("close")} + +
); diff --git a/src/components/Common/ExcelViewer.tsx b/src/components/Common/ExcelViewer.tsx index d35c98a6cc8..e77dc0132da 100644 --- a/src/components/Common/ExcelViewer.tsx +++ b/src/components/Common/ExcelViewer.tsx @@ -1,8 +1,10 @@ +import { t } from "i18next"; import { ReactNode, useEffect, useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2, { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import DialogModal from "@/components/Common/Dialog"; import Pagination from "@/components/Common/Pagination"; @@ -76,16 +78,16 @@ const ExcelViewer = ({

{downloadURL && downloadURL.length > 0 && ( - + )}
@@ -261,8 +263,12 @@ const ExcelViewer = ({
- - + {t("close")} + +
); diff --git a/src/components/Common/FilePreviewDialog.tsx b/src/components/Common/FilePreviewDialog.tsx index 95155fcc9d9..4d6709d427d 100644 --- a/src/components/Common/FilePreviewDialog.tsx +++ b/src/components/Common/FilePreviewDialog.tsx @@ -14,12 +14,12 @@ import { useTranslation } from "react-i18next"; import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; -import ButtonV2, { Cancel } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import CircularProgress from "@/components/Common/CircularProgress"; import DialogModal from "@/components/Common/Dialog"; import { StateInterface } from "@/components/Files/FileUpload"; - -import { FileUploadModel } from "../Patient/models"; +import { FileUploadModel } from "@/components/Patient/models"; const PDFViewer = lazy(() => import("@/components/Common/PDFViewer")); @@ -211,24 +211,27 @@ const FilePreviewDialog = (props: FilePreviewProps) => {
{downloadURL && downloadURL.length > 0 && ( - + )} - +
{uploadedFiles && uploadedFiles.length > 1 && ( - handleNext(index - 1)} disabled={index <= 0} aria-label="Previous file" @@ -237,7 +240,7 @@ const FilePreviewDialog = (props: FilePreviewProps) => { } > - + )}
{file_state.isImage ? ( @@ -279,8 +282,9 @@ const FilePreviewDialog = (props: FilePreviewProps) => {
{uploadedFiles && uploadedFiles.length > 1 && ( - handleNext(index + 1)} disabled={index >= uploadedFiles.length - 1} aria-label="Next file" @@ -289,7 +293,7 @@ const FilePreviewDialog = (props: FilePreviewProps) => { } > - + )}
@@ -330,9 +334,8 @@ const FilePreviewDialog = (props: FilePreviewProps) => { false, ], ].map((button, index) => ( - void} className="z-50 rounded bg-white/60 px-4 py-2 text-black backdrop-blur transition hover:bg-white/70" @@ -345,7 +348,7 @@ const FilePreviewDialog = (props: FilePreviewProps) => { /> )} {button[0] as string} - + ))} )} @@ -366,9 +369,8 @@ const FilePreviewDialog = (props: FilePreviewProps) => { page === numPages, ], ].map((button, index) => ( - void} className="z-50 rounded bg-white/60 px-4 py-2 text-black backdrop-blur transition hover:bg-white/70" @@ -381,7 +383,7 @@ const FilePreviewDialog = (props: FilePreviewProps) => { /> )} {button[0] as string} - + ))} )} diff --git a/src/components/Common/Menu.tsx b/src/components/Common/Menu.tsx index aa647a3dedb..6568e5b143c 100644 --- a/src/components/Common/Menu.tsx +++ b/src/components/Common/Menu.tsx @@ -3,7 +3,7 @@ import { DetailedHTMLProps, HTMLAttributes, ReactNode } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import { ButtonSize, ButtonVariant } from "@/components/Common/ButtonV2"; +import { buttonVariants } from "@/components/ui/button"; import { useIsAuthorized } from "@/hooks/useIsAuthorized"; @@ -13,8 +13,6 @@ import { classNames } from "@/Utils/utils"; interface DropdownMenuProps { id?: string; title: string; - variant?: ButtonVariant; - size?: ButtonSize; icon?: JSX.Element | undefined; children: ReactNode | ReactNode[]; disabled?: boolean | undefined; @@ -23,11 +21,11 @@ interface DropdownMenuProps { containerClassName?: string | undefined; } -export default function DropdownMenu({ - variant = "primary", - size = "default", - ...props -}: DropdownMenuProps) { +/** + * @deprecated This component will be replaced with ShadCN's dropdown. + */ + +export default function DropdownMenu({ ...props }: DropdownMenuProps) { return (
-
+
{props.icon} {props.title || "Dropdown"}
- + - - {icon} - + {icon} {children}
diff --git a/src/components/Common/Pagination.tsx b/src/components/Common/Pagination.tsx index fb12ff66efa..6db267ed9c7 100644 --- a/src/components/Common/Pagination.tsx +++ b/src/components/Common/Pagination.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; import { statusType, useAbortableEffect } from "@/common/utils"; @@ -171,18 +171,17 @@ interface NavButtonProps { const NavButton = (props: NavButtonProps) => { return ( - {props.children} {props.tooltip} - + ); }; diff --git a/src/components/Common/UpdatableApp.tsx b/src/components/Common/UpdatableApp.tsx index d27c778830f..c623c2c10a3 100644 --- a/src/components/Common/UpdatableApp.tsx +++ b/src/components/Common/UpdatableApp.tsx @@ -3,7 +3,7 @@ import { ReactNode, useEffect, useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; import { classNames } from "@/Utils/utils"; @@ -136,14 +136,9 @@ const UpdateAppPopup = ({ onUpdate }: UpdateAppPopupProps) => { A new version of CARE is available

- +
diff --git a/src/components/Facility/FacilityHome.tsx b/src/components/Facility/FacilityHome.tsx index 7f33dec2b1b..3eba20f4765 100644 --- a/src/components/Facility/FacilityHome.tsx +++ b/src/components/Facility/FacilityHome.tsx @@ -190,7 +190,7 @@ export const FacilityHome = ({ facilityId }: Props) => { } action="Delete" - variant="danger" + variant="destructive" show={openDeleteDialog} onClose={handleDeleteClose} onConfirm={handleDeleteSubmit} diff --git a/src/components/Files/CameraCaptureDialog.tsx b/src/components/Files/CameraCaptureDialog.tsx index f81d854c559..0a9e3fc39ad 100644 --- a/src/components/Files/CameraCaptureDialog.tsx +++ b/src/components/Files/CameraCaptureDialog.tsx @@ -4,7 +4,8 @@ import Webcam from "react-webcam"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2, { Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import DialogModal from "@/components/Common/Dialog"; import useBreakpoints from "@/hooks/useBreakpoints"; @@ -134,9 +135,13 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) {
{!previewImage ? ( - + ) : ( <> )} @@ -145,20 +150,22 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { {!previewImage ? ( <>
- { captureImage(); }} className="m-2" > {t("capture")} - +
) : ( <>
- { setPreviewImage(null); onResetCapture(); @@ -166,8 +173,9 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { className="m-2" > {t("retake")} - - +
)}
- { setPreviewImage(null); onResetCapture(); @@ -191,16 +199,16 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { className="m-2" > {t("close")} - +
{/* buttons for laptop screens */}
- +
@@ -208,42 +216,45 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { {!previewImage ? ( <>
- { captureImage(); }} > {t("capture")} - +
) : ( <>
- { setPreviewImage(null); onResetCapture(); }} > {t("retake")} - - +
)}
- { setPreviewImage(null); onResetCapture(); @@ -251,7 +262,7 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { }} > {`${t("close")} ${t("camera")}`} - +
diff --git a/src/components/Files/FileBlock.tsx b/src/components/Files/FileBlock.tsx index 5015a67e2e1..46b6f680889 100644 --- a/src/components/Files/FileBlock.tsx +++ b/src/components/Files/FileBlock.tsx @@ -3,7 +3,8 @@ import { t } from "i18next"; import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import { FileUploadModel } from "@/components/Patient/models"; import { FileManagerResult } from "@/hooks/useFileManager"; @@ -90,35 +91,37 @@ export default function FileBlock(props: FileBlockProps) { )} {!file.is_archived && (fileManager.isPreviewable(file) ? ( - fileManager.viewFile(file, associating_id)} className="w-full md:w-auto" > {t("view")} - + ) : ( - fileManager.downloadFile(file, associating_id)} className="w-full md:w-auto" > {t("download")} - + ))}
{!file.is_archived && editable && ( - fileManager.editFile(file, associating_id)} className="flex-1 md:flex-auto" > {t("rename")} - + )} {(file.is_archived || editable) && archivable && ( - fileManager.archiveFile(file, associating_id)} className="flex-1 md:flex-auto" @@ -127,7 +130,7 @@ export default function FileBlock(props: FileBlockProps) { icon={file.is_archived ? "l-info-circle" : "l-archive"} /> {file.is_archived ? t("more_info") : t("archive")} - + )}
diff --git a/src/components/Files/FileUpload.tsx b/src/components/Files/FileUpload.tsx index e28c99ce513..7a4798c5320 100644 --- a/src/components/Files/FileUpload.tsx +++ b/src/components/Files/FileUpload.tsx @@ -1,10 +1,12 @@ +import { Loader2 } from "lucide-react"; import { ReactNode, useState } from "react"; import { useTranslation } from "react-i18next"; import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import Pagination from "@/components/Common/Pagination"; import Tabs from "@/components/Common/Tabs"; import FileBlock from "@/components/Files/FileBlock"; @@ -291,25 +293,30 @@ export const FileUpload = (props: FileUploadProps) => { error={fileUpload.error || undefined} />
- fileUpload.handleFileUpload(associatedId) } - loading={fileUpload.uploading} - className="w-full" + disabled={fileUpload.uploading} // Disable the button when loading + className={`w-full ${fileUpload.uploading ? "opacity-50" : ""}`} id="upload_file_button" > - + {fileUpload.uploading ? ( + + ) : ( + + )} {t("upload")} - - +
{!!fileUpload.progress && ( diff --git a/src/components/Form/Form.tsx b/src/components/Form/Form.tsx index 97f424f69d7..38a4cb0818b 100644 --- a/src/components/Form/Form.tsx +++ b/src/components/Form/Form.tsx @@ -1,6 +1,7 @@ import { useEffect, useMemo, useRef, useState } from "react"; -import { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import { FieldValidator } from "@/components/Form/FieldValidators"; import { FormContextValue, @@ -142,19 +143,20 @@ const Form = ({ {(!hideCancelButton || !hideSubmitButton) && (
{!hideCancelButton && ( - + )} {!hideSubmitButton && ( - + > + {props.submitLabel ?? "Submit"} + )}
)} diff --git a/src/components/Patient/PatientConsentRecordBlock.tsx b/src/components/Patient/PatientConsentRecordBlock.tsx index f46648c0bae..0378ba95819 100644 --- a/src/components/Patient/PatientConsentRecordBlock.tsx +++ b/src/components/Patient/PatientConsentRecordBlock.tsx @@ -1,6 +1,8 @@ +import { t } from "i18next"; import { useEffect, useState } from "react"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import { PatientConsentModel } from "@/components/Facility/models"; import FileBlock from "@/components/Files/FileBlock"; import { SelectFormField } from "@/components/Form/FormFields/SelectFormField"; @@ -86,15 +88,16 @@ export default function PatientConsentRecordBlockGroup(props: { required error="Please select a patient code status type" /> - { handlePCSUpdate(patientCodeStatus); }} disabled={patientCodeStatus === consentRecord.patient_code_status} className="h-[46px]" > - Update - + {t("update")} + )} {files?.map((file: FileUploadModel, i: number) => ( diff --git a/src/components/Patient/PatientConsentRecords.tsx b/src/components/Patient/PatientConsentRecords.tsx index 55ced7435ed..7d33487c730 100644 --- a/src/components/Patient/PatientConsentRecords.tsx +++ b/src/components/Patient/PatientConsentRecords.tsx @@ -1,9 +1,10 @@ import { t } from "i18next"; +import { Loader2 } from "lucide-react"; import { useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button, buttonVariants } from "@/components//ui/button"; import ConfirmDialog from "@/components/Common/ConfirmDialog"; import Page from "@/components/Common/Page"; import Tabs from "@/components/Common/Tabs"; @@ -126,7 +127,7 @@ export default function PatientConsentRecords(props: { setShowPCSChangeModal(null); }} action="Change Patient Code Status" - variant="danger" + variant="destructive" description={`Consent records exist with the "${CONSENT_PATIENT_CODE_STATUS_CHOICES.find((c) => consentRecords?.find((c) => c.type === 2 && !c.archived)?.patient_code_status === c.id)?.text}" patient code status. Adding a new record for a different type will archive the existing records. Are you sure you want to proceed?`} title="Archive Previous Records" className="w-auto" @@ -177,7 +178,8 @@ export default function PatientConsentRecords(props: {
{fileUpload.files[0] ? ( <> - { const diffPCS = consentRecords?.find( (record) => @@ -193,31 +195,33 @@ export default function PatientConsentRecords(props: { handleUpload(); } }} - loading={fileUpload.uploading} disabled={ - newConsent.type === 2 && - newConsent.patient_code_status === 0 + fileUpload.uploading || + (newConsent.type === 2 && + newConsent.patient_code_status === 0) } - className="flex-1" + className={`flex-1 ${fileUpload.uploading ? "opacity-50" : ""}`} > - - Upload - - + ) : ( + + )} + {t("upload")} + + ) : ( <>
)} */} @@ -250,7 +250,7 @@ export const PatientHome = (props: { {/* {NonReadOnlyUsers && (
- setOpenAssignVolunteerDialog(true)} disabled={false} @@ -264,7 +264,7 @@ export const PatientHome = (props: { ? t("update_volunteer") : t("assign_to_volunteer")} - +
)} */} diff --git a/src/components/Patient/PatientIndex.tsx b/src/components/Patient/PatientIndex.tsx index afdd9d1e92b..64b3480f925 100644 --- a/src/components/Patient/PatientIndex.tsx +++ b/src/components/Patient/PatientIndex.tsx @@ -156,7 +156,7 @@ export default function PatientIndex({ facilityId }: { facilityId: string }) { return (
-
+
diff --git a/src/components/Resource/ResourceCommentSection.tsx b/src/components/Resource/ResourceCommentSection.tsx index 8b80bd6a27a..777284b7c7f 100644 --- a/src/components/Resource/ResourceCommentSection.tsx +++ b/src/components/Resource/ResourceCommentSection.tsx @@ -2,7 +2,8 @@ import { useState } from "react"; import PaginatedList from "@/CAREUI/misc/PaginatedList"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import CircularProgress from "@/components/Common/CircularProgress"; import TextAreaFormField from "@/components/Form/FormFields/TextAreaFormField"; @@ -51,14 +52,15 @@ const CommentSection = (props: { id: string }) => { />
- { await onSubmitComment(); query.refetch(); }} > Post Your Comment - +
diff --git a/src/components/Resource/ResourceCreate.tsx b/src/components/Resource/ResourceCreate.tsx index d8c7e25ea97..e0f199af7ad 100644 --- a/src/components/Resource/ResourceCreate.tsx +++ b/src/components/Resource/ResourceCreate.tsx @@ -6,7 +6,8 @@ import { useTranslation } from "react-i18next"; import Card from "@/CAREUI/display/Card"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import { FacilitySelect } from "@/components/Common/FacilitySelect"; import Loading from "@/components/Common/Loading"; import Page from "@/components/Common/Page"; @@ -316,8 +317,12 @@ export default function ResourceCreate(props: resourceProps) { />
- goBack()} /> - + +
diff --git a/src/components/Resource/ResourceDetailsUpdate.tsx b/src/components/Resource/ResourceDetailsUpdate.tsx index e78f002e8a0..edeb252d7e0 100644 --- a/src/components/Resource/ResourceDetailsUpdate.tsx +++ b/src/components/Resource/ResourceDetailsUpdate.tsx @@ -1,9 +1,11 @@ +import { t } from "i18next"; import { navigate, useQueryParams } from "raviger"; import { useReducer, useState } from "react"; import Card from "@/CAREUI/display/Card"; -import { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import CircularProgress from "@/components/Common/CircularProgress"; import { FacilitySelect } from "@/components/Common/FacilitySelect"; import Loading from "@/components/Common/Loading"; @@ -280,8 +282,12 @@ export const ResourceDetailsUpdate = (props: resourceProps) => {
- goBack()} /> - + +
diff --git a/src/components/Resource/ResourceList.tsx b/src/components/Resource/ResourceList.tsx index f2f663184c8..bdcf0929701 100644 --- a/src/components/Resource/ResourceList.tsx +++ b/src/components/Resource/ResourceList.tsx @@ -1,10 +1,10 @@ import { Link, navigate } from "raviger"; import { useTranslation } from "react-i18next"; -import Chip from "@/CAREUI/display/Chip"; import CareIcon from "@/CAREUI/icons/CareIcon"; import { AdvancedFilterButton } from "@/CAREUI/interactive/FiltersSlideover"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { ExportButton } from "@/components/Common/Export"; @@ -90,34 +90,38 @@ export default function ListView() { {resource.status === "TRANSPORTATION TO BE ARRANGED" ? (
- + > + + + + {t(`${resource.status}`)} +
) : (
- + > + + + + {t(`${resource.status}`)} +
)} diff --git a/src/components/Users/ConfirmFacilityModal.tsx b/src/components/Users/ConfirmFacilityModal.tsx index 289e576aa54..851f685fbb9 100644 --- a/src/components/Users/ConfirmFacilityModal.tsx +++ b/src/components/Users/ConfirmFacilityModal.tsx @@ -69,7 +69,7 @@ const ConfirmFacilityModal = ({ action={action} onClose={handleCancel} onConfirm={handleOk} - variant="danger" + variant="destructive" >
{body}
diff --git a/src/components/Users/UnlinkFacilityDialog.tsx b/src/components/Users/UnlinkFacilityDialog.tsx index ff729150fbf..f0ba9c65704 100644 --- a/src/components/Users/UnlinkFacilityDialog.tsx +++ b/src/components/Users/UnlinkFacilityDialog.tsx @@ -32,7 +32,7 @@ const UnlinkFacilityDialog = (props: ConfirmDialogProps) => { onClose={handleCancel} onConfirm={handleSubmit} disabled={disable} - variant="danger" + variant="destructive" >
diff --git a/src/components/Users/UserAvatar.tsx b/src/components/Users/UserAvatar.tsx index 74bd0789d35..e6493e526ca 100644 --- a/src/components/Users/UserAvatar.tsx +++ b/src/components/Users/UserAvatar.tsx @@ -2,9 +2,11 @@ import careConfig from "@careConfig"; import { useState } from "react"; import { useTranslation } from "react-i18next"; +import { Button } from "@/components/ui/button"; +import { TooltipComponent } from "@/components/ui/tooltip"; + import { Avatar } from "@/components/Common/Avatar"; import AvatarEditModal from "@/components/Common/AvatarEditModal"; -import ButtonV2 from "@/components/Common/ButtonV2"; import Loading from "@/components/Common/Loading"; import useAuthUser from "@/hooks/useAuthUser"; @@ -99,21 +101,32 @@ export default function UserAvatar({ className="h-20 w-20" />
- setEditAvatar(!editAvatar)} - type="button" - id="change-avatar" - className="border border-gray-200 bg-gray-50 text-black hover:bg-gray-100" - shadow={false} - disabled={!showAvatarEdit(authUser, userData)} - tooltip={ - !showAvatarEdit(authUser, userData) - ? t("edit_avatar_permission_error") - : undefined - } - > - {t("change_avatar")} - + {!showAvatarEdit(authUser, userData) ? ( + + + + ) : ( + + )} +

{t("change_avatar_note")}

diff --git a/src/components/Users/UserDeleteDialog.tsx b/src/components/Users/UserDeleteDialog.tsx index 665b2ef0b4a..5a2becefe3d 100644 --- a/src/components/Users/UserDeleteDialog.tsx +++ b/src/components/Users/UserDeleteDialog.tsx @@ -16,7 +16,7 @@ const UserDeleteDialog = (props: ConfirmDialogProps) => { } action="Delete" - variant="danger" + variant="destructive" show onConfirm={props.handleOk} onClose={props.handleCancel} diff --git a/src/components/Users/UserResetPassword.tsx b/src/components/Users/UserResetPassword.tsx index 5807ecd129b..2ceae7314ae 100644 --- a/src/components/Users/UserResetPassword.tsx +++ b/src/components/Users/UserResetPassword.tsx @@ -3,6 +3,8 @@ import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; +import { Button } from "@/components/ui/button"; + import Form from "@/components/Form/Form"; import TextFormField from "@/components/Form/FormFields/TextFormField"; import { validateRule } from "@/components/Users/UserFormValidations"; @@ -13,8 +15,6 @@ import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import { UserBase } from "@/types/user/user"; -import ButtonV2 from "../Common/ButtonV2"; - interface PasswordForm { username: string; old_password: string; @@ -192,16 +192,18 @@ export default function UserResetPassword({ const editButton = () => (
- setIsEditing(!isEditing)} type="button" id="change-edit-password-button" - className="flex items-center gap-2 rounded-sm border border-gray-100 bg-white px-3 py-1.5 text-sm text-[#009D48] shadow-sm hover:bg-gray-50" - shadow={false} > - + {isEditing ? t("cancel") : t("change_password")} - +
); diff --git a/src/components/Users/UserSummary.tsx b/src/components/Users/UserSummary.tsx index 870c5f19739..397396abc8e 100644 --- a/src/components/Users/UserSummary.tsx +++ b/src/components/Users/UserSummary.tsx @@ -3,8 +3,8 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; +import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild"; -import ButtonV2 from "@/components/Common/ButtonV2"; import LanguageSelector from "@/components/Common/LanguageSelector"; import UserColumns from "@/components/Common/UserColumns"; import UserAvatar from "@/components/Users/UserAvatar"; @@ -29,6 +29,8 @@ import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import { UserBase } from "@/types/user/user"; +import { Button } from "../ui/button"; + export default function UserSummaryTab({ userData, refetchUserData, @@ -172,17 +174,20 @@ export default function UserSummaryTab({
- deletePermitted} - onClick={() => setshowDeleteDialog(true)} - variant="danger" - data-testid="user-delete-button" - className="my-1 inline-flex" - disabled={isDeleting} - > - - {t("delete_account_btn")} - + deletePermitted}> + {({ isAuthorized }) => ( + + )} +
)} diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 60973469121..b794b6a99fb 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -28,6 +28,10 @@ const buttonVariants = cva( "text-white border border-primary-900 rounded-lg font-medium relative overflow-hidden bg-gradient-to-b from-primary-700 to-primary-800 hover:from-primary-800 hover:to-primary-900 shadow-lg", white: "bg-white border border-secondary-400 text-gray-900 shadow-sm hover:bg-gray-100 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-50 dark:hover:bg-gray-800/80", + warning: + "bg-warning-100 text-warning-900 border border-warning-300 shadow-sm hover:bg-warning-100/80 dark:bg-warning-900 dark:text-warning-50 dark:hover:bg-warning-900/80", + alert: + "bg-alert-100 text-alert-900 border border-alert-300 shadow-sm hover:bg-alert-100/80 dark:bg-alert-900 dark:text-alert-50 dark:hover:bg-alert-900/80", }, size: { default: "h-9 px-4 py-2", @@ -44,6 +48,19 @@ const buttonVariants = cva( }, ); +export type ButtonVariant = + | "primary" + | "outline" + | "secondary" + | "destructive" + | "primary_gradient" + | "ghost" + | "link" + | "white" + | "alert" + | "warning" + | "outline_primary"; + export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { diff --git a/src/hooks/useFileManager.tsx b/src/hooks/useFileManager.tsx index b1efeaf5082..3c1660e3674 100644 --- a/src/hooks/useFileManager.tsx +++ b/src/hooks/useFileManager.tsx @@ -1,9 +1,11 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { t } from "i18next"; import { useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; -import { Cancel, Submit } from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import DialogModal from "@/components/Common/Dialog"; import FilePreviewDialog from "@/components/Common/FilePreviewDialog"; import { StateInterface } from "@/components/Files/FileUpload"; @@ -306,8 +308,16 @@ export default function useFileManager( />
- setArchiveDialogueOpen(null)} /> - + +
@@ -384,7 +394,13 @@ export default function useFileManager( ))}
- setArchiveDialogueOpen(null)} /> +
- setEditDialogueOpen(null)} /> - setEditDialogueOpen(null)} + > + {t("cancel")} + +
diff --git a/src/pages/Encounters/tabs/EncounterFeedTab.tsx b/src/pages/Encounters/tabs/EncounterFeedTab.tsx index 5f5a75ee210..648ab9159fe 100644 --- a/src/pages/Encounters/tabs/EncounterFeedTab.tsx +++ b/src/pages/Encounters/tabs/EncounterFeedTab.tsx @@ -14,7 +14,6 @@ // import useOperateCamera, { // PTZPayload, // } from "@/components/CameraFeed/useOperateCamera"; -// import ButtonV2 from "@/components/Common/ButtonV2"; // import ConfirmDialog from "@/components/Common/ConfirmDialog"; // import Loading from "@/components/Common/Loading"; // import { ConsultationTabProps } from "@/components/Facility/ConsultationDetails/index"; @@ -226,7 +225,7 @@ // className="animate-spin text-base text-zinc-300 md:mx-2" // /> // ) : ( -// setShowPresetSaveConfirmation(true)} // > // -// +// // )} // // ) : ( diff --git a/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx b/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx index 38baf3787d1..9efa21e64ae 100644 --- a/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx +++ b/src/pages/FacilityOrganization/FacilityOrganizationIndex.tsx @@ -62,7 +62,7 @@ export default function FacilityOrganizationIndex({ if (!data?.results?.length) { return ( -
+
@@ -90,7 +90,7 @@ export default function FacilityOrganizationIndex({ return ( -
+
diff --git a/src/pages/FacilityOrganization/components/CreateFacilityOrganizationSheet.tsx b/src/pages/FacilityOrganization/components/CreateFacilityOrganizationSheet.tsx index 4e45160b495..6350a613622 100644 --- a/src/pages/FacilityOrganization/components/CreateFacilityOrganizationSheet.tsx +++ b/src/pages/FacilityOrganization/components/CreateFacilityOrganizationSheet.tsx @@ -93,7 +93,7 @@ export default function CreateFacilityOrganizationSheet({ return ( - diff --git a/src/style/CAREUI.css b/src/style/CAREUI.css index e65c2c5554e..893d16c2e4e 100644 --- a/src/style/CAREUI.css +++ b/src/style/CAREUI.css @@ -99,69 +99,12 @@ @apply h-full md:h-[300px] w-full } -.button-primary-default { @apply accent-primary-500 bg-primary-500 hover:bg-primary-400 text-white !important } -.button-primary-ghost { @apply accent-primary-500 hover:bg-primary-100 text-primary-500 !important } -.button-primary-border { @apply border border-primary-500 } - -.button-secondary-default { @apply accent-secondary-200 bg-white hover:bg-secondary-200 text-secondary-800 !important } -.button-secondary-ghost { @apply accent-secondary-300 hover:bg-secondary-400 text-secondary-700 !important } -.button-secondary-border { @apply border border-secondary-300 } - -.button-danger-default { @apply accent-danger-500 bg-danger-500 hover:bg-danger-400 text-white !important } -.button-danger-ghost { @apply accent-danger-500 hover:bg-danger-100 text-danger-500 !important } -.button-danger-border { @apply border border-danger-500 } - -.button-warning-default { @apply accent-warning-500 bg-warning-500 hover:bg-warning-400 text-white !important } -.button-warning-ghost { @apply accent-warning-500 hover:bg-warning-100 text-warning-500 !important } -.button-warning-border { @apply border border-warning-500 } - -.button-alert-default { @apply accent-alert-600 bg-alert-600 hover:bg-alert-500 text-white !important } -.button-alert-ghost { @apply accent-alert-600 hover:bg-alert-100 text-alert-600 !important } -.button-alert-border { @apply border border-alert-600 } - -.button-shape-square { @apply rounded } -.button-shape-circle { @apply rounded-full } - -.button-size-small { @apply px-2 py-1 text-xs } -.button-size-default { @apply py-2 px-4 text-sm } -.button-size-large { @apply py-3 px-5 text-base } - .dropdown-item-primary { @apply accent-primary-500 hover:bg-primary-100 text-black hover:text-primary-500 } .dropdown-item-secondary { @apply accent-secondary-200 hover:bg-secondary-200 text-secondary-700 } .dropdown-item-danger { @apply accent-danger-500 hover:bg-danger-100 text-danger-500 } .dropdown-item-warning { @apply accent-warning-500 hover:bg-warning-100 text-warning-500 } .dropdown-item-alert { @apply accent-alert-600 hover:bg-alert-100 text-alert-600 } -a.button-primary-default { @apply hover:bg-primary-400 } -a.button-primary-ghost { @apply hover:bg-primary-100 } - -a.button-secondary-default { @apply hover:bg-secondary-200 } -a.button-secondary-ghost { @apply hover:bg-secondary-100 } - -a.button-danger-default { @apply hover:bg-danger-400 } -a.button-danger-ghost { @apply hover:bg-danger-100 } - -a.button-warning-default { @apply hover:bg-warning-400 } -a.button-warning-ghost { @apply hover:bg-warning-100 } - -a.button-alert-default { @apply hover:bg-alert-500 } -a.button-alert-ghost { @apply hover:bg-alert-100 } - -button.button-primary-default { @apply enabled:hover:bg-primary-400 } -button.button-primary-ghost { @apply enabled:hover:bg-primary-100 } - -button.button-secondary-default { @apply enabled:hover:bg-secondary-200 } -button.button-secondary-ghost { @apply enabled:hover:bg-secondary-100 } - -button.button-danger-default { @apply enabled:hover:bg-danger-400 } -button.button-danger-ghost { @apply enabled:hover:bg-danger-100 } - -button.button-warning-default { @apply enabled:hover:bg-warning-400 } -button.button-warning-ghost { @apply enabled:hover:bg-warning-100 } - -button.button-alert-default { @apply enabled:hover:bg-alert-500 } -button.button-alert-ghost { @apply enabled:hover:bg-alert-100 } - .cui-form-button-group { @apply flex flex-col-reverse md:flex-row md:justify-end gap-2 w-full md:w-auto }