LintPageTabs.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { InformationCircleIcon } from '@heroicons/react/16/solid'
  2. import { MessageSquareMore } from 'lucide-react'
  3. import { useRouter } from 'next/router'
  4. import {
  5. cn,
  6. Tabs_Shadcn_,
  7. TabsList_Shadcn_,
  8. TabsTrigger_Shadcn_,
  9. Tooltip,
  10. TooltipContent,
  11. TooltipTrigger,
  12. } from 'ui'
  13. import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
  14. import { LINT_TABS, LINTER_LEVELS } from '@/components/interfaces/Linter/Linter.constants'
  15. import { Lint } from '@/data/lint/lint-query'
  16. interface LintPageTabsProps {
  17. currentTab: string
  18. setCurrentTab: (value: LINTER_LEVELS) => void
  19. isLoading: boolean
  20. activeLints: Lint[]
  21. }
  22. const LintPageTabs = ({ currentTab, setCurrentTab, isLoading, activeLints }: LintPageTabsProps) => {
  23. const router = useRouter()
  24. const warnLintsCount = activeLints.filter((x) => x.level === 'WARN').length
  25. const errorLintsCount = activeLints.filter((x) => x.level === 'ERROR').length
  26. const infoLintsCount = activeLints.filter((x) => x.level === 'INFO').length
  27. const LintCountLabel = ({ tab }: { tab: (typeof LINT_TABS)[number] }) => {
  28. let count = 0
  29. let label = ''
  30. if (tab.id === LINTER_LEVELS.ERROR) {
  31. count = errorLintsCount
  32. label = 'errors'
  33. }
  34. if (tab.id === LINTER_LEVELS.WARN) {
  35. count = warnLintsCount
  36. label = 'warnings'
  37. }
  38. if (tab.id === LINTER_LEVELS.INFO) {
  39. count = infoLintsCount
  40. label = 'suggestions'
  41. }
  42. return (
  43. <span className="text-xs text-foreground-muted group-hover:text-foreground-lighter group-data-[state=active]:text-foreground-lighter transition">
  44. {isLoading ? (
  45. <ShimmeringLoader className="w-20 pt-1" />
  46. ) : (
  47. <>
  48. {count} {label}
  49. </>
  50. )}
  51. </span>
  52. )
  53. }
  54. return (
  55. <Tabs_Shadcn_
  56. defaultValue={currentTab}
  57. onValueChange={(value) => {
  58. setCurrentTab(value as LINTER_LEVELS)
  59. const { sort, search, ...rest } = router.query
  60. router.push({ ...router, query: { ...rest, preset: value, id: null } })
  61. }}
  62. >
  63. <TabsList_Shadcn_ className={cn('flex gap-0 border-0 items-end z-10 relative')}>
  64. {LINT_TABS.map((tab) => (
  65. <TabsTrigger_Shadcn_
  66. key={tab.id}
  67. value={tab.id}
  68. className={cn(
  69. 'group relative',
  70. 'px-6 py-3 border-b-0 flex flex-col items-start shadow-none! border-default border-t',
  71. 'even:border-x last:border-r even:border-x-strong! last:border-r-strong!',
  72. tab.id === currentTab ? 'bg-surface-200!' : 'bg-surface-200/33!',
  73. 'hover:bg-surface-100!',
  74. 'data-[state=active]:bg-surface-200!',
  75. 'hover:text-foreground-light',
  76. 'transition'
  77. )}
  78. >
  79. {tab.id === currentTab && (
  80. <div className="absolute top-0 left-0 w-full h-px bg-foreground" />
  81. )}
  82. <div className="flex items-center gap-x-2">
  83. <span
  84. className={
  85. tab.id === LINTER_LEVELS.ERROR
  86. ? 'text-destructive-600'
  87. : tab.id === LINTER_LEVELS.WARN
  88. ? 'text-warning'
  89. : 'text-brand-500'
  90. }
  91. >
  92. <MessageSquareMore size={14} fill="currentColor" strokeWidth={0} />
  93. </span>
  94. <span className="">{tab.label}</span>
  95. <Tooltip>
  96. <TooltipTrigger asChild>
  97. <InformationCircleIcon className="transition text-foreground-muted w-3 h-3 data-[state=delayed-open]:text-foreground-light" />
  98. </TooltipTrigger>
  99. <TooltipContent side="top">{tab.description}</TooltipContent>
  100. </Tooltip>
  101. </div>
  102. <LintCountLabel tab={tab} />
  103. </TabsTrigger_Shadcn_>
  104. ))}
  105. </TabsList_Shadcn_>
  106. </Tabs_Shadcn_>
  107. )
  108. }
  109. export default LintPageTabs