celeroncoder / celeroncoder/vitas

React Review Audit

Open
#4 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
0
Forks
1
PR merge metrics
No merged PRs in 30d

Description

**Score: 83/100** · 3 errors · 124 warnings

Copy as prompt

```text
Fix the following React Review diagnostics in my codebase.

## Errors (3)

1. [error] jsx-key — app/page.tsx:40
Missing "key" prop for element in iterator.

2. [error] rules-of-hooks — components/uploadbanner.tsx:24
React Hook "useToast" is called conditionally. React Hooks must be called in the exact same order in every component render.

3. [error] rules-of-hooks — components/uploadbanner.tsx:26
React Hook "useMutation" is called conditionally. React Hooks must be called in the exact same order in every component render.

## Warnings (124)

4. [warning] no-react19-deprecated-apis — components/ui/button.tsx:43
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

5. [warning] no-effect-chain — components/members-table/data-table/index.tsx:90
useEffect reacts to "selectedRows" which is set by another useEffect — chains of effects add an extra render per link and become rigid as code evolves. Compute what you can during render and write all related state inside the event handler that originally fires the chain

6. [warning] prefer-useReducer — components/members-table/data-table/index.tsx:48
Component "DataTable" has 8 useState calls — consider useReducer for related state

7. [warning] js-combine-iterations — components/members-table/data-table/index.tsx:134
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

8. [warning] design-no-space-on-flex-children — components/members-table/data-table/index.tsx:208
space-x-2 on a flex/grid parent — use gap-x-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL

9. [warning] no-react19-deprecated-apis — components/ui/avatar.tsx:8
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

10. [warning] no-react19-deprecated-apis — components/ui/avatar.tsx:23
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

11. [warning] no-react19-deprecated-apis — components/ui/avatar.tsx:35
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

12. [warning] react-compiler-destructure-method — components/create-account.tsx:63
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

13. [warning] design-no-space-on-flex-children — components/create-account.tsx:88
space-x-3 on a flex/grid parent — use gap-x-3 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL

14. [warning] query-mutation-missing-invalidation — components/members-table/data-table/deliever-email-confirmation-modal.tsx:31
useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

15. [warning] no-react19-deprecated-apis — components/ui/alert-dialog.tsx:21
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

16. [warning] no-react19-deprecated-apis — components/ui/alert-dialog.tsx:36
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

17. [warning] no-react19-deprecated-apis — components/ui/alert-dialog.tsx:82
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

18. [warning] no-react19-deprecated-apis — components/ui/alert-dialog.tsx:94
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

19. [warning] no-react19-deprecated-apis — components/ui/alert-dialog.tsx:107
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

20. [warning] no-react19-deprecated-apis — components/ui/alert-dialog.tsx:119
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

21. [warning] design-no-three-period-ellipsis — components/checkout-card.tsx:31
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

22. [warning] react-compiler-destructure-method — components/checkout-card.tsx:44
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

23. [warning] design-no-three-period-ellipsis — app/(application)/dashboard/projects/[id]/settings/page.tsx:78
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

24. [warning] no-react19-deprecated-apis — components/ui/accordion.tsx:11
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

25. [warning] no-react19-deprecated-apis — components/ui/accordion.tsx:23
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

26. [warning] design-no-redundant-size-axes — components/ui/accordion.tsx:37
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

27. [warning] no-react19-deprecated-apis — components/ui/accordion.tsx:43
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

28. [warning] async-defer-await — app/(application)/dashboard/projects/[id]/page.tsx:47
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast

29. [warning] server-sequential-independent-await — app/(application)/dashboard/projects/[id]/page.tsx:47
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

30. [warning] no-cascading-set-state — components/theme-toggle-card.tsx:32
4 setState calls in a single useEffect — consider using useReducer or deriving state

31. [warning] design-no-redundant-size-axes — components/members-table/columns/actions-col/index.tsx:42
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)

32. [warning] design-no-redundant-size-axes — components/members-table/columns/actions-col/index.tsx:44
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

33. [warning] server-sequential-independent-await — app/page.tsx:25
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

34. [warning] nextjs-no-img-element — app/page.tsx:43
Use next/image instead of — provides automatic optimization, lazy loading, and responsive srcset

35. [warning] design-no-default-tailwind-palette — app/page.tsx:50
bg-gray-600 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

36. [warning] query-mutation-missing-invalidation — components/members-table/columns/actions-col/deliever-email-confirmation-modal.tsx:31
useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

37. [warning] design-no-redundant-size-axes — components/members-table/column-header.tsx:46
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

38. [warning] design-no-redundant-size-axes — components/members-table/column-header.tsx:48
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

39. [warning] design-no-redundant-size-axes — components/members-table/column-header.tsx:50
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

40. [warning] design-no-three-period-ellipsis — components/project-grid.tsx:52
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

41. [warning] server-sequential-independent-await — app/(application)/settings/billing/page.tsx:65
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

42. [warning] react-compiler-destructure-method — components/project-delete.tsx:77
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

43. [warning] no-unknown-property — app/api/projects/og/route.tsx:29
Unknown property found

44. [warning] no-unknown-property — app/api/projects/og/route.tsx:31
Unknown property found

45. [warning] no-unknown-property — app/api/projects/og/route.tsx:40
Unknown property found

46. [warning] no-unknown-property — app/api/projects/og/route.tsx:42
Unknown property found

47. [warning] no-unknown-property — app/api/projects/og/route.tsx:53
Unknown property found

48. [warning] no-react19-deprecated-apis — components/ui/table.tsx:5
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

49. [warning] no-react19-deprecated-apis — components/ui/table.tsx:19
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

50. [warning] no-react19-deprecated-apis — components/ui/table.tsx:27
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

51. [warning] no-react19-deprecated-apis — components/ui/table.tsx:39
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

52. [warning] no-react19-deprecated-apis — components/ui/table.tsx:51
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

53. [warning] no-react19-deprecated-apis — components/ui/table.tsx:66
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

54. [warning] no-react19-deprecated-apis — components/ui/table.tsx:81
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

55. [warning] no-react19-deprecated-apis — components/ui/table.tsx:96
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

56. [warning] async-await-in-loop — service/project.ts:110
await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

57. [warning] no-react19-deprecated-apis — components/ui/separator.tsx:8
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

58. [warning] no-react19-deprecated-apis — components/ui/select.tsx:15
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

59. [warning] design-no-redundant-size-axes — components/ui/select.tsx:29
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

60. [warning] no-react19-deprecated-apis — components/ui/select.tsx:35
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

61. [warning] no-react19-deprecated-apis — components/ui/select.tsx:65
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

62. [warning] no-react19-deprecated-apis — components/ui/select.tsx:77
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

63. [warning] design-no-redundant-size-axes — components/ui/select.tsx:89
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)

64. [warning] design-no-redundant-size-axes — components/ui/select.tsx:91
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

65. [warning] no-react19-deprecated-apis — components/ui/select.tsx:99
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

66. [warning] design-no-redundant-size-axes — components/user-button.tsx:41
w-6 h-6 → use the shorthand size-6 (Tailwind v3.4+)

67. [warning] design-no-redundant-size-axes — components/user-button.tsx:51
w-6 h-6 → use the shorthand size-6 (Tailwind v3.4+)

68. [warning] react-compiler-destructure-method — components/user-button.tsx:67
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

69. [warning] react-compiler-destructure-method — components/user-button.tsx:78
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

70. [warning] design-no-three-period-ellipsis — components/user-button.tsx:100
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

71. [warning] no-react19-deprecated-apis — components/ui/scroll-area.tsx:8
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

72. [warning] no-react19-deprecated-apis — components/ui/scroll-area.tsx:26
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

73. [warning] nextjs-no-img-element — components/uploadbanner.tsx:16
Use next/image instead of — provides automatic optimization, lazy loading, and responsive srcset

74. [warning] no-react19-deprecated-apis — components/ui/popover.tsx:14
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

75. [warning] rendering-hydration-mismatch-time — components/update-project.tsx:231
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

76. [warning] design-no-redundant-size-axes — components/update-project.tsx:222
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

77. [warning] rendering-hydration-mismatch-time — components/update-project.tsx:231
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

78. [warning] rendering-hydration-mismatch-time — components/update-project.tsx:274
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

79. [warning] design-no-redundant-size-axes — components/update-project.tsx:265
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

80. [warning] rendering-hydration-mismatch-time — components/update-project.tsx:274
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

81. [warning] no-react19-deprecated-apis — components/ui/label.tsx:13
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

82. [warning] no-react19-deprecated-apis — components/ui/input.tsx:8
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

83. [warning] no-react19-deprecated-apis — components/ui/form.tsx:43
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

84. [warning] no-react19-deprecated-apis — components/ui/form.tsx:44
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

85. [warning] no-react19-deprecated-apis — components/ui/form.tsx:73
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

86. [warning] no-react19-deprecated-apis — components/ui/form.tsx:87
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

87. [warning] no-react19-deprecated-apis — components/ui/form.tsx:104
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

88. [warning] no-react19-deprecated-apis — components/ui/form.tsx:126
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

89. [warning] no-react19-deprecated-apis — components/ui/form.tsx:143
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

90. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:25
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

91. [warning] design-no-redundant-size-axes — components/ui/dropdown-menu.tsx:41
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

92. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:47
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

93. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:63
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

94. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:82
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

95. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:100
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

96. [warning] design-no-redundant-size-axes — components/ui/dropdown-menu.tsx:113
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)

97. [warning] design-no-redundant-size-axes — components/ui/dropdown-menu.tsx:115
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

98. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:124
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

99. [warning] design-no-redundant-size-axes — components/ui/dropdown-menu.tsx:136
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)

100. [warning] design-no-redundant-size-axes — components/ui/dropdown-menu.tsx:138
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

101. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:146
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

102. [warning] no-react19-deprecated-apis — components/ui/dropdown-menu.tsx:164
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

103. [warning] js-hoist-intl — lib/utils.ts:58
new Intl.NumberFormat() inside a function — hoist to module scope or wrap in useMemo so it isn't recreated each call

104. [warning] no-react19-deprecated-apis — components/ui/toast.tsx:10
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

105. [warning] no-react19-deprecated-apis — components/ui/toast.tsx:41
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

106. [warning] no-react19-deprecated-apis — components/ui/toast.tsx:56
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

107. [warning] no-react19-deprecated-apis — components/ui/toast.tsx:71
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

108. [warning] design-no-redundant-size-axes — components/ui/toast.tsx:84
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

109. [warning] no-react19-deprecated-apis — components/ui/toast.tsx:89
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

110. [warning] no-react19-deprecated-apis — components/ui/toast.tsx:101
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

111. [warning] no-react19-deprecated-apis — components/ui/dialog.tsx:21
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

112. [warning] no-react19-deprecated-apis — components/ui/dialog.tsx:36
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

113. [warning] design-no-redundant-size-axes — components/ui/dialog.tsx:52
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

114. [warning] no-react19-deprecated-apis — components/ui/dialog.tsx:88
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

115. [warning] no-react19-deprecated-apis — components/ui/dialog.tsx:103
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

116. [warning] design-no-default-tailwind-palette — app/(application)/dashboard/page.tsx:26
text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

117. [warning] no-react19-deprecated-apis — components/ui/checkbox.tsx:9
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

118. [warning] design-no-redundant-size-axes — components/ui/checkbox.tsx:24
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

119. [warning] heading-has-content — components/ui/card.tsx:36
Headings must have content and the content must be accessible by a screen reader.

120. [warning] no-react19-deprecated-apis — components/ui/card.tsx:5
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

121. [warning] no-react19-deprecated-apis — components/ui/card.tsx:20
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

122. [warning] no-react19-deprecated-apis — components/ui/card.tsx:32
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

123. [warning] no-react19-deprecated-apis — components/ui/card.tsx:44
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

124. [warning] no-react19-deprecated-apis — components/ui/card.tsx:56
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

125. [warning] no-react19-deprecated-apis — components/ui/card.tsx:64
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

126. [warning] design-no-redundant-size-axes — components/ui/calendar.tsx:63
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

127. [warning] design-no-redundant-size-axes — components/ui/calendar.tsx:64
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
```

