MarketplaceDetailHero.tsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import Link from 'next/link'
  2. import type { ReactNode } from 'react'
  3. import { Badge, cn, NavMenu, NavMenuItem } from 'ui'
  4. import {
  5. PageHeader,
  6. PageHeaderDescription,
  7. PageHeaderIcon,
  8. PageHeaderMeta,
  9. PageHeaderNavigationTabs,
  10. PageHeaderSummary,
  11. PageHeaderTitle,
  12. } from 'ui-patterns'
  13. import { getMarketplaceSource, MarketplaceSourceBadge } from './Marketplace.constants'
  14. import { IntegrationLogo } from '@/components/interfaces/Integrations/Integration/IntegrationLogo'
  15. import type { IntegrationDefinition } from '@/components/interfaces/Integrations/Landing/Integrations.constants'
  16. interface MarketplaceDetailHeroProps {
  17. integration: IntegrationDefinition
  18. title: string
  19. subtitle?: ReactNode
  20. tabs: Array<{ label: string; href: string; active: boolean }>
  21. }
  22. interface BadgesComponentProps {
  23. className?: string
  24. source: ReturnType<typeof getMarketplaceSource>
  25. integration: IntegrationDefinition
  26. }
  27. const BadgesComponent = ({ className, source, integration }: BadgesComponentProps) => {
  28. return (
  29. <div className={cn('flex items-center gap-2', className)}>
  30. <MarketplaceSourceBadge source={source} />
  31. {integration.status && <Badge variant="warning">{integration.status}</Badge>}
  32. </div>
  33. )
  34. }
  35. export const MarketplaceDetailHero = ({
  36. integration,
  37. title,
  38. subtitle,
  39. tabs,
  40. }: MarketplaceDetailHeroProps) => {
  41. const source = getMarketplaceSource(integration)
  42. return (
  43. <PageHeader size="full" className={cn('@container')}>
  44. <PageHeaderMeta className="mx-auto w-full flex @xl:flex-col @xl:justify-start @xl:items-start gap-4">
  45. <div className="mx-auto w-full flex items-center gap-2 @lg:gap-4">
  46. <PageHeaderIcon>
  47. <IntegrationLogo integration={integration} size="w-10 h-10 @lg:w-14 @lg:h-14" />
  48. </PageHeaderIcon>
  49. <PageHeaderSummary className="gap-y-0.5">
  50. <div className="mb-1 flex flex-col flex-wrap @lg:flex-row @lg:items-center gap-2">
  51. <PageHeaderTitle className="heading-title truncate">{title}</PageHeaderTitle>
  52. <BadgesComponent
  53. className="hidden @xl:flex"
  54. source={source}
  55. integration={integration}
  56. />
  57. </div>
  58. <PageHeaderDescription className="hidden @lg:block">{subtitle}</PageHeaderDescription>
  59. </PageHeaderSummary>
  60. </div>
  61. <PageHeaderDescription className="@lg:hidden">{subtitle}</PageHeaderDescription>
  62. <BadgesComponent className="flex @xl:hidden" source={source} integration={integration} />
  63. </PageHeaderMeta>
  64. {tabs.length > 0 && (
  65. <PageHeaderNavigationTabs className="mx-auto w-full">
  66. <NavMenu>
  67. {tabs.map((tab) => (
  68. <NavMenuItem key={tab.href} active={tab.active}>
  69. <Link href={tab.href}>{tab.label}</Link>
  70. </NavMenuItem>
  71. ))}
  72. </NavMenu>
  73. </PageHeaderNavigationTabs>
  74. )}
  75. </PageHeader>
  76. )
  77. }