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