---

### ❌ Errors (3)

**`rules-of-hooks`**

React Hook "useToast" is called conditionally. React Hooks must be called in the exact same order in every component render.

> Move the Hook call before the condition, or call it unconditionally and branch inside the Hook/effect instead.

[`components/uploadbanner.tsx:24`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/uploadbanner.tsx#L24)
[`components/uploadbanner.tsx:26`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/uploadbanner.tsx#L26)

**`jsx-key`**

Missing "key" prop for element in iterator.

> Add a "key" prop to the element in the iterator (https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key).

[`app/page.tsx:40`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/page.tsx#L40)

---

### ⚠️ Warnings (124)

**`no-react19-deprecated-apis`**

forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

> Pass `ref` as a regular prop on function components — `forwardRef` is no longer needed in React 19+. Replace `useContext(X)` with `use(X)` for branch-aware context reads. Only enabled on projects detected as React 19+.

[`components/ui/button.tsx:43`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/button.tsx#L43)
[`components/ui/avatar.tsx:8`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/avatar.tsx#L8)
[`components/ui/avatar.tsx:23`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/avatar.tsx#L23)
[`components/ui/avatar.tsx:35`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/avatar.tsx#L35)
[`components/ui/alert-dialog.tsx:21`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/alert-dialog.tsx#L21)
[`components/ui/alert-dialog.tsx:36`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/alert-dialog.tsx#L36)
[`components/ui/alert-dialog.tsx:82`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/alert-dialog.tsx#L82)
[`components/ui/alert-dialog.tsx:94`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/alert-dialog.tsx#L94)
[`components/ui/alert-dialog.tsx:107`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/alert-dialog.tsx#L107)
[`components/ui/alert-dialog.tsx:119`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/alert-dialog.tsx#L119)
[`components/ui/accordion.tsx:11`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/accordion.tsx#L11)
[`components/ui/accordion.tsx:23`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/accordion.tsx#L23)
[`components/ui/accordion.tsx:43`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/accordion.tsx#L43)
[`components/ui/table.tsx:5`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L5)
[`components/ui/table.tsx:19`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L19)
[`components/ui/table.tsx:27`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L27)
[`components/ui/table.tsx:39`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L39)
[`components/ui/table.tsx:51`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L51)
[`components/ui/table.tsx:66`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L66)
[`components/ui/table.tsx:81`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L81)
[`components/ui/table.tsx:96`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/table.tsx#L96)
[`components/ui/separator.tsx:8`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/separator.tsx#L8)
[`components/ui/select.tsx:15`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L15)
[`components/ui/select.tsx:35`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L35)
[`components/ui/select.tsx:65`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L65)
[`components/ui/select.tsx:77`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L77)
[`components/ui/select.tsx:99`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L99)
[`components/ui/scroll-area.tsx:8`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/scroll-area.tsx#L8)
[`components/ui/scroll-area.tsx:26`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/scroll-area.tsx#L26)
[`components/ui/popover.tsx:14`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/popover.tsx#L14)
[`components/ui/label.tsx:13`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/label.tsx#L13)
[`components/ui/input.tsx:8`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/input.tsx#L8)
[`components/ui/form.tsx:43`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/form.tsx#L43)
[`components/ui/form.tsx:44`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/form.tsx#L44)
[`components/ui/form.tsx:73`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/form.tsx#L73)
[`components/ui/form.tsx:87`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/form.tsx#L87)
[`components/ui/form.tsx:104`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/form.tsx#L104)
[`components/ui/form.tsx:126`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/form.tsx#L126)
[`components/ui/form.tsx:143`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/form.tsx#L143)
[`components/ui/dropdown-menu.tsx:25`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L25)
[`components/ui/dropdown-menu.tsx:47`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L47)
[`components/ui/dropdown-menu.tsx:63`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L63)
[`components/ui/dropdown-menu.tsx:82`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L82)
[`components/ui/dropdown-menu.tsx:100`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L100)
[`components/ui/dropdown-menu.tsx:124`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L124)
[`components/ui/dropdown-menu.tsx:146`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L146)
[`components/ui/dropdown-menu.tsx:164`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L164)
[`components/ui/toast.tsx:10`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/toast.tsx#L10)
[`components/ui/toast.tsx:41`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/toast.tsx#L41)
[`components/ui/toast.tsx:56`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/toast.tsx#L56)
[`components/ui/toast.tsx:71`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/toast.tsx#L71)
[`components/ui/toast.tsx:89`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/toast.tsx#L89)
[`components/ui/toast.tsx:101`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/toast.tsx#L101)
[`components/ui/dialog.tsx:21`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dialog.tsx#L21)
[`components/ui/dialog.tsx:36`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dialog.tsx#L36)
[`components/ui/dialog.tsx:88`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dialog.tsx#L88)
[`components/ui/dialog.tsx:103`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dialog.tsx#L103)
[`components/ui/checkbox.tsx:9`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/checkbox.tsx#L9)
[`components/ui/card.tsx:5`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/card.tsx#L5)
[`components/ui/card.tsx:20`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/card.tsx#L20)
[`components/ui/card.tsx:32`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/card.tsx#L32)
[`components/ui/card.tsx:44`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/card.tsx#L44)
[`components/ui/card.tsx:56`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/card.tsx#L56)
[`components/ui/card.tsx:64`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/card.tsx#L64)

**`design-no-redundant-size-axes`**

w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

> Collapse `w-N h-N` to `size-N` (Tailwind v3.4+) when both axes match

[`components/ui/accordion.tsx:37`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/accordion.tsx#L37)
[`components/members-table/columns/actions-col/index.tsx:42`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/columns/actions-col/index.tsx#L42)
[`components/members-table/columns/actions-col/index.tsx:44`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/columns/actions-col/index.tsx#L44)
[`components/members-table/column-header.tsx:46`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/column-header.tsx#L46)
[`components/members-table/column-header.tsx:48`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/column-header.tsx#L48)
[`components/members-table/column-header.tsx:50`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/column-header.tsx#L50)
[`components/ui/select.tsx:29`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L29)
[`components/ui/select.tsx:89`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L89)
[`components/ui/select.tsx:91`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/select.tsx#L91)
[`components/user-button.tsx:41`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/user-button.tsx#L41)
[`components/user-button.tsx:51`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/user-button.tsx#L51)
[`components/update-project.tsx:222`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/update-project.tsx#L222)
[`components/update-project.tsx:265`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/update-project.tsx#L265)
[`components/ui/dropdown-menu.tsx:41`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L41)
[`components/ui/dropdown-menu.tsx:113`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L113)
[`components/ui/dropdown-menu.tsx:115`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L115)
[`components/ui/dropdown-menu.tsx:136`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L136)
[`components/ui/dropdown-menu.tsx:138`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dropdown-menu.tsx#L138)
[`components/ui/toast.tsx:84`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/toast.tsx#L84)
[`components/ui/dialog.tsx:52`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/dialog.tsx#L52)
[`components/ui/checkbox.tsx:24`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/checkbox.tsx#L24)
[`components/ui/calendar.tsx:63`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/calendar.tsx#L63)
[`components/ui/calendar.tsx:64`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/calendar.tsx#L64)

**`react-compiler-destructure-method`**

Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

> Destructure the method up front: `const { push } = useRouter()` then call `push(...)` directly — clearer dependency graph and easier for React Compiler to memoize

[`components/create-account.tsx:63`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/create-account.tsx#L63)
[`components/checkout-card.tsx:44`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/checkout-card.tsx#L44)
[`components/project-delete.tsx:77`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/project-delete.tsx#L77)
[`components/user-button.tsx:67`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/user-button.tsx#L67)
[`components/user-button.tsx:78`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/user-button.tsx#L78)

**`no-unknown-property`**

Unknown property found

> Remove unknown property

[`app/api/projects/og/route.tsx:29`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/api/projects/og/route.tsx#L29)
[`app/api/projects/og/route.tsx:31`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/api/projects/og/route.tsx#L31)
[`app/api/projects/og/route.tsx:40`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/api/projects/og/route.tsx#L40)
[`app/api/projects/og/route.tsx:42`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/api/projects/og/route.tsx#L42)
[`app/api/projects/og/route.tsx:53`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/api/projects/og/route.tsx#L53)

**`design-no-three-period-ellipsis`**

Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

> Use the typographic ellipsis "…" (or `…`) instead of three periods — pairs with action-with-followup labels ("Rename…", "Loading…")

[`components/checkout-card.tsx:31`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/checkout-card.tsx#L31)
[`app/(application)/dashboard/projects/[id]/settings/page.tsx:78`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/(application)/dashboard/projects/[id]/settings/page.tsx#L78)
[`components/project-grid.tsx:52`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/project-grid.tsx#L52)
[`components/user-button.tsx:100`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/user-button.tsx#L100)

**`rendering-hydration-mismatch-time`**

new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

> Wrap dynamic time/random values in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

[`components/update-project.tsx:231`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/update-project.tsx#L231)
[`components/update-project.tsx:231`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/update-project.tsx#L231)
[`components/update-project.tsx:274`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/update-project.tsx#L274)
[`components/update-project.tsx:274`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/update-project.tsx#L274)

**`server-sequential-independent-await`**

Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

> Wrap independent awaits in `Promise.all([...])` so they race instead of waterfalling — second call doesn't depend on the first

[`app/(application)/dashboard/projects/[id]/page.tsx:47`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/(application)/dashboard/projects/[id]/page.tsx#L47)
[`app/page.tsx:25`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/page.tsx#L25)
[`app/(application)/settings/billing/page.tsx:65`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/(application)/settings/billing/page.tsx#L65)

**`design-no-space-on-flex-children`**

space-x-2 on a flex/grid parent — use gap-x-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL

> Use `gap-*` on the flex/grid parent. `space-x-*` / `space-y-*` produce phantom gaps when a sibling is conditionally rendered, lose vertical spacing on wrapped lines, and don't mirror in RTL

[`components/members-table/data-table/index.tsx:208`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/data-table/index.tsx#L208)
[`components/create-account.tsx:88`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/create-account.tsx#L88)

**`query-mutation-missing-invalidation`**

useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

> Add `onSuccess: () => queryClient.invalidateQueries({ queryKey: ['...'] })` so cached data stays in sync after the mutation

[`components/members-table/data-table/deliever-email-confirmation-modal.tsx:31`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/data-table/deliever-email-confirmation-modal.tsx#L31)
[`components/members-table/columns/actions-col/deliever-email-confirmation-modal.tsx:31`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/columns/actions-col/deliever-email-confirmation-modal.tsx#L31)

**`nextjs-no-img-element`**

Use next/image instead of <img> — provides automatic optimization, lazy loading, and responsive srcset

> `import Image from 'next/image'` — provides automatic WebP/AVIF, lazy loading, and responsive srcset

[`app/page.tsx:43`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/page.tsx#L43)
[`components/uploadbanner.tsx:16`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/uploadbanner.tsx#L16)

**`design-no-default-tailwind-palette`**

bg-gray-600 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

> Replace `indigo-*` / `gray-*` / `slate-*` with project tokens, your brand color, or a less-default neutral (`zinc`, `neutral`, `stone`)

[`app/page.tsx:50`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/page.tsx#L50)
[`app/(application)/dashboard/page.tsx:26`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/(application)/dashboard/page.tsx#L26)

**`no-effect-chain`**

useEffect reacts to "selectedRows" which is set by another useEffect — chains of effects add an extra render per link and become rigid as code evolves. Compute what you can during render and write all related state inside the event handler that originally fires the chain

> Compute as much as possible during render (e.g. `const isGameOver = round > 5`) and write all related state inside the event handler that originally fires the chain. Each effect link adds an extra render and makes the code rigid as requirements evolve

[`components/members-table/data-table/index.tsx:90`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/data-table/index.tsx#L90)

**`prefer-useReducer`**

Component "DataTable" has 8 useState calls — consider useReducer for related state

> Group related state: `const [state, dispatch] = useReducer(reducer, { field1, field2, ... })`

[`components/members-table/data-table/index.tsx:48`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/data-table/index.tsx#L48)

**`js-combine-iterations`**

.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

> Combine `.map().filter()` (or similar chains) into a single pass with `.reduce()` or a `for...of` loop to avoid iterating the array twice

[`components/members-table/data-table/index.tsx:134`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/members-table/data-table/index.tsx#L134)

**`async-defer-await`**

await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast

> Move the `await` after the synchronous early-return guard so the skip path stays fast

[`app/(application)/dashboard/projects/[id]/page.tsx:47`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/app/(application)/dashboard/projects/[id]/page.tsx#L47)

**`no-cascading-set-state`**

4 setState calls in a single useEffect — consider using useReducer or deriving state

> Combine into useReducer: `const [state, dispatch] = useReducer(reducer, initialState)`

[`components/theme-toggle-card.tsx:32`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/theme-toggle-card.tsx#L32)

**`async-await-in-loop`**

await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

> Collect the items and use `await Promise.all(items.map(...))` to run independent operations concurrently

[`service/project.ts:110`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/service/project.ts#L110)

**`js-hoist-intl`**

new Intl.NumberFormat() inside a function — hoist to module scope or wrap in useMemo so it isn't recreated each call

> Hoist `new Intl.NumberFormat(...)` to module scope or wrap in `useMemo` — Intl constructors allocate dozens of objects per locale lookup

[`lib/utils.ts:58`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/lib/utils.ts#L58)

**`heading-has-content`**

Headings must have content and the content must be accessible by a screen reader.

> Provide screen reader accessible content when using heading elements.

[`components/ui/card.tsx:36`](https://github.com/celeroncoder/vitas/blob/a5c4dfd2d65144b0b4b4b4cc1d3bdd52c0bcd2c2/components/ui/card.tsx#L36)

---

Last scored May 14, 2026 at 9:39 AM UTC. Maintained by [React Review](https://github.com/millionco/react-review).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.