您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

provider-card.tsx 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. 'use client'
  2. import React from 'react'
  3. import type { FC } from 'react'
  4. import { useTheme } from 'next-themes'
  5. import { useTranslation } from 'react-i18next'
  6. import { RiArrowRightUpLine } from '@remixicon/react'
  7. import Badge from '../base/badge'
  8. import type { Plugin } from './types'
  9. import Description from './card/base/description'
  10. import Icon from './card/base/card-icon'
  11. import Title from './card/base/title'
  12. import DownloadCount from './card/base/download-count'
  13. import Button from '@/app/components/base/button'
  14. import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace'
  15. import cn from '@/utils/classnames'
  16. import { useBoolean } from 'ahooks'
  17. import { getPluginLinkInMarketplace } from '@/app/components/plugins/marketplace/utils'
  18. import { useI18N } from '@/context/i18n'
  19. import { useRenderI18nObject } from '@/hooks/use-i18n'
  20. type Props = {
  21. className?: string
  22. payload: Plugin
  23. }
  24. const ProviderCard: FC<Props> = ({
  25. className,
  26. payload,
  27. }) => {
  28. const getValueFromI18nObject = useRenderI18nObject()
  29. const { t } = useTranslation()
  30. const { theme } = useTheme()
  31. const [isShowInstallFromMarketplace, {
  32. setTrue: showInstallFromMarketplace,
  33. setFalse: hideInstallFromMarketplace,
  34. }] = useBoolean(false)
  35. const { org, label } = payload
  36. const { locale } = useI18N()
  37. return (
  38. <div className={cn('group relative rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg p-4 pb-3 shadow-xs hover:bg-components-panel-on-panel-item-bg', className)}>
  39. {/* Header */}
  40. <div className="flex">
  41. <Icon src={payload.icon} />
  42. <div className="ml-3 w-0 grow">
  43. <div className="flex h-5 items-center">
  44. <Title title={getValueFromI18nObject(label)} />
  45. {/* <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> */}
  46. </div>
  47. <div className='mb-1 flex h-4 items-center justify-between'>
  48. <div className='flex items-center'>
  49. <div className='system-xs-regular text-text-tertiary'>{org}</div>
  50. <div className='system-xs-regular mx-2 text-text-quaternary'>·</div>
  51. <DownloadCount downloadCount={payload.install_count || 0} />
  52. </div>
  53. </div>
  54. </div>
  55. </div>
  56. <Description className='mt-3' text={getValueFromI18nObject(payload.brief)} descriptionLineRows={2}></Description>
  57. <div className='mt-3 flex space-x-0.5'>
  58. {payload.tags.map(tag => (
  59. <Badge key={tag.name} text={tag.name} />
  60. ))}
  61. </div>
  62. <div
  63. className='absolute bottom-0 left-0 right-0 hidden items-center gap-2 rounded-xl bg-gradient-to-tr from-components-panel-on-panel-item-bg to-background-gradient-mask-transparent p-4 pt-8 group-hover:flex'
  64. >
  65. <Button
  66. className='grow'
  67. variant='primary'
  68. onClick={showInstallFromMarketplace}
  69. >
  70. {t('plugin.detailPanel.operation.install')}
  71. </Button>
  72. <Button
  73. className='grow'
  74. variant='secondary'
  75. >
  76. <a href={`${getPluginLinkInMarketplace(payload)}?language=${locale}${theme ? `&theme=${theme}` : ''}`} target='_blank' className='flex items-center gap-0.5'>
  77. {t('plugin.detailPanel.operation.detail')}
  78. <RiArrowRightUpLine className='h-4 w-4' />
  79. </a>
  80. </Button>
  81. </div>
  82. {
  83. isShowInstallFromMarketplace && (
  84. <InstallFromMarketplace
  85. manifest={payload}
  86. uniqueIdentifier={payload.latest_package_identifier}
  87. onClose={hideInstallFromMarketplace}
  88. onSuccess={() => hideInstallFromMarketplace()}
  89. />
  90. )
  91. }
  92. </div>
  93. )
  94. }
  95. export default ProviderCard