status-with-action.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. 'use client'
  2. import { RiAlertFill, RiCheckboxCircleFill, RiErrorWarningFill, RiInformation2Fill } from '@remixicon/react'
  3. import type { FC } from 'react'
  4. import React from 'react'
  5. import cn from '@/utils/classnames'
  6. import Divider from '@/app/components/base/divider'
  7. type Status = 'success' | 'error' | 'warning' | 'info'
  8. type Props = {
  9. type?: Status
  10. description: string
  11. actionText: string
  12. onAction: () => void
  13. disabled?: boolean
  14. }
  15. const IconMap = {
  16. success: {
  17. Icon: RiCheckboxCircleFill,
  18. color: 'text-text-success',
  19. },
  20. error: {
  21. Icon: RiErrorWarningFill,
  22. color: 'text-text-destructive',
  23. },
  24. warning: {
  25. Icon: RiAlertFill,
  26. color: 'text-text-warning-secondary',
  27. },
  28. info: {
  29. Icon: RiInformation2Fill,
  30. color: 'text-text-accent',
  31. },
  32. }
  33. const getIcon = (type: Status) => {
  34. return IconMap[type]
  35. }
  36. const StatusAction: FC<Props> = ({
  37. type = 'info',
  38. description,
  39. actionText,
  40. onAction,
  41. disabled,
  42. }) => {
  43. const { Icon, color } = getIcon(type)
  44. return (
  45. <div className='relative flex items-center h-[34px] rounded-lg pl-2 pr-3 border border-components-panel-border bg-components-panel-bg-blur shadow-xs'>
  46. <div className={`absolute inset-0 opacity-40 rounded-lg ${(type === 'success' && 'bg-[linear-gradient(92deg,rgba(23,178,106,0.25)_0%,rgba(255,255,255,0.00)_100%)]')
  47. || (type === 'warning' && 'bg-[linear-gradient(92deg,rgba(247,144,9,0.25)_0%,rgba(255,255,255,0.00)_100%)]')
  48. || (type === 'error' && 'bg-[linear-gradient(92deg,rgba(240,68,56,0.25)_0%,rgba(255,255,255,0.00)_100%)]')
  49. || (type === 'info' && 'bg-[linear-gradient(92deg,rgba(11,165,236,0.25)_0%,rgba(255,255,255,0.00)_100%)]')
  50. }`}
  51. />
  52. <div className='relative z-10 flex h-full items-center space-x-2'>
  53. <Icon className={cn('w-4 h-4', color)} />
  54. <div className='text-[13px] font-normal text-text-secondary'>{description}</div>
  55. <Divider type='vertical' className='!h-4' />
  56. <div onClick={onAction} className={cn('text-text-accent font-semibold text-[13px] cursor-pointer', disabled && 'text-text-disabled cursor-not-allowed')}>{actionText}</div>
  57. </div>
  58. </div>
  59. )
  60. }
  61. export default React.memo(StatusAction)