Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe pull request applies a series of reformatting changes across the codebase. The Changes
Suggested reviewers
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (27)
apps/mail/components/create/editor-buttons.tsx (1)
149-222: AttachmentButtons Component is Intuitive
TheAttachmentButtonscomponent (lines 149–222) efficiently renders attachment counts and manages file displays with a popover. One minor suggestion from static analysis:Optional Chaining for Safety:
Consider refactoring the removal callback to use optional chaining for brevity and safety. For example:- onAttachmentRemove && onAttachmentRemove(index) + onAttachmentRemove?.(index)This refactor (in lines 186–188) reduces the chance of runtime errors if
onAttachmentRemoveis undefined.🧰 Tools
🪛 Biome (1.9.4)
[error] 187-187: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
apps/mail/components/create/editor.link-selector.tsx (1)
33-42: Simplify Autofocus useEffect and Add Dependency ArrayWithin the
LinkSelectorcomponent, the autofocus effect uses a redundant check:- useEffect(() => { - inputRef.current && inputRef.current?.focus(); - }); + useEffect(() => { + inputRef.current?.focus(); + }, []);This change improves readability and ensures the effect runs only once on mount.
🧰 Tools
🪛 Biome (1.9.4)
[error] 39-39: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
apps/mail/components/create/editor.colors.tsx (1)
104-105: Debug Logging NoticeA debug log is present:
console.log('editor', editor);It is useful for development; however, consider removing or disabling this logging in production builds.
apps/mail/components/create/editor.node-selector.tsx (1)
27-37: Items Array Formatting with a Note for Future Optimization
The items array (lines 27–37) is now formatted consistently. There is an inline comment suggesting there may be a more efficient way to handle the logic, which is a proactive note for future refinement.Consider revisiting this section in the future to evaluate performance or to simplify the logic further if possible.
apps/mail/components/home/hero.tsx (1)
48-83: Comprehensive Form Submission Logic with Visual Feedback
TheonSubmitfunction (lines 48–83) handles the form submission process comprehensively: it sets a loading state, logs progress, triggers a confetti animation on success, and resets the form. Consider verifying that the endpoint consistently returns a status of 201 for new sign-ups to ensure reliable state updates.Optionally, you might add more robust error handling or user feedback in cases where the response status deviates from the expected value.
apps/mail/components/create/editor.tsx (3)
1-17: Organized Imports and Extension Setup
The reordering and reformatting of import statements (especially fromlucide-reactandnovel) are well executed. One minor note: the extensions array is force‑cast asany[](line 56). For long‑term maintainability, it may be beneficial to investigate stronger typing if possible.
421-443: Content Initialization and Update Logic
The use of asetTimeout(with a delay of 0) to ensure that the editor is ready before setting content is a pragmatic choice given the asynchronous nature of the editor initialization. Consider exploring more robust lifecycle hooks or callbacks for future refinement.
445-457: Extending the Editor's Imperative Handle
ExtendingeditorRefusingReact.useImperativeHandleto incorporate aclearContentmethod is a neat solution. As noted earlier, further type safety improvements could be explored, but the current approach is functional and clearly documented.apps/mail/app/(full-width)/contributors/page.tsx (1)
223-245: Timeline Data GenerationThe code generating timeline data (lines 223–245) correctly computes fallback commit counts (using
Math.floor(Math.random() * 5)when no commit data is available).
Note: While using randomness for fallback data is acceptable for visual purposes, consider a deterministic approach for unit testing to avoid flakiness.apps/mail/components/context/thread-context.tsx (1)
79-95: Commented Unimplemented Logic – Consider Cleanup
There is a commented-out function forhandleArchive(lines 79–95). If this code is no longer needed or is pending future work, please consider removing or noting a TODO reference to declutter the file.apps/mail/app/(routes)/settings/notifications/page.tsx (1)
43-49: Simple and Effective onSubmit Implementation
The onSubmit function uses a simulated delay withsetTimeoutto mimic saving. While this is acceptable for demonstration purposes, consider integrating actual save logic or error handling as the application evolves.apps/mail/components/draft/drafts-list.tsx (1)
20-38: Enhance Text Highlighting with Proper Regex Escaping
ThehighlightTextfunction effectively splits the text based on the provided highlight. However, the direct use of thehighlightstring in the RegExp constructor can lead to issues if it contains special regex characters. To avoid unintended behavior, consider escaping these characters. For example:- const regex = new RegExp(`(${highlight})`, 'gi'); + const escapedHighlight = highlight.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regex = new RegExp(`(${escapedHighlight})`, 'gi');apps/mail/components/draft/drafts.tsx (1)
81-89: Remove Unnecessary Fragment – SuggestionThe fragment wrapping the search button when
!searchModeis redundant since it encloses only a single child. Removing it would simplify the JSX.-{!searchMode && ( - <> - <div className="flex items-center gap-1.5"> - <Button - variant="ghost" - className="md:h-fit md:px-2" - onClick={() => setSearchMode(true)} - onMouseEnter={() => searchIconRef.current?.startAnimation?.()} - onMouseLeave={() => searchIconRef.current?.stopAnimation?.()} - > - <SearchIcon ref={searchIconRef} className="h-4 w-4" /> - </Button> - </div> - </> -)} +{!searchMode && ( + <div className="flex items-center gap-1.5"> + <Button + variant="ghost" + className="md:h-fit md:px-2" + onClick={() => setSearchMode(true)} + onMouseEnter={() => searchIconRef.current?.startAnimation?.()} + onMouseLeave={() => searchIconRef.current?.stopAnimation?.()} + > + <SearchIcon ref={searchIconRef} className="h-4 w-4" /> + </Button> + </div> +)}apps/mail/app/(routes)/settings/security/page.tsx (1)
38-46: Form Submission Logic and TODO ReminderThe onSubmit function simulates a save operation using
setTimeoutand logs the values. The TODO comment reminds you to integrate saving logic into the user’s account. Once in production, consider replacing the simulated delay with an actual API call.apps/mail/components/home/navbar.tsx (1)
76-94: Unnecessary Fragment in Conditional Rendering – SuggestionWithin the development-mode branch, the fragment wrapping the single
<div>is unnecessary. Simplifying the JSX by removing it will improve readability.-{process.env.NODE_ENV === 'development' ? ( - <> - <div className="hidden items-center gap-4 lg:flex"> - ... // content - </div> - </> -) : ( - <Button ...>Contact Us</Button> -)} +{process.env.NODE_ENV === 'development' ? ( + <div className="hidden items-center gap-4 lg:flex"> + ... // content + </div> +) : ( + <Button ...>Contact Us</Button> +)}apps/mail/app/(routes)/settings/appearance/page.tsx (1)
20-37: Form Setup and Submission Handling – LGTMThe useForm hook is set up correctly with a zod resolver and default values. The onSubmit function uses a simulated delay to mimic saving. In the future, replace this with actual API calls to persist settings.
apps/mail/components/cookies/cookie-trigger.tsx (1)
33-43: Remove Unnecessary Fragment in Children Rendering
Static analysis indicates that the outer fragment wrapping the ternary expression is redundant. You can simplify the JSX by removing the extra<>wrapper. For example, replace:- {children || ( - <> - {variant === 'icon' ? ( - <Cookie className="h-3 w-3" /> - ) : ( - <> - <Cookie className="mr-2 h-4 w-4" /> - Cookie Settings - </> - )} - </> - )} + {children || ( + variant === 'icon' ? ( + <Cookie className="h-3 w-3" /> + ) : ( + <> + <Cookie className="mr-2 h-4 w-4" /> + Cookie Settings + </> + ) + )}This refinement reduces unnecessary JSX nesting while preserving the intended conditional rendering.
🧰 Tools
🪛 Biome (1.9.4)
[error] 33-42: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
apps/mail/app/(routes)/settings/general/page.tsx (2)
38-72: Well-Structured Form Logic with a Clear TODO.
The form initialization and submission logic (lines 38–72) are implemented correctly. Notably, the TODO comment regarding saving the settings highlights an area for future work. Please ensure that persistent saving logic is added prior to production deployment.
74-186: Clear and Organized UI Rendering.
The returned JSX (lines 74–186) is cleanly structured, and the updates to the component’s formatting make it more maintainable. There’s a TODO note on adding all timezones (around line 116)—remember to address this when you extend timezone support.apps/mail/app/(auth)/login/login-client.tsx (2)
59-97: Robust Login Client Implementation.
TheLoginClientcomponent (lines 59–97) manages authentication states and provider logic effectively. One minor suggestion: in the condition that checks for an active session, consider using optional chaining for cleaner syntax.
98-98: Optional Chaining Improvement.
Refactor the session check to use optional chaining for clarity and safety. For example, update-if (isPending || (session && session.connectionId)) return null; +if (isPending || session?.connectionId) return null;This small change improves readability while maintaining the same logic.
🧰 Tools
🪛 Biome (1.9.4)
[error] 98-98: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
apps/mail/components/create/uploaded-file-icon.tsx (1)
35-67: Well-FormattedUploadedFileIconComponent
The JSX structure and conditional rendering within the component have been reformatted to improve clarity. One suggestion: since you are usingURL.createObjectURL(file)to generate an image source, consider revoking the object URL (usingURL.revokeObjectURL) when the component unmounts to prevent potential memory leaks if many images are rendered.apps/mail/components/icons/animated/align-vertical.tsx (1)
41-124: Solid Animation Control in the Component
TheAlignVerticalSpaceAroundIconcomponent correctly implements the imperative handle pattern usinguseImperativeHandle,useAnimation, anduseCallback. The separation of mouse event logic (with conditional checks onisControlledRef) is well-structured.
A minor suggestion: if similar animation control patterns appear across your icon components, consider abstracting that logic into a custom hook to reduce duplication and improve maintainability.apps/mail/components/icons/animated/moon.tsx (1)
27-87: Consistent and ReadableMoonIconComponent
The component correctly usesforwardRef,useAnimation,useImperativeHandle, anduseCallbackfor handling animations and events.
A suggestion: If you find that the animation handling logic is repeated in multiple icon components, consider refactoring this common logic into a shared custom hook to enhance maintainability.apps/mail/components/icons/animated/bell.tsx (1)
18-29: Well-Structured Animation Control inBellIconComponent
The Bell icon component leveragesforwardRef,useAnimation, and conditional mouse event handling. The formatting adjustments enhance readability while the logic remains intact.
A minor suggestion similar to other animated icons: consider abstracting common animation control hooks if you anticipate further reuse across components.apps/mail/app/(auth)/login/early-access/page.tsx (1)
69-101: Confetti Animation LogicThe confetti animation triggered when verification is achieved is implemented efficiently with a setInterval and proper cleanup via clearInterval. One minor consideration: the literal values (e.g., duration and particle count factor) could be extracted into constants for future maintainability.
apps/mail/components/create/ai-chat.tsx (1)
26-69: Custom Hook: useAutoResizeTextarea ImplementationThe custom hook effectively manages the dynamic resizing of a textarea based on its scroll height. The use of
useCallbackto memoize the height adjustment function, coupled with initial setup in a useEffect and a window resize listener, is solid.
Consideration: If any flickering is observed during rendering, switching touseLayoutEffectfor DOM measurements might provide a smoother experience.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (83)
.prettierrc(1 hunks)apps/mail/app/(auth)/login/early-access/page.tsx(1 hunks)apps/mail/app/(auth)/login/login-client.tsx(1 hunks)apps/mail/app/(auth)/login/page.tsx(1 hunks)apps/mail/app/(auth)/zero/login/page.tsx(1 hunks)apps/mail/app/(auth)/zero/signup/page.tsx(1 hunks)apps/mail/app/(error)/not-found.tsx(1 hunks)apps/mail/app/(full-width)/contributors/page.tsx(2 hunks)apps/mail/app/(full-width)/layout.tsx(1 hunks)apps/mail/app/(full-width)/privacy/page.tsx(1 hunks)apps/mail/app/(full-width)/terms/page.tsx(1 hunks)apps/mail/app/(routes)/create/layout.tsx(1 hunks)apps/mail/app/(routes)/create/page.tsx(1 hunks)apps/mail/app/(routes)/developer/page.tsx(1 hunks)apps/mail/app/(routes)/layout.tsx(1 hunks)apps/mail/app/(routes)/mail/[folder]/page.tsx(1 hunks)apps/mail/app/(routes)/mail/create/page.tsx(1 hunks)apps/mail/app/(routes)/mail/draft/page.tsx(1 hunks)apps/mail/app/(routes)/mail/layout.tsx(1 hunks)apps/mail/app/(routes)/mail/page.tsx(1 hunks)apps/mail/app/(routes)/mail/under-construction/[path]/back-button.tsx(1 hunks)apps/mail/app/(routes)/mail/under-construction/[path]/page.tsx(1 hunks)apps/mail/app/(routes)/settings/[...settings]/page.tsx(1 hunks)apps/mail/app/(routes)/settings/appearance/page.tsx(1 hunks)apps/mail/app/(routes)/settings/connections/page.tsx(2 hunks)apps/mail/app/(routes)/settings/general/page.tsx(2 hunks)apps/mail/app/(routes)/settings/layout.tsx(1 hunks)apps/mail/app/(routes)/settings/notifications/page.tsx(2 hunks)apps/mail/app/(routes)/settings/security/page.tsx(2 hunks)apps/mail/app/(routes)/settings/shortcuts/page.tsx(1 hunks)apps/mail/app/api/og/home/route.tsx(1 hunks)apps/mail/app/error.tsx(1 hunks)apps/mail/app/global-error.tsx(1 hunks)apps/mail/app/layout.tsx(1 hunks)apps/mail/app/page.tsx(1 hunks)apps/mail/components/connection/add.tsx(2 hunks)apps/mail/components/context/command-palette-context.tsx(2 hunks)apps/mail/components/context/sidebar-context.tsx(1 hunks)apps/mail/components/context/thread-context.tsx(2 hunks)apps/mail/components/cookies/cookie-dialog.tsx(2 hunks)apps/mail/components/cookies/cookie-trigger.tsx(1 hunks)apps/mail/components/cookies/toggle.tsx(1 hunks)apps/mail/components/create/ai-assistant.tsx(1 hunks)apps/mail/components/create/ai-chat.tsx(2 hunks)apps/mail/components/create/ai-textarea.tsx(1 hunks)apps/mail/components/create/create-email.tsx(1 hunks)apps/mail/components/create/editor-buttons.tsx(1 hunks)apps/mail/components/create/editor-menu.tsx(1 hunks)apps/mail/components/create/editor.colors.tsx(1 hunks)apps/mail/components/create/editor.link-selector.tsx(1 hunks)apps/mail/components/create/editor.node-selector.tsx(2 hunks)apps/mail/components/create/editor.text-buttons.tsx(1 hunks)apps/mail/components/create/editor.tsx(2 hunks)apps/mail/components/create/selectors/link-selector.tsx(1 hunks)apps/mail/components/create/selectors/math-selector.tsx(1 hunks)apps/mail/components/create/selectors/node-selector.tsx(2 hunks)apps/mail/components/create/selectors/text-buttons.tsx(1 hunks)apps/mail/components/create/slash-command.tsx(1 hunks)apps/mail/components/create/uploaded-file-icon.tsx(1 hunks)apps/mail/components/draft/drafts-list.tsx(1 hunks)apps/mail/components/draft/drafts.tsx(1 hunks)apps/mail/components/home/footer.tsx(1 hunks)apps/mail/components/home/hero-image.tsx(1 hunks)apps/mail/components/home/hero.tsx(1 hunks)apps/mail/components/home/navbar.tsx(1 hunks)apps/mail/components/icons/animated/align-vertical.tsx(1 hunks)apps/mail/components/icons/animated/archive.tsx(1 hunks)apps/mail/components/icons/animated/arrow-left.tsx(1 hunks)apps/mail/components/icons/animated/bell.tsx(1 hunks)apps/mail/components/icons/animated/book-text.tsx(1 hunks)apps/mail/components/icons/animated/cart.tsx(1 hunks)apps/mail/components/icons/animated/check-check.tsx(1 hunks)apps/mail/components/icons/animated/expand.tsx(1 hunks)apps/mail/components/icons/animated/filter.tsx(1 hunks)apps/mail/components/icons/animated/inbox.tsx(1 hunks)apps/mail/components/icons/animated/keyboard.tsx(1 hunks)apps/mail/components/icons/animated/message-square.tsx(1 hunks)apps/mail/components/icons/animated/message.tsx(1 hunks)apps/mail/components/icons/animated/moon.tsx(1 hunks)apps/mail/components/icons/animated/more-vertical.tsx(1 hunks)apps/mail/components/icons/animated/reply.tsx(1 hunks)apps/mail/components/icons/animated/search.tsx(1 hunks)apps/mail/components/icons/animated/settings-gear.tsx(1 hunks)
🧰 Additional context used
🧬 Code Definitions (39)
apps/mail/app/(routes)/mail/layout.tsx (2)
apps/mail/components/ui/app-sidebar.tsx (1) (1)
AppSidebar(23-123)apps/mail/components/mail/keyboard-shortcuts.tsx (1) (1)
KeyboardShortcuts(8-23)
apps/mail/app/(routes)/create/layout.tsx (1)
apps/mail/components/ui/app-sidebar.tsx (1) (1)
AppSidebar(23-123)
apps/mail/app/(routes)/layout.tsx (2)
apps/mail/components/context/command-palette-context.tsx (1) (1)
CommandPaletteProvider(210-216)apps/mail/lib/idb.ts (1) (1)
dexieStorageProvider(24-67)
apps/mail/components/create/selectors/link-selector.tsx (1)
apps/mail/components/create/editor.link-selector.tsx (3) (3)
getUrlFromString(18-27)isValidUrl(10-17)LinkSelector(33-96)
apps/mail/components/cookies/toggle.tsx (3)
apps/mail/lib/cookies.ts (1) (1)
CookieCategory(3-3)apps/mail/hooks/use-geo-location.ts (1) (1)
useGeoLocation(3-19)apps/mail/actions/cookies.ts (1) (1)
updateCookiePreferences(34-52)
apps/mail/components/create/selectors/text-buttons.tsx (1)
apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/app/(routes)/mail/create/page.tsx (1)
apps/mail/components/create/create-email.tsx (1) (1)
CreateEmail(20-498)
apps/mail/app/(full-width)/terms/page.tsx (5)
apps/mail/hooks/use-copy-to-clipboard.ts (1) (1)
useCopyToClipboard(4-18)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/ui/card.tsx (3) (3)
Card(55-55)CardHeader(55-55)CardTitle(55-55)apps/mail/lib/utils.ts (1) (1)
createSectionId(141-143)apps/mail/components/home/footer.tsx (1) (1)
Footer(29-88)
apps/mail/app/(routes)/mail/page.tsx (2)
apps/mail/components/mail/mail.tsx (1) (1)
MailLayout(196-407)apps/mail/app/(routes)/mail/layout.tsx (1) (1)
MailLayout(4-12)
apps/mail/components/home/hero.tsx (5)
apps/mail/components/ui/card.tsx (2) (2)
Card(55-55)CardContent(55-55)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/ui/form.tsx (4) (4)
Form(163-163)FormField(169-169)FormItem(164-164)FormControl(166-166)apps/mail/components/ui/input.tsx (1) (1)
Input(31-31)apps/mail/components/ui/animated-number.tsx (1) (1)
AnimatedNumber(13-29)
apps/mail/components/create/editor.link-selector.tsx (3)
apps/mail/components/create/selectors/link-selector.tsx (3) (3)
getUrlFromString(18-27)isValidUrl(10-17)LinkSelector(33-103)apps/mail/components/ui/popover.tsx (3) (3)
Popover(31-31)PopoverTrigger(31-31)PopoverContent(31-31)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/app/(routes)/settings/layout.tsx (4)
apps/mail/components/ui/app-sidebar.tsx (1) (1)
AppSidebar(23-123)apps/mail/components/ui/resizable.tsx (2) (2)
ResizablePanelGroup(42-42)ResizablePanel(42-42)apps/mail/components/ui/sidebar-toggle.tsx (1) (1)
SidebarToggle(10-18)apps/mail/components/ui/scroll-area.tsx (1) (1)
ScrollArea(42-42)
apps/mail/app/(full-width)/privacy/page.tsx (4)
apps/mail/hooks/use-copy-to-clipboard.ts (1) (1)
useCopyToClipboard(4-18)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/ui/card.tsx (3) (3)
Card(55-55)CardHeader(55-55)CardTitle(55-55)apps/mail/lib/utils.ts (1) (1)
createSectionId(141-143)
apps/mail/components/create/selectors/node-selector.tsx (3)
apps/mail/components/create/editor.node-selector.tsx (2) (2)
SelectorItem(20-25)NodeSelector(93-133)apps/mail/components/ui/popover.tsx (3) (3)
Popover(31-31)PopoverTrigger(31-31)PopoverContent(31-31)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/components/connection/add.tsx (3)
apps/mail/components/ui/dialog.tsx (6) (6)
Dialog(89-89)DialogTrigger(93-93)DialogContent(94-94)DialogHeader(95-95)DialogTitle(97-97)DialogDescription(98-98)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/lib/constants.ts (1) (1)
emailProviders(100-106)
apps/mail/components/create/editor.tsx (9)
apps/mail/components/ui/separator.tsx (1) (1)
Separator(26-26)apps/mail/components/ui/popover.tsx (3) (3)
Popover(31-31)PopoverTrigger(31-31)PopoverContent(31-31)apps/mail/components/create/uploaded-file-icon.tsx (1) (1)
UploadedFileIcon(35-67)apps/mail/lib/utils.ts (1) (1)
truncateFileName(112-119)apps/mail/components/ui/dialog.tsx (6) (6)
Dialog(89-89)DialogContent(94-94)DialogHeader(95-95)DialogTitle(97-97)DialogDescription(98-98)DialogFooter(96-96)apps/mail/components/ui/input.tsx (1) (1)
Input(31-31)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/create/slash-command.tsx (1) (1)
suggestionItems(19-75)apps/mail/components/create/editor-menu.tsx (1) (1)
EditorMenu(12-34)
apps/mail/app/page.tsx (5)
apps/mail/components/ui/skeleton.tsx (1) (1)
Skeleton(7-7)apps/mail/components/home/navbar.tsx (1) (1)
Navbar(10-103)apps/mail/components/home/hero.tsx (1) (1)
Hero(23-189)apps/mail/components/mail/mail.tsx (1) (1)
DemoMailLayout(53-194)apps/mail/components/home/footer.tsx (1) (1)
Footer(29-88)
apps/mail/app/(routes)/settings/shortcuts/page.tsx (2)
apps/mail/config/shortcuts.ts (1) (1)
keyboardShortcuts(2-24)apps/mail/components/settings/settings-card.tsx (1) (1)
SettingsCard(11-33)
apps/mail/app/(routes)/settings/notifications/page.tsx (5)
apps/mail/components/settings/settings-card.tsx (1) (1)
SettingsCard(11-33)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/ui/form.tsx (6) (6)
Form(163-163)FormField(169-169)FormItem(164-164)FormLabel(165-165)FormControl(166-166)FormDescription(167-167)apps/mail/components/ui/select.tsx (5) (5)
Select(143-143)SelectTrigger(146-146)SelectValue(145-145)SelectContent(147-147)SelectItem(149-149)apps/mail/components/ui/switch.tsx (1) (1)
Switch(36-36)
apps/mail/components/cookies/cookie-trigger.tsx (1)
apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/components/context/sidebar-context.tsx (4)
apps/mail/components/ui/sidebar.tsx (1) (1)
SidebarProvider(605-605)apps/mail/hooks/use-mobile.tsx (1) (1)
useIsMobile(5-19)apps/mail/lib/utils.ts (1) (1)
getCookie(58-63)apps/mail/components/ui/tooltip.tsx (1) (1)
TooltipProvider(59-59)
apps/mail/app/(routes)/settings/connections/page.tsx (7)
apps/mail/components/settings/settings-card.tsx (1) (1)
SettingsCard(11-33)apps/mail/components/ui/skeleton.tsx (1) (1)
Skeleton(7-7)apps/mail/lib/constants.ts (1) (1)
emailProviders(100-106)apps/mail/components/ui/tooltip.tsx (3) (3)
Tooltip(59-59)TooltipTrigger(59-59)TooltipContent(59-59)apps/mail/components/ui/dialog.tsx (7) (7)
Dialog(89-89)DialogTrigger(93-93)DialogContent(94-94)DialogHeader(95-95)DialogTitle(97-97)DialogDescription(98-98)DialogClose(92-92)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/connection/add.tsx (1) (1)
AddConnectionDialog(16-94)
apps/mail/app/(routes)/settings/appearance/page.tsx (2)
apps/mail/components/settings/settings-card.tsx (1) (1)
SettingsCard(11-33)apps/mail/components/theme/theme-switcher.tsx (1) (1)
ModeToggle(21-91)
apps/mail/components/home/footer.tsx (2)
apps/mail/components/icons/icons.tsx (2) (2)
Discord(30-38)apps/mail/components/theme/theme-toggle.tsx (1) (1)
ThemeToggle(13-47)
apps/mail/app/(auth)/zero/login/page.tsx (3)
apps/mail/components/ui/form.tsx (5) (5)
Form(163-163)FormField(169-169)FormItem(164-164)FormLabel(165-165)FormControl(166-166)apps/mail/components/ui/input.tsx (1) (1)
Input(31-31)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/components/context/command-palette-context.tsx (3)
apps/mail/types/index.ts (1) (1)
NavItem(13-19)apps/mail/components/ui/command.tsx (8) (8)
CommandDialog(140-140)CommandInput(143-143)CommandList(145-145)CommandEmpty(141-141)CommandGroup(142-142)CommandItem(144-144)CommandShortcut(147-147)CommandSeparator(146-146)apps/mail/components/ui/dialog.tsx (2) (2)
DialogTitle(97-97)DialogDescription(98-98)
apps/mail/app/(routes)/settings/security/page.tsx (4)
apps/mail/components/settings/settings-card.tsx (1) (1)
SettingsCard(11-33)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/ui/form.tsx (6) (6)
Form(163-163)FormField(169-169)FormItem(164-164)FormLabel(165-165)FormDescription(167-167)FormControl(166-166)apps/mail/components/ui/switch.tsx (1) (1)
Switch(36-36)
apps/mail/app/(auth)/login/page.tsx (2)
apps/mail/lib/auth-providers.ts (3) (3)
authProviders(29-79)isProviderEnabled(81-92)customProviders(18-27)apps/mail/app/(auth)/login/login-client.tsx (1) (1)
LoginClient(59-354)
apps/mail/app/(routes)/settings/[...settings]/page.tsx (6)
apps/mail/app/(routes)/settings/general/page.tsx (1) (1)
GeneralPage(38-186)apps/mail/app/(routes)/settings/connections/page.tsx (1) (1)
ConnectionsPage(27-179)apps/mail/app/(routes)/settings/security/page.tsx (1) (1)
SecurityPage(26-109)apps/mail/app/(routes)/settings/appearance/page.tsx (1) (1)
AppearancePage(20-63)apps/mail/app/(routes)/settings/shortcuts/page.tsx (1) (1)
ShortcutsPage(10-36)apps/mail/app/(routes)/settings/notifications/page.tsx (1) (1)
NotificationsPage(32-118)
apps/mail/components/create/editor.colors.tsx (2)
apps/mail/components/ui/popover.tsx (3) (3)
Popover(31-31)PopoverTrigger(31-31)PopoverContent(31-31)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/components/create/create-email.tsx (3)
apps/mail/actions/drafts.ts (2) (2)
getDraft(35-49)createDraft(22-33)apps/mail/components/create/editor.tsx (1) (1)
Editor(373-587)apps/mail/components/create/ai-assistant.tsx (1) (1)
AIAssistant(210-478)
apps/mail/app/(routes)/mail/draft/page.tsx (1)
apps/mail/components/draft/drafts.tsx (1) (1)
DraftsLayout(22-151)
apps/mail/app/(routes)/create/page.tsx (1)
apps/mail/components/create/create-email.tsx (1) (1)
CreateEmail(20-498)
apps/mail/components/create/ai-assistant.tsx (2)
apps/mail/lib/ai.ts (1) (1)
generateConversationId(16-18)apps/mail/actions/ai.ts (1) (1)
generateAIEmailContent(18-66)
apps/mail/components/cookies/cookie-dialog.tsx (9)
apps/mail/providers/cookie-provider.tsx (1) (1)
useCookies(138-144)apps/mail/components/cookies/cookie-trigger.tsx (1) (1)
CookieTrigger(12-46)apps/mail/components/ui/dialog.tsx (6) (6)
Dialog(89-89)DialogTrigger(93-93)DialogContent(94-94)DialogHeader(95-95)DialogTitle(97-97)DialogDescription(98-98)apps/mail/components/ui/accordion.tsx (4) (4)
Accordion(54-54)AccordionItem(54-54)AccordionTrigger(54-54)AccordionContent(54-54)apps/mail/lib/cookies.ts (2) (2)
COOKIE_CATEGORIES(19-45)CookieCategory(3-3)apps/mail/components/ui/label.tsx (1) (1)
Label(21-21)apps/mail/components/ui/switch.tsx (1) (1)
Switch(36-36)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/ui/card.tsx (1) (1)
Card(55-55)
apps/mail/components/draft/drafts.tsx (6)
apps/mail/components/ui/tooltip.tsx (4) (4)
TooltipProvider(59-59)Tooltip(59-59)TooltipTrigger(59-59)TooltipContent(59-59)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/icons/animated/x.tsx (1) (1)
XIcon(92-92)apps/mail/components/icons/animated/search.tsx (1) (1)
SearchIcon(88-88)apps/mail/components/ui/skeleton.tsx (1) (1)
Skeleton(7-7)apps/mail/components/draft/drafts-list.tsx (1) (1)
DraftsList(102-400)
apps/mail/app/(auth)/zero/signup/page.tsx (3)
apps/mail/components/ui/form.tsx (5) (5)
Form(163-163)FormField(169-169)FormItem(164-164)FormLabel(165-165)FormControl(166-166)apps/mail/components/ui/input.tsx (1) (1)
Input(31-31)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/components/create/ai-chat.tsx (2)
apps/mail/components/create/ai-textarea.tsx (1) (1)
AITextarea(24-24)apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)
apps/mail/app/(full-width)/contributors/page.tsx (8)
apps/mail/components/ui/button.tsx (1) (1)
Button(55-55)apps/mail/components/theme/theme-toggle.tsx (1) (1)
ThemeToggle(13-47)apps/mail/components/ui/separator.tsx (1) (1)
Separator(26-26)apps/mail/components/ui/card.tsx (1) (1)
Card(55-55)apps/mail/components/ui/tooltip.tsx (1) (1)
Tooltip(59-59)apps/mail/components/ui/avatar.tsx (3) (3)
Avatar(47-47)AvatarImage(47-47)AvatarFallback(47-47)apps/mail/components/icons/icons.tsx (2) (2)
Discord(30-38)apps/mail/components/ui/tabs.tsx (4) (4)
Tabs(55-55)TabsList(55-55)TabsTrigger(55-55)TabsContent(55-55)
🪛 Biome (1.9.4)
apps/mail/components/create/editor-buttons.tsx
[error] 187-187: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
apps/mail/components/create/editor.link-selector.tsx
[error] 39-39: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
apps/mail/app/(auth)/login/login-client.tsx
[error] 98-98: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
apps/mail/components/cookies/cookie-trigger.tsx
[error] 33-42: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
apps/mail/components/draft/drafts.tsx
[error] 82-120: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (293)
apps/mail/app/(full-width)/layout.tsx (1)
2-2: Consistent Indentation Adjustment.
The return statement’s indentation has been updated to use 2 spaces per our new formatting standard (as enforced by the updated.prettierrc). This is a cosmetic change that improves readability without impacting functionality.apps/mail/app/(routes)/mail/draft/page.tsx (1)
4-4: JSX Indentation Standardized.
The return statement in theMailPagecomponent has been reformatted with a consistent two-space indentation. This aligns with the overall project style and does not alter the component’s behavior..prettierrc (1)
3-3: Indentation Configuration Update.
Updating"useTabs": falseenforces space-based indentation throughout the codebase, ensuring consistency with the recently reformatted files.apps/mail/app/(routes)/mail/page.tsx (1)
4-10: Enhanced JSX Formatting in Mail Page.
The nested JSX structure has been reformatted using consistent two-space indentation. This cosmetic improvement aids readability and maintains the original functional layout.apps/mail/app/(routes)/mail/layout.tsx (1)
5-11: Refined Component Layout Formatting.
TheMailLayoutcomponent’s return block now uses uniform two-space indentation, which improves clarity and consistency across the codebase. There are no functional changes in this update.apps/mail/app/global-error.tsx (1)
5-15: Improved JSX Indentation for Enhanced Readability
The updated indentation of the<html>and<body>elements (and the nested<NextError>component) provides a clearer structure and aligns with the updated Prettier configuration. No functional changes were introduced.apps/mail/app/(routes)/layout.tsx (1)
8-23: Consistent Formatting in Layout Component
The re-indented return statement and nested components (using theCommandPaletteProviderandSWRConfig) improve readability and maintainability. The logic remains unchanged, and the conditional provider setup is clear.apps/mail/components/home/hero-image.tsx (1)
4-16: Refined JSX Structure in HeroImage Component
The adjusted indentation and alignment of the<div>and<Image>components yield a cleaner and more uniform layout. These cosmetic changes align with the updated code style guidelines without affecting functionality.apps/mail/components/create/ai-textarea.tsx (1)
8-20: Standardized Indentation in AITextarea’s Arrow Function
The reformatted function body—with its consistent spacing and proper indentations for thetextareaelement—improves code clarity and adheres to the updated styling standards. The component’s behavior remains intact.apps/mail/app/(routes)/mail/under-construction/[path]/back-button.tsx (1)
8-18: Uniform Formatting in BackButton Component
Switching the code from tab-based to space-based indentation results in a neat and consistent style. The logic for usinguseRouteralong with the button’s click handler remains correct and easy to follow.apps/mail/app/page.tsx (1)
10-30: Consistent JSX Formatting in Home Component
The reformatting of the JSX structure (lines 10–30) improves readability without changing functionality. All components (e.g., Navbar, Hero, DemoMailLayout, HeroImage, and Footer) remain well organized. Ensure that any integration regarding the mass unsubscribe dialog (as per the PR objectives) is reflected in the appropriate component elsewhere.apps/mail/components/create/selectors/link-selector.tsx (3)
10-17: Clean URL Validation Utility
TheisValidUrlfunction now uses an underscore for the unused error variable in the catch block—this is a good practice to avoid lint warnings and indicate intentional omission.
18-27: Robust URL Parsing with Graceful Fallback
ThegetUrlFromStringfunction properly validates and constructs URLs. Using an underscore for the error parameter in the catch block is consistent and keeps the code clean.
33-102: Enhanced LinkSelector User Experience
TheLinkSelectorcomponent now includes improvements such as auto-closing the popover upon successfully setting or unsetting a link and clearing the input where needed. The changes lead to a smoother UX while preserving the original functionality.apps/mail/app/layout.tsx (1)
15-62: Uniform Layout Reformatting
Reformatting in the layout file (lines 15–62) has standardized the indentation and improved the overall readability of the configuration constants and theRootLayoutfunction. No behavioral changes have been introduced.apps/mail/app/error.tsx (2)
7-9: Proper Error Logging
TheuseEffect(lines 7–9) continues to appropriately log errors to the console. The formatting adjustments enhance clarity without affecting functionality.
11-29: Clear and Accessible Error Display
The JSX structure (lines 11–29) for error presentation is clean and well-organized, clearly separating the error message and the retry button. This makes the component easier to maintain and understand.apps/mail/components/create/editor-buttons.tsx (3)
9-140: Well-Formatted MenuBar Implementation
The MenuBar component (lines 9–140) has been reformatted for readability. Its logic (for toggling formatting options such as Bold, Italic, Heading levels, and more) remains intact and clear.
142-148: AttachmentButtons Props Interface Clarity
The props interface forAttachmentButtonsis clearly defined (lines 142–148), ensuring that any file attachment logic will have proper type guarantees.
224-227: Clean EditorProvider Integration
The default export wrapping the editor content with<EditorProvider>and the custom MenuBar (lines 224–227) is concise and maintains proper component hierarchy.apps/mail/app/(error)/not-found.tsx (1)
8-44: Consistent Formatting and Readability ImprovementThe reformatting changes—including adjusted indentation and spacing—improve the readability of the NotFound component without impacting its functionality. The usage of
useRouteranduseTranslationsis correct and remains clear.apps/mail/components/context/sidebar-context.tsx (4)
3-9: Consistent Import FormattingThe import block now uses space indentation (per the updated
.prettierrcsettings), which enhances clarity and consistency. No functional changes are introduced here.
15-23: Improved SidebarContext Type DeclarationThe formatting for the
SidebarContexttype declaration is now clearer and more consistent. All property types are explicitly defined, and the overall readability has improved without affecting functionality.
27-33: Robust Custom Hook ImplementationThe
useSidebarhook retains its essential error checking and context retrieval. The formatting updates do not alter its logic, and the code remains concise and easy to follow.
36-132: Well-Structured SidebarProvider ComponentThe
SidebarProvidercomponent is implemented correctly with all necessary hooks, callbacks, and state management in place. The updated formatting—including clearer spacing and indentation—improves readability while preserving the original behavior (such as cookie management and toggling logic).apps/mail/app/(routes)/create/layout.tsx (1)
3-10: Clean and Consistent Layout FormattingThe
CreateLayoutcomponent now exhibits well-aligned indentation and spacing. The structure of the layout (rendering theAppSidebarand wrapping its children) remains functionally identical, enhancing maintainability through improved formatting.apps/mail/components/connection/add.tsx (3)
1-8: Uniform Dialog Component ImportsThe import section for dialog-related components is now consistently formatted with spaces rather than tabs. This change aligns with the global configuration and does not affect functionality.
16-24: Clear Component Props StructuringThe prop destructuring and type annotations for
AddConnectionDialogare now formatted with consistent spacing. This enhancement improves code clarity while leaving the component’s logic intact.
27-94: Well-Formatted JSX Structure for AddConnectionDialogThe JSX layout inside
AddConnectionDialog—including theDialogTrigger,DialogContent, and nested button elements—is now more readable due to the formatting refinements. The changes are purely stylistic; the dialog’s behavior remains correct.apps/mail/components/create/editor-menu.tsx (3)
6-10: Improved Interface FormattingThe
EditorMenuPropsinterface now uses consistent indentation, which enhances the clarity of the component’s API without affecting its functionality.
12-19: Effective useEffect Hook ImplementationThe
useEffecthook correctly removes AI highlights when theopenprop is false. The updated indentation makes the logic clearer, and no changes to behavior have been made.
20-34: Well-Structured JSX Return StatementThe returned JSX from the
EditorMenucomponent is now consistently indented, which improves maintainability. The component’s logic and rendering behavior remain unchanged.apps/mail/components/create/editor.link-selector.tsx (3)
10-17: Formatting & Functionality Check on URL ValidationThe
isValidUrlfunction is clear and concise. The use of a try/catch block to validate the URL works well.
19-27: Robust URL Extraction ImplementationThe
getUrlFromStringfunction’s logic is straightforward and handles error conditions appropriately with a try/catch.
43-55: JSX Structure and Popover UsageThe returned JSX for the popover, button, and link display is well structured. The conditional rendering based on the editor’s state is clear and aligns with the component’s purpose.
apps/mail/components/create/ai-assistant.tsx (3)
14-23: Enhanced Type Interface ClarityThe reformatting of the
AIAssistantPropsinterface improves readability and aligns with our style guidelines. No functional changes were introduced.
60-100: Smooth Animation VariantsThe animation configuration for container, content, input, and buttons is clearly defined. The structure is intuitive and should work well with Framer Motion.
210-478: Comprehensive AI Assistant Component LogicThe main component effectively manages AI interaction, state updates, and error handling. The use of toast notifications and the clear separation between message types (user, assistant, system) results in robust flow.
- The asynchronous
handleSubmitfunction is well structured and properly resets state on success or failure.- Error handling with
toast.erroris appropriate.Overall, the formatted code enhances readability while retaining the original functionality. Consider removing any temporary console logging (if any remain) once the feature is finalized.
apps/mail/app/(auth)/login/page.tsx (4)
5-7: Environment Variable Setup and Production FlagThe initialization of
envNodeEnvand the production flag (isProd) is concise and clear.
8-25: Provider Status Mapping ImplementationMapping over
authProvidersto calculateenvVarStatusand determining each provider’s enabled status is well implemented. The clarity in these transformations makes the code easy to follow.
27-36: Custom Providers HandlingThe mapping of
customProvidersis simple and effective, maintaining consistency with the standard provider mappings.
38-44: Consolidated Provider List for UI RenderingThe combination of custom and auth providers into a single array (
allProviders) is straightforward. The subsequent rendering via<LoginClient>benefits from this clean data structure.apps/mail/app/(routes)/mail/create/page.tsx (1)
3-10: Simple Page Wrapper for CreateEmailThe
CreatePagecomponent serves as a clean and minimal wrapper for the<CreateEmail />component. The formatting changes (indentation adjustments) align with the new space-based style without altering the component’s behavior.apps/mail/components/create/editor.colors.tsx (7)
7-9: Interface Declaration for Color Menu ItemsThe
BubbleColorMenuIteminterface is clearly defined and now formatted consistently with our guidelines.
11-48: Well-Formatted Text Colors ArrayThe
TEXT_COLORSarray is now formatted with consistent indentation. The color values and names are accurate and presented clearly.
50-87: Consistent Highlight Colors ArrayThe
HIGHLIGHT_COLORSarray follows the same formatting improvements as the text colors. The use of CSS variables for default values is maintained.
90-92: ColorSelectorProps Interface ClarityThe props interface for
ColorSelectoris succinct and correctly typed, aiding in component reusability.
94-103: Initialization and Fallback for Editor DependencyThe
ColorSelectorcomponent checks for the existence ofeditorearly and returnsnullif unavailable, which is a safe guard for runtime behavior.
107-120: Popover Trigger and Button ConsistencyThe combination of
<PopoverTrigger>and<Button>(with gap and styling) renders the current text color and highlight color correctly. The styling is consistent with the design system and leverages the utility classes effectively.
123-174: Dynamic Rendering of Color OptionsMapping over
TEXT_COLORSandHIGHLIGHT_COLORSto render selectable options through<EditorBubbleItem>is implemented cleanly.
- The onSelect callbacks correctly trigger editor command chains.
- The conditional rendering of the check icon in the highlight section offers clear visual feedback.
apps/mail/components/cookies/toggle.tsx (4)
10-13: Consistent Prop Definitions with Updated Formatting
ThePropstype now uses consistent space-based indentation and clear type definitions. This improves readability without altering functionality.
16-21: Clear and Concise Async Handler Implementation
ThehandleCookieTogglefunction is implemented with an async callback insidestartTransition, ensuring that updates are handled correctly. The formatting change improves clarity while keeping the original logic intact.
23-27: Effective Conditional Rendering Based on Region and Cookie Category
The condition on lines 23–27 cleanly ensures that non-necessary cookies are not rendered outside the EU/UK region. This logic remains both clear and effective.
28-34: Clean and Readable JSX for the Toggle Component
The return block that renders the<Switch>component is well formatted and straightforward. The inline conditional for thecheckedprop and use of proper props fordisabledandonCheckedChangecontribute to clear code.apps/mail/app/(routes)/mail/under-construction/[path]/page.tsx (3)
9-12: Improved Interface Formatting for Readability
The updated indentation for theUnderConstructionPropsinterface (lines 9–12) enhances readability while keeping the functional declaration unchanged.
15-18: Efficient Resolution and Decoding of Dynamic Route Parameters
The use of the experimentalusehook to resolve the promise inparamsand the subsequent decoding of the path parameter is clear and concise. Ensure that this pattern aligns with your overall use of asynchronous component data.
19-40: Consistent and Responsive Under-Construction Page Layout
The JSX layout for the under-construction page (lines 19–40) is well formatted and clearly displays UI components such as the sidebar toggle and construction icon. The overall structure supports responsive design.apps/mail/components/create/editor.node-selector.tsx (4)
1-13: Organized Import Block with Consistent Formatting
The import block is now neatly organized with aligned indentation. This ensures that dependency imports (including icon components fromlucide-react) are clear and maintainable.
20-25: Well-Defined SelectorItem Type
TheSelectorItemtype definition (lines 20–25) is clear and self-explanatory, ensuring that each item in the selector conforms to the expected interface.
88-91: Clear Definition of NodeSelectorProps
TheNodeSelectorPropsinterface (lines 88–91) is clear and concise. The prop types are self-explanatory and appropriately defined for use in the component.
93-133: Robust NodeSelector Component with Intuitive UI Integration
TheNodeSelectorcomponent (lines 93–133) correctly uses theuseEditorhook and conditionally renders based on the editor state. The integration with popover UI elements and the mapping of selector items is both readable and functionally sound.apps/mail/components/home/hero.tsx (4)
19-22: Schema Definition Formatted for Clarity
ThebetaSignupSchema(lines 19–22) is defined using Zod with clear constraints. The formatting aligns with the new style configuration and supports readability.
24-33: Efficient State and Form Initialization
The state variables and form hook initialization (lines 24–33) are well structured, providing a clean setup for handling form submissions and state updates.
35-46: Reliable Data Fetch with Appropriate Error Logging
TheuseEffecthook (lines 35–46) fetches the signup count and handles potential errors with a console log, ensuring the application can gracefully handle API failures.
85-189: Well-Structured and Responsive Hero Component
The JSX structure (lines 85–189) cleanly lays out the Hero section, balancing responsive design elements, conditional renderings (success state vs. form), and integration with various UI components. The component adheres to best practices for a responsive and accessible design.apps/mail/components/create/selectors/math-selector.tsx (3)
1-5: Clear and Consistent Imports
The import statements (lines 1–5) are neatly formatted and ensure that dependencies such as theButton,SigmaIcon, and utility functions are imported correctly with the updated spacing.
6-9: Appropriate Editor Hook Usage and Early Return
The use of theuseEditorhook (lines 6–9) correctly handles the case when the editor is not initialized by returningnull. This early exit enhances component robustness.
12-27: Effective OnClick Handler for Toggling Math Mode
The onClick handler (lines 12–27) smartly checks if the editor is currently active in math mode and toggles LaTeX content accordingly. The use of destructuring to obtain the selected text and the conditional logic for setting or unsetting LaTeX content is both clear and effective.apps/mail/app/(routes)/create/page.tsx (1)
3-10: Cosmetic Refactor and Component Consistency
The changes in this file are limited to reformatting the JSX structure in theCreatePagecomponent. The updated two-space indentation makes the structure easier to follow, and the component usage of<CreateEmail />remains consistent with the rest of the app.apps/mail/app/(routes)/settings/connections/page.tsx (3)
27-43: Consistent Formatting in Connection Management
The reformatting of theConnectionsPagecomponent—including the error handling in thedisconnectAccountfunction and the clean use of toast notifications—is well done. The slight modifications to indentation and spacing help improve readability without altering the functional logic.
45-61: UI Rendering & Accessibility Adjustments
The layout of the settings card (with skeletons for loading state and the conditional rendering of connection items) has been preserved while applying consistent spacing and formatting. This makes the code more maintainable and visually coherent with the rest of the codebase.
162-174: Interactive Dialog Integration for Adding Connections
The integration of the<AddConnectionDialog>with its responsive button (including a smooth transition on hover) is clearly formatted. The use of conditional class names and group hover effects adds to the polished UI, and overall, the reformatting does not affect the functionality.apps/mail/components/create/editor.text-buttons.tsx (1)
7-62: Enhanced Readability in Text Formatting Controls
The changes in theTextButtonscomponent are purely cosmetic, with adjusted indentation and spacing. The code remains clear: it checks for the editor’s existence, maps over a well‑structured list of formatting commands, and renders each command correctly using the<EditorBubbleItem>and<Button>components.apps/mail/components/create/selectors/text-buttons.tsx (3)
8-22: Refined AI Action Handler for Text Selection
The introduction of thehandleChatWithAIfunction is clear and concise. It correctly retrieves the currently selected text from the editor and logs it. While the actual AI chat functionality is left as a placeholder, the structure is in place.
24-32: Well-Defined Command Items
The definition of theitemsarray is straightforward. Using properties such asname,label,action, andimageSrcis clear, and the conditional rendering (based onuseImage) is handled properly.
34-62: Clean Rendering of Selector Buttons
The mapping over theitemsarray to render an<EditorBubbleItem>and a corresponding<Button>is both clear and consistent with the design principles used elsewhere in the codebase. The formatted JSX improves readability and maintainability.apps/mail/components/create/editor.tsx (8)
58-66: Clear Default Editor Content Structure
ThedefaultEditorContentobject is concise and properly structured. The use of a minimal document with a paragraph block is appropriate for initializing the editor content, and the formatting changes enhance clarity.
68-90: Well‑Typed Component Props and Reducer Setup
The interfaces forEditorProps,EditorState, and the union typeEditorActionare defined clearly. TheeditorReducerfunction uses a simple switch case to update component state and is easy to follow.
107-130: Robust MenuBar Component Implementation
TheMenuBarcomponent properly handles link dialog operations. It pre-fills the URL if the link is active and correctly toggles dialog state. The formatting adjustments make the control flow very clear. No functional issues are identified.
150-170: Efficient Attachment Handling in MenuBar
The code for handling file attachments (using dynamic input creation, file selection, and update callbacks) is correctly structured. The use of popovers to display attachment count and details enhances the overall UI experience.
373-393: Consistent Editor Initialization and State Management
TheEditorcomponent uses a combination ofuseReducer,useRef, anduseEffecthooks to manage its state and the editor instance. The use of a ref (contentRef) to store editor content to prevent data loss on refresh is practical.
458-469: Clear and Effective Command Handling
The keyboard event handling for Command/Ctrl+Enter (triggering email send and content clearing) is cleanly implemented. The additionalsetTimeoutto clear the content after sending ensures that the editor state is updated appropriately.
489-536: Seamless EditorContent Integration and Command Palette
The integration of<EditorContent>with custom DOM event handlers (for paste, drop, and keydown events) is detailed and correctly prevents unintended default behaviors. The use of<EditorCommand>, including an empty state (EditorCommandEmpty) and iterating oversuggestionItems, is well organized.
576-583: Streamlined Editor Menu Toggle
Replacing the default editor menu with theEditorMenucomponent, which uses a dispatched state update to toggle AI features, is implemented with clear intent. The placeholder child is used solely to fulfill type requirements, which is acceptable given the design constraints.apps/mail/app/(routes)/mail/[folder]/page.tsx (3)
3-7: Interface Formatting & ReadabilityThe updated indentation in the
MailPagePropsinterface (lines 4–6) improves readability. The type definition remains clear and correct.
11-16: Async Parameter Extraction and Folder ValidationIn the
MailPagefunction, extracting thefoldervalue viaawait params(line 12) and validating it against theALLOWED_FOLDERSarray (lines 14–16) is implemented correctly.
18-19: Consistent and Clean ReturnThe final return statement simply renders the
<MailLayout />when the folder is valid. No issues are noted here.apps/mail/components/icons/animated/more-vertical.tsx (4)
11-14: Interface Declaration for Imperative HandleThe
MoreVerticalIconHandleinterface definingstartAnimationandstopAnimationis clean and accurate.
20-23: Transition & Variant DefinitionsThe constants
transition(lines 20–23) andvariants(lines 25–38) are well defined. The custom delay via thecustomparameter for each animated circle offers flexible staggered animations.
54-63: Mouse Event Handling & Conditional AnimationThe use of
useCallbackin thehandleMouseEnterandhandleMouseLeavefunctions—combined with checkingisControlledRef.currentto determine whether to trigger the animation or delegate to passed-in callbacks—is both robust and clear.
76-103: SVG Animation ImplementationThe SVG markup with motion-based animations is implemented correctly. The approach ensures the component is reusable and animations are easily controlled via the imperative handle.
apps/mail/app/(full-width)/contributors/page.tsx (2)
142-150: Consolidating Contributor DataThe
useEffectblock combininginitialContributorswithadditionalContributors(lines 142–150) is well implemented. This fallback ensures that if more than 100 contributors exist, the second page is fetched and merged.
196-205: Error Handling and Fallback StrategyThe error-checking block (lines 196–205) that sets an error state and triggers
generateFallbackData()for robust fallback behavior is a sensible design for handling API errors.apps/mail/app/(full-width)/privacy/page.tsx (3)
15-23: Clipboard Link Copy HandlingThe
handleCopyLinkfunction (lines 19–22) correctly constructs the URL usingwindow.location(appropriate for this client component) and then calls thecopyToClipboardhook. This implementation is both simple and effective.
39-87: Structured and Accessible Privacy Policy RenderingThe sectioned layout using a
CardwithCardHeaderand mapping through thesectionsarray to render individual policy sections (lines 39–87) makes for a clean, modular, and accessible design. The usage ofcreateSectionIdhelps ensure the IDs are URL-friendly.
95-286: Rich Content in the Sections ArrayThe
sectionsconstant holds well-structured JSX for each privacy policy topic. With clearly defined titles, content, and even embedded links (with properaria-labeland security attributes), the markup supports both clarity and accessibility.apps/mail/components/icons/animated/expand.tsx (5)
9-12: ExpandIconHandle InterfaceThe interface defining
startAnimationandstopAnimationis clear. This allows consumers to imperatively control the icon animations when needed.
18-22: Default Transition ConstantThe
defaultTransitionconstant (lines 18–22) is defined appropriately using a spring animation. These parameters (stiffness and damping) appear well-tuned for subtle yet responsive movements.
24-36: Use of Imperative Handle with Forwarded RefThe component uses
forwardRefalong withuseImperativeHandle(lines 24–36) to exposestartAnimationandstopAnimationmethods. TheisControlledRefflag to decide between internal handling and delegating to a passed callback is a nice touch.
38-58: Mouse Event CallbacksThe mouse event handlers (
handleMouseEnterandhandleMouseLeavedefined in lines 38–58) useuseCallbackto minimize unnecessary re-renders. Their logic to conditionally activate animation depending on the control state is correct.
60-117: SVG and Motion Paths for AnimationThe SVG markup with multiple
<motion.path>elements (lines 60–117) is well-organized. Each path uses thedefaultTransitionand has separate variants for 'normal' and 'animate' states, which clearly achieves the intended animated effect.apps/mail/app/(routes)/settings/layout.tsx (4)
10-16: Improved Component Composition in SettingsLayout
TheSettingsLayoutfunction now uses a clear composition with<Suspense>and a dedicatedSettingsLayoutSkeletonfallback. The consistent two-space indent improves readability without affecting functionality.
18-30: Consistent Mobile Detection Logic with useEffect
TheSettingsLayoutContentcomponent initializes theisMobilestate and correctly adds/removes the resize event listener in the effect. The refactored indentation and structure enhance clarity.
32-60: Clean JSX Layout in SettingsLayoutContent
The layout section using<AppSidebar>,<ResizablePanelGroup>, and<ScrollArea>is now uniformly formatted. The improved spacing and indentation make the component easier to follow.
63-72: Well-Formatted Skeleton Fallback Component
TheSettingsLayoutSkeletoncomponent is neatly indented and maintains a clear structure. This fallback UI is straightforward and consistent with the rest of the file’s formatting improvements.apps/mail/app/(routes)/developer/page.tsx (2)
9-70: Consistent Formatting in Developer Resources Array
All entries in thedeveloperResourcesarray are now uniformly formatted, with consistent spacing and indentation. This enhances maintainability without modifying the logic.
72-149: Clean and Consistent DeveloperPage Component
TheDeveloperPagefunction has been reformatted for improved readability. The back navigation button, header, and card components are clearly structured, ensuring that the UI layout remains unaffected by the cosmetic changes.apps/mail/app/(full-width)/terms/page.tsx (5)
15-23: Effective Hook Usage in TermsOfService Component
The integration of hooks likeuseRouteranduseCopyToClipboardis clear and well-formatted. The event handlerhandleCopyLinkis concise and correctly positioned.
24-38: Well-Structured Back Button and Header
The back button (with its associated icon and click action) and the header elements are now consistently indented. This improves the overall clarity of the component without introducing logic changes.
40-88: Clean Card Layout for Terms of Service
The<Card>component and its inner elements (header, content area) have been reformatted for better readability. Each JSX block is clear and maintains its intended styling.
90-94: Consistent Footer and Overall Layout Structure
The wrapping structure including the<Footer>component and surrounding containers is uniformly formatted. The layout improvements contribute to a cohesive design.
96-191: Well-Formatted Sections Array
Thesectionsarray, which defines the content for Terms of Service, is clearly structured. Each section’s title and content are properly indented, which enhances the maintainability and readability of the configuration.apps/mail/app/api/og/home/route.tsx (5)
5-19: Well-Formatted Font Loading Utility
The nestedloadGoogleFontfunction is clearly written with proper asynchronous calls and error handling. The inline regular expression matching is succinct and the indentation improvements make the logic easy to follow.
21-26: Clear Image Buffer Processing for Mail Icon
Fetching the mail icon, converting it to a base64 string, and forming the data URL is implemented cleanly. The diff improves readability without altering the functional intent.
27-29: Consistent Retrieval of Multiple Font Weights
The calls to fetch different font weights (400and600) are clear and sequential. The formatting adjustments aid in understanding the parallel font-loading steps.
30-91: Stylish OG Image JSX with Inline Styling
The JSX provided toImageResponseis neatly indented using Tailwind utilities alongside inline style objects. The layout and component structure are clear and consistent with the design intent.
91-111: Accurate Configuration of ImageResponse Options
The configuration object forImageResponse(including width, height, and font information) is well-formed. Removal of superfluous debug options enhances clarity.apps/mail/app/(auth)/zero/signup/page.tsx (8)
12-16: Robust Form Schema Validation with Zod
The Zod schema for validatingname,passwordis clearly defined with descriptive error messages. The consistent formatting makes future maintenance straightforward.
18-26: Clear useForm Initialization with Default Values
The use ofreact-hook-formalongsidezodResolveris neatly configured. Default values are explicitly defined, and the overall structure aligns with modern form management practices.
27-37: Effective onSubmit Handler with Toast Notification
TheonSubmitfunction appends the@0.emailsuffix as intended and usestoast.successproperly. Although this example is a stub for authentication, the logic is concise and clearly formatted.
39-45: Nicely Formatted Signup Header
The header section with the title and subtitle is clearly arranged and visually engaging. The consistency in indentation supports improved readability.
47-64: Cleanly Structured Name and Email Fields
The form fields for name and email (including the static domain suffix for email) are well-structured using the UI form components. The layout and class names are uniformly indented, which aids in clarity.
66-106: Clear Implementation of the Password Field
The password field leverages the same form component structure, providing a consistent UX. The formatting and indentation improvements make the component easier to maintain.
108-120: Well-Defined Submit Button and Navigation Link
The submit button and the login link are clearly implemented, with appropriate styling and spacing. This ensures a smooth user experience on form submission.
124-141: Consistent Footer Section
The footer with links to the "Terms of Service" and "Privacy Policy" is uniformly styled and properly aligned with the page content. The improvements in indentation enhance overall clarity.apps/mail/components/create/create-email.tsx (7)
21-32: State Initialization is Clear and Consistent
The declaration of state variables (e.g.toInput,toEmails,subjectInput, etc.) is well organized and readable. The use of TypeScript generics (where applicable) and default values is appropriate.
51-65: Default Editor Initialization for New Drafts
The effect that sets a default document structure when there is no draft loaded is implemented in a clear and straightforward way. This ensures the editor has the correct initial content.
67-130: Robust Draft Loading Logic with Error Handling
TheloadDraftfunction inside the useEffect is well structured. It properly checks if a draft exists, parses its content, and utilizes toast notifications for error reporting. Consider logging or handling cases where the draft ID exists but the data remains incomplete, though the current implementation is solid.
141-159: Email Input Handling is Robust
ThehandleAddEmailfunction performs necessary trimming, duplication checks, and validation using a regular expression. This helps prevent invalid entries and keeps the state consistent.
168-195: Auto-save Functionality Works Well
ThesaveDraftfunction encapsulated in aReact.useCallbackis correctly implemented with proper try–catch error handling and state updates to manage the saving process. The auto-save useEffect that triggers save after 3 seconds is a good touch.
211-264: Comprehensive Email Sending Validation
ThehandleSendEmailfunction includes thorough checks for valid recipient emails, non-empty subject, and message content. The subsequent state resets upon successful email sending ensure the UI remains in sync.
289-303: Effective Document-Level Event Handling
The use of a ref for the "to" input and attaching a global keydown event to focus the input is a neat user experience enhancement. Cleanup with removal of the event listener is correctly implemented.apps/mail/components/context/thread-context.tsx (2)
1-11: Uniform Import Formatting Improves Readability
The re-indentation of imports from the context-menu component now follows a consistent, space-indented style. This aligns well with the project’s updated formatting standards.
12-25: Consistent Formatting for Icon Imports
The imports fromlucide-reactare now uniformly formatted (each imported entity on its own line). This enhances readability and maintains consistency across the file.apps/mail/app/(routes)/settings/notifications/page.tsx (4)
3-10: Consistent Import Formatting in Settings Page
The import statements for UI form components (e.g.Form,Select, etc.) have been reformatted to use spaces consistently. This ensures the code adheres to the project’s style guidelines and improves maintainability.
27-30: Clear Schema Definition for Notifications
The use of Zod for the schema definition (formSchema) is concise and correct, establishing clear types for notification settings.
32-42: Well-configured React Hook Form Setup
TheuseFormhook is configured with the proper resolver and default values. This setup is standard and will ensure correct validation and state management in the notifications form.
51-117: Clean and Semantic JSX Structure
The Settings page layout wrapped in a<SettingsCard>is well organized. The form fields, reset functionality, and submission buttons are clearly structured. All UI elements enjoy consistent spacing and alignment.apps/mail/components/context/command-palette-context.tsx (7)
3-12: Streamlined Imports for the Command Palette Components
The imports for command-related components now follow a consistent space-indented format, improving overall code clarity.
25-29: Clear Type and Context Definitions
TheCommandPaletteContexttype and initial context are defined clearly. The pattern used here promotes type safety and proper context management in React.
37-43: Proper Custom Hook Implementation
The custom hookuseCommandPalettechecks for a valid context and throws an error if misused. This pattern is effective for ensuring that context is used within its provider.
45-60: Effective Event Listener for Toggling the Dialog
The useEffect that adds and cleans up the keydown listener (toggling the palette on Ctrl/Cmd + K) is implemented correctly. The use of a callback to toggle the open state is both concise and efficient.
62-120: Logical Construction and Filtering of Command Groups
The code that builds theallCommandsarray via mapping, filtering, and combining different navigation sections is well structured. It properly leveragesReact.useMemoto avoid unnecessary recalculations, and integrates localization (t) effectively.
123-145: Well-Structured Dialog and Command Item Rendering
TheCommandDialogcomponent encapsulates the command palette UI nicely. The conditional rendering of command groups and usage of components such asCommandGroup,CommandItem, andCommandSeparatorare straightforward and consistent with UI patterns elsewhere in the codebase.
210-217: Clean Provider Implementation
TheCommandPaletteProviderusesReact.Suspenseappropriately to wrap the CommandPalette. This ensures that any async loading is handled gracefully.apps/mail/components/create/slash-command.tsx (2)
1-14: Consistent Import Formatting for Slash Command
The reformatting of Lucide icon imports is now consistent, contributing to improved code readability and adherence to project style guidelines.
19-75: Clear and Maintainable Suggestion Items Definition
The array of suggestion items for the slash command is well defined. Each item includes a title, description, search terms, and an icon. The use of inline arrow functions for the command actions is concise and clear. The formatting adjustments improve overall legibility without altering functionality.apps/mail/components/cookies/cookie-dialog.tsx (7)
3-10: Formatting Improvement: Dialog Import Block
The updated import statements for the Dialog components now use consistent space-based indentation as per the updated.prettierrcsettings. This enhances readability and maintains consistency across the codebase.
11-16: Formatting Improvement: Accordion Import Block
The import statements for the Accordion components have been reformatted to use the new space-based style. This change improves clarity and aligns with the project’s updated configuration.
27-30: Clear Interface Declaration
TheCookieConsentPropsinterface is clearly defined with optionalchildrenandshowFloatingButtonproperties. This makes the component’s expected props easy to understand and use.
32-44: Appropriate useEffect Logic for Banner Display
TheuseEffecthook efficiently checks if cookie preferences are not set (using!Object.values(preferences).some((value) => value)) and then delays the banner display by 1 second. The cleanup usingclearTimeoutis correctly implemented.
46-61: Simple and Effective Event Handlers
The event handler functions (handleSavePreferences,handleAcceptAll,handleRejectAll) succinctly update component state to close the dialog and hide the banner. Their straightforward implementation contributes to clear UI behavior.
63-217: Well-Structured Dialog Component Render
The Dialog component’s usage—with nested components likeDialogHeader,DialogTitle, andDialogDescription—is neatly organized and accessible. The content is clearly laid out, ensuring that cookie information and options are presented in an effective manner.
218-267: Responsive Floating Banner Rendering
The conditional rendering of the floating banner via the Card component is implemented effectively. The fixed positioning, animation classes, and clear call-to-action buttons enhance the user experience when cookie preferences are prompted.apps/mail/components/create/selectors/node-selector.tsx (3)
1-13: Refined Imports and Type Adjustments
The consolidated and consistently formatted import block fromlucide-reactand related modules improves readability. Additionally, changing theSelectorItemtype to useReturnType<typeof useEditor>['editor']enhances type safety for editor operations.
27-88: Robust Items Array Declaration
Theitemsarray is well-defined with clear implementations for both thecommandandisActiveproperties of each selector item. Inline comments add helpful context, especially for the “Text” configuration.
94-134: Clear NodeSelector Component Implementation
The NodeSelector component gracefully handles situations when the editor is not available, computes the active item correctly, and utilizes Popover components to render a clean, interactive UI. The onSelect handler correctly resets the popover state upon an item selection.apps/mail/components/icons/animated/reply.tsx (5)
11-14: Consistent Interface for ReplyIconHandle
TheReplyIconHandleinterface is concisely defined withstartAnimationandstopAnimationmethods. This clear contract allows parent components to control the icon’s animations via imperative methods.
20-24: Well-Defined Animation Transition and Variants
The configuration of thetransition, along with bothpathVariantsandarrowVariants, provides smooth animation sequences. These settings contribute to a polished visual experience for the reply icon.
54-66: Effective Usage of forwardRef and useImperativeHandle
The component leveragesforwardReftogether withuseImperativeHandleto expose internal animation controls. This pattern is well executed and allows parent components to trigger animations when necessary.
68-88: Optimized Mouse Event Handling with useCallback
TheuseCallbackhooks for mouse enter and leave events ensure that event handler references remain stable, optimizing re-renders. The conditional check usingisControlledRefeffectively determines whether to trigger internal animations or call the external handlers.
90-116: Clean SVG Rendering with Motion Paths
Using motion components to render SVG paths with smooth transitions enhances the visual responsiveness of the icon. The implementation is clean and aligns well with the animated design.apps/mail/components/draft/drafts-list.tsx (6)
129-154: Effective Bulk Selection Initialization
TheselectAllfunction—together withresetSelectMode—effectively initializes and toggles bulk selection for drafts. The clear use of state and conditional messaging (via toast notifications) ensures an intuitive bulk selection experience.
156-164: Comprehensive Use of HotKey Hooks for Selection Modes
MultipleuseHotKeyhooks are used to toggle various selection modes (mass, range, select-all-below). This flexible design accommodates different user interaction patterns; just ensure these hotkeys do not conflict with other global shortcuts.
266-295: Robust Handling for Keyboard and Blur Events
The useEffect hook monitoringkeyupandblurevents guarantees that all selection modes are reset appropriately when keys are released or the window loses focus. The proper cleanup of event listeners prevents potential memory leaks.
305-349: Dynamic Handling Based on Selection Mode in handleMailClick
ThehandleMailClickfunction dynamically adjusts its behavior based on the current selection mode. It toggles bulk selection for mass or range modes and navigates appropriately for single selections. This adaptive logic enhances user interaction with drafts.
361-374: Efficient Row Rendering with useCallback and Virtuoso
The memoization ofrowRendererviauseCallbackoptimizes performance by preventing unnecessary re-renders, which is especially beneficial when integrated with the Virtuoso virtualized list component.
377-400: Smooth Integration with Virtuoso for Virtualized Lists
The Virtuoso component is well integrated to render a virtualized list of drafts. The handling of theendReachedcallback and the display of loading indicators contribute to a responsive and scalable UI experience.apps/mail/app/(routes)/settings/shortcuts/page.tsx (4)
3-7: Consistent Import and Shortcut Configuration
The imports forSettingsCardandkeyboardShortcutsare now uniformly formatted and clearly structured, reflecting the project’s updated style guidelines.
11-13: Direct Access to Shortcuts Configuration
AssigningkeyboardShortcutsto a local constant simplifies the component logic, making it straightforward to iterate over and render the shortcut definitions.
15-36: Clean Use of SettingsCard for Page Layout
The usage of theSettingsCardcomponent neatly encapsulates the page layout, incorporating an informative title, description, and footer actions. This structure contributes to a clean and user-friendly settings page.
38-54: Well-Structured Shortcut Component
TheShortcutcomponent is succinctly implemented to display both the action label and its corresponding key bindings. The semantic use of<kbd>elements and clear visual styling enhances readability and accessibility.apps/mail/components/draft/drafts.tsx (4)
22-28: State and Hook Initialization – LGTMThe state hooks for search mode, search value, and mail are initialized correctly and clearly.
30-34: Session Validation in useEffect – LGTMThe useEffect hook properly checks the session state and redirects unauthenticated users to the login page.
42-48: Hotkey for Exiting Search Mode – LGTMThe implementation for handling the 'Esc' hotkey is appropriate. The use of
// @ts-expect-errorfor preventing potential TypeScript errors is acceptable in this context.
153-176: BulkSelectActions Component – LGTMThe BulkSelectActions component is well-structured and clearly implements the bulk action buttons with tooltips.
apps/mail/app/(routes)/settings/security/page.tsx (1)
48-60: Settings Form Structure – LGTMThe form is well integrated within the SettingsCard component using React Hook Form. The use of a dedicated form id and proper Button configuration for submission is clear and effective.
apps/mail/components/home/navbar.tsx (2)
14-22: Responsive Behavior via useEffect – LGTMThe useEffect hook effectively uses a media query to automatically close the sheet on large screens. The event listener is properly added and cleaned up.
1-103: Navbar Component Structure – LGTMOverall, the Navbar component is cleanly constructed with clear conditional rendering and proper use of hooks, making it easy to maintain and understand.
apps/mail/components/icons/animated/message-square.tsx (3)
9-12: Icon Handle Interface and Forwarding – LGTMThe interface for MessageSquareIconHandle and its integration with forwardRef are correctly implemented, exposing the animation methods as intended.
54-74: Mouse Event Handling for Animation – LGTMThe callbacks for handling mouse enter and leave events are defined appropriately. They ensure that the animation starts or stops based on whether the component is controlled.
76-103: SVG and Motion Configuration – LGTMThe motion.svg element is properly configured with animation variants and control bindings. The SVG icon renders as expected, and the animation transitions are clear.
apps/mail/app/(routes)/settings/appearance/page.tsx (2)
15-18: Form Schema Definition – LGTMThe formSchema using zod correctly defines the
inboxTypeas an enumeration. The schema is concise, clear, and maintains consistency with similar validations.
39-62: Appearance Settings Form – LGTMThe AppearancePage component cleanly integrates the SettingsCard, form elements, and the ModeToggle component. The layout and structure promote good readability and maintainability.
apps/mail/components/icons/animated/filter.tsx (6)
10-13: Cosmetic Update to the Interface Declaration
The interface members (startAnimationandstopAnimation) now include explicit formatting adjustments. There are no functional changes.
15-24: Consistent Reformatting of Animation Variants
ThelineVariantsobject has been reformatted with adjusted indentation. The values and transition settings remain unchanged and clearly readable.
26-39: Clean ForwardRef & Imperative Handle Implementation
The ref forwarding withuseImperativeHandleis correctly structured. The changes focus on consistent indentation without altering the underlying logic.
40-49: Consistent Mouse Event Handling (Mouse Enter)
The animation trigger logic on mouse enter is intact, and the formatting improvements enhance readability.
51-60: Consistent Mouse Event Handling (Mouse Leave)
ThehandleMouseLeavecallback correctly handles the animation reset. The formatting refinements do not affect functionality.
62-86: Well-formatted Return JSX Structure
The return statement properly renders the container<div>and nested<svg>. The maintained use ofmotion.pathwith correct variants ensures the component animation works as intended.apps/mail/components/icons/animated/book-text.tsx (5)
7-10: Interface Formatting Update Maintains Contract
TheBookTextIconHandleinterface’s methods are now indented consistently. There is no change in the logic or intended API.
12-24: Refined ForwardRef and Imperative Handle Logic
The component’s use offorwardRefalong withuseImperativeHandleis correctly implemented. The cosmetic changes improve readability while preserving functionality.
26-35: Consistent Mouse Enter Callback Implementation
ThehandleMouseEntercallback is structured correctly with a conditional check onisControlledRefand calls the proper animation control method. The reformatting enhances clarity.
37-46: Consistent Mouse Leave Callback Implementation
ThehandleMouseLeavecallback usesuseCallbackappropriately. The conditional logic and animation reset remain correct and clearly presented.
48-90: Clean and Readable JSX Return Block
The return block renders the<div>wrapping a<motion.svg>element correctly. The animation variants and SVG paths are unchanged, while the reformatting increases visual consistency.apps/mail/components/cookies/cookie-trigger.tsx (3)
5-10: Interface Definition is Clear and Unchanged
TheCookieTriggerPropsinterface now shows a consistent indentation. Its properties (variant,className,children, andonClick) remain functionally equivalent.
18-23: Variants Object: Consistent Styling
Thevariantsobject mapping has been reformatted for clarity. The CSS class strings remain unchanged, ensuring the correct styling is applied based on thevariantprop.
25-47: Overall JSX Structure is Clear
Beyond the unnecessary fragment, the JSX structure using theButtoncomponent (from@/components/ui/button) is clear and the props are correctly passed.🧰 Tools
🪛 Biome (1.9.4)
[error] 33-42: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
apps/mail/components/icons/animated/settings-gear.tsx (5)
9-12: Interface Declaration and Formatting Consistency
TheSettingsGearIconHandleinterface now shows refined formatting. The methods continue to serve their purpose without any functional modification.
14-27: Proper Ref Forwarding with useImperativeHandle
The component correctly implementsforwardRefalong withuseImperativeHandle; the slight re-indentation enhances readability without impacting functionality.
28-37: Mouse Event Callbacks (Enter) are Structured Well
ThehandleMouseEntercallback is consistently implemented. The conditional check and call tocontrols.startremain correct, and the formatting updates are beneficial.
39-48: Mouse Event Callbacks (Leave) are Structured Well
ThehandleMouseLeavefunction is similarly well-structured, with no alterations in its logic, only cosmetic spacing improvements.
50-83: Well-Formatted Return Block for the Animated Icon
The return JSX block correctly renders a<div>containing a<motion.svg>element with proper animation properties and transition settings. The structural consistency across similar components is maintained.apps/mail/components/icons/animated/check-check.tsx (6)
8-11: Interface Remains Unchanged
TheCheckCheckIconHandleinterface’s declaration is now uniformly formatted, ensuring ease of reading and use across the codebase.
13-33: Animation Variants Definition is Clear and Maintainable
ThepathVariantsobject outlines both thenormalandanimatestates with clear timing and transition configurations. The changes are solely cosmetic, and the animation behavior remains intact.
35-47: Accurate useImperativeHandle with ForwardRef
The logic withinuseImperativeHandleis implemented correctly. The formatting changes improve readability while preserving functionality.
49-58: Consistent Mouse Enter Callback
ThehandleMouseEntercallback is clearly defined and continues to manage animation control as expected with the updated, consistent formatting.
60-69: Consistent Mouse Leave Callback
ThehandleMouseLeavecallback mirrors the structure of the enter callback, ensuring a uniform approach to event handling with improved code clarity.
71-106: Well-Structured SVG Rendering and Animation Control
The return statement renders the container<div>and nested<svg>element accurately. The paths are animated via themotion.pathcomponent using the definedpathVariants. The reformatting enhances maintainability and consistency with other animated icon components.apps/mail/components/icons/animated/keyboard.tsx (7)
8-11: Interface Formatting is Consistent
TheKeyboardIconHandleinterface is reformatted for clarity. Its method signatures remain unchanged and clear.
13-22: Array Definition is Clean and Readable
TheKEYBOARD_PATHSarray is reformatted with consistent spacing. There are no functional changes; these cosmetic adjustments improve readability.
24-38: Component Definition and Ref Forwarding
TheKeyboardIconcomponent’s implementation—including the use offorwardRef, state management, and imperative handle—is maintained as before. The reformatting helps in understanding the flow without altering functionality.
40-48: Well-Structured Event Handlers
The use ofuseImperativeHandleand the mouse event handlers (handleMouseEnter/handleMouseLeave) is clear and consistent. The separation of concerns is maintained.
62-82: Animation Logic is Explicit
The asynchronous animation logic within theuseEffecthook is handled properly. The cosmetic reformatting does not affect its behavior.
84-117: SVG and Motion Component Rendering Maintained
The SVG rendering along with themotioncomponents remains functionally equivalent while benefiting from improved indentation for readability.
120-123: Component Metadata and Export
SettingKeyboardIcon.displayNameand exporting the component continue to be clear and properly formatted.apps/mail/components/icons/animated/inbox.tsx (7)
8-11: InboxIconHandle Interface is Neatly Formatted
The interface now uses a consistent indentation style without changing its functionality.
13-16: Polyline Variants Formatting
ThepolylineVariantsobject is cleanly formatted. The property values remain unchanged, ensuring the original animation behavior is preserved.
18-25: Path Variants are Consistent
ThepathVariantsobject is formatted with improved clarity. Its values and structure remain intact.
27-39: Component Implementation is Refined
TheInboxIconcomponent’s implementation, including ref handling and event response, is maintained without logical changes. The reformatting enhances readability.
41-60: Event Callback Structure is Clear
The mouse event callbacks viauseCallbackare reformatted to be clearer, without altering functionality. Dependencies are correctly specified.
63-70: Component Rendering is Organized
The return statement and the integration of themotioncomponents (for both polyline and path) are formatted for better clarity while preserving the original animation transitions.
99-102: Display Name and Export are Unchanged
The setup for displaying and exportingInboxIconis clear and consistent.apps/mail/app/(routes)/settings/[...settings]/page.tsx (3)
12-19: Settings Pages Mapping is Clear
ThesettingsPagesobject is reformatted to use consistent spacing. The mapping of routes to components is maintained without disruption.
21-30: Dynamic Component Resolution in SettingsPage
The extraction of the settings section from the URL parameters and the conditional rendering of the corresponding page component are clear. The concise error handling (if no component is found) is appropriate.
32-33: Component Rendering is Straightforward
Returning<SettingsComponent />preserves functionality and benefits from improved formatting.apps/mail/components/icons/animated/message.tsx (6)
8-11: MessageCircleIconHandle Interface is Neatly Styled
The interface withstartAnimationandstopAnimationis now consistently indented, with no changes to its intended functionality.
13-33: Icon Variants are Well-Organized
TheiconVariantsobject is reformatted to make the animation definitions (bothnormalandanimatestates) easier to read. All property values are preserved.
35-47: Component Definition with Ref Forwarding is Clear
TheMessageCircleIconcomponent usesforwardRefanduseImperativeHandleconsistently. The reformatting does not affect the behavior but enhances clarity in setup.
49-58: Mouse Event Handlers are Consistent
The implementations forhandleMouseEnterandhandleMouseLeaveare reformatted with clearer structure and dependency arrays. Their logic remains correct.
71-90: SVG Rendering and Motion Integration are Intact
The SVG with integratedmotionproperties is presented with improved spacing. The animation control viavariantsandanimateremains unchanged.
99-102: Component Metadata and Export are Properly Formatted
The assignment ofMessageCircleIcon.displayNameand the export statement are both clear and correctly maintained.apps/mail/app/(auth)/zero/login/page.tsx (9)
12-15: Form Schema is Clearly Defined
TheformSchemausing zod for validating email and password is now reformatted to use spaces instead of tabs. The validation messages remain informative and unchanged.
17-25: React Hook Form Initialization is Consistent
The initialization of the form viauseFormand the definition of default values are clear and benefit from the new indentation standard.
26-33: onSubmit Handler is Straightforward
TheonSubmitfunction, which currently simulates a login attempt by invoking a toast notification, is reformatted for clarity. The inline comment provides context, though the actual authentication logic remains to be implemented.
35-44: Login Form JSX is Well-Structured
The returned JSX, including the header with title and description, is now uniformly formatted. The use of UI components (Form,FormField,FormItem, etc.) is consistent with design guidelines.
45-62: Email Field Setup is Clear
The JSX within the firstFormFieldfor the email input is clearly structured with proper labels and control wrappers using the UI components. The placeholder and styling classes are maintained.
64-88: Password Field with Auxiliary Link is Well Organized
The secondFormFieldfor the password input includes the label and a "Forgot your password?" link. The formatting changes enhance clarity without altering functionality.
90-93: Submit Button is Prominently Displayed
TheButtoncomponent for form submission is formatted to span the full width, enhancing the user experience.
94-101: Signup Prompt Section is Clear and Concise
The text prompting users to sign up is uniformly formatted with clear hyperlink styling, consistent with the rest of the page.
106-121: Footer Section is Cleanly Separated
The footer containing links for Terms of Service and Privacy Policy is well formatted. The styling classes ensure that it remains unobtrusive yet accessible.apps/mail/components/icons/animated/cart.tsx (5)
9-10: Consistent Interface Declaration Formatting.
The updated indentation for theCartIconHandleinterface (lines 9–10) aligns perfectly with the new style guidelines without affecting functionality.
13-23: Clear and Consistent Animation Variants.
ThecartVariantsobject is formatted clearly and remains functionally correct. The animation parameters (e.g., scale, y-axis movement, and transition settings) are easy to read and manage.
26-38: Proper Use of Forward Ref and Imperative Handle.
TheCartIconcomponent’s use offorwardRefalong withuseImperativeHandle(lines 26–38) is implemented correctly. The formatting changes improve readability without altering the component’s behavior.
40-60: Efficient Event Handling with useCallback.
BothhandleMouseEnter(lines 40–49) andhandleMouseLeave(lines 51–60) are implemented usinguseCallback, ensuring that the event handlers are memoized appropriately. This update is purely cosmetic and does not impact the underlying functionality.
61-87: Clean JSX Rendering.
The JSX returned by the component (lines 61–87) is well-organized, with proper use of motion elements for animations and clear application of class names. The reformatting enhances overall code clarity.apps/mail/app/(routes)/settings/general/page.tsx (2)
3-10: Updated Import Formatting.
The import statements (lines 3–10) have been reformatted to a consistent style, which improves readability and complies with the new formatting guidelines.
31-36: Consistent Schema Definition.
The schema defined withz.object(lines 31–36) is clear and well-formatted. The changes are cosmetic and help maintain uniformity across the codebase.apps/mail/app/(auth)/login/login-client.tsx (2)
13-34: Clean Interface Definitions.
The interfaces (EnvVarStatus,Provider, andLoginClientProps) in lines 13–34 have been reformatted for clarity and now conform to the updated code style without affecting their definitions.
36-58: Concise Provider Icon Mapping.
ThegetProviderIconfunction (lines 36–58) clearly maps provider IDs to their corresponding icons. The changes are solely formatting updates that enhance readability.apps/mail/components/icons/animated/arrow-left.tsx (4)
8-11: Consistent Arrow Icon Handle Interface.
TheArrowLeftIconHandleinterface’s indentation (lines 8–11) now complies with the updated standards while keeping its functionality intact.
13-32: Well-Formatted Animation Variants.
BothpathVariants(lines 13–22) andsecondPathVariants(lines 24–32) are clearly structured and documented. The reformatting makes the intended animations straightforward to review.
34-94: Clean Implementation of ArrowLeftIcon Component.
The component implementation (lines 34–94) correctly usesforwardRef,useImperativeHandle, anduseCallbackto manage its internal state and animations. The updated formatting enhances maintainability without altering the component’s behavior.
96-99: Proper Component Export.
Assigning a display name (line 96) and exporting the component (line 98–99) is handled correctly, with formatting changes being purely cosmetic.apps/mail/components/home/footer.tsx (2)
8-27: Uniform Social Links Array Formatting.
ThesocialLinksarray (lines 8–27) has been reformatted to use space-based indentation, which improves consistency and readability across the file.
29-88: Clean and Responsive Footer Layout.
TheFootercomponent’s JSX (lines 29–88) is well-organized and clearly structured. The reformatting aligns it with the updated style guidelines without affecting the component’s functionality.apps/mail/components/create/uploaded-file-icon.tsx (2)
6-27: Consistent Formatting in thegetLogoFunction
The conditional logic mapping MIME types to asset paths has been reformatted for clarity and consistency. The changes are purely cosmetic and do not affect functionality.
29-33: Clean and ReadablePropsType Definition
The reformatting of thePropstype enhances readability without modifying its meaning.apps/mail/components/icons/animated/align-vertical.tsx (2)
8-11: Clear Interface Definition
TheAlignVerticalSpaceAroundIconHandleinterface is clearly defined and correctly specifies the animation control methods.
13-31: Readable Animation Variants for Rectangles
TherectVariantsobject is well-formatted with clear transition parameters. The use of thespringtransition with specified stiffness and damping is consistent and clear.apps/mail/components/icons/animated/archive.tsx (3)
8-11: Interface and Method Declaration Remain Clear
TheArchiveIconHandleinterface clearly defines the expected animation methods without any changes to its functionality.
13-32: Well-Defined Animation Variants for Archive Icon
BothrectVariantsandpathVariantsare reformatted for improved clarity. The transition parameters (duration, stiffness, damping) are explicitly specified and maintain the original behavior.
44-118: Reliable Component Implementation
TheArchiveIconcomponent usesforwardRef,useAnimation, and controlled event handlers to manage animations on mouse events. The formatting changes enhance readability while retaining the original behavior.apps/mail/components/icons/animated/moon.tsx (2)
8-11: Neat Interface Definition forMoonIconHandle
The interface remains unchanged and clearly defines thestartAnimationandstopAnimationmethods.
13-26: Well-Formatted SVG Variants and Transition Settings
ThesvgVariantsobject and the associatedsvgTransitionare clearly defined. The animation sequence and transition duration contribute to a smooth effect.apps/mail/components/icons/animated/bell.tsx (3)
8-11: Clear and ConsistentBellIconHandleInterface
The interface correctly defines methods for starting and stopping animations without changes to its functionality.
13-16: Effective SVG Variant Definitions
ThesvgVariantsobject is concise and clear. The animation keyframes for theanimatestate are specified as an array of rotation values, which is neatly formatted.
32-83: Clean and Consistent JSX Rendering
The component’s return statement lays out the SVG and associated event handlers in a clear manner. The use of class names and transition properties is consistent with the overall project style.apps/mail/app/(auth)/login/early-access/page.tsx (9)
20-28: Validation Schema Formatting and ClarityThe Zod validation schema is clearly defined with explicit error messages for each field. The formatting changes improve the readability without altering functionality.
32-45: State Initialization and URL Parameter ExtractionThe initialization of state (including retrieval of URL search parameters) and the default assignment for
currentStepare implemented clearly. This segment sets the stage correctly for the subsequent rendering logic.
47-66: URL Update useEffect HookThe useEffect hook that updates the URL based on the current step and user email is well structured. The use of
URLSearchParamscombined with router.replace ensures the URL stays in sync with the component’s state.
103-109: useForm InitializationThe useForm hook is correctly initialized with the zodResolver and appropriate default values. This ensures that form validation is integrated as expected.
111-122: Form Submission HandlerThe
onSubmitfunction properly appends the '@0.email' suffix to the username, updates the state, and triggers a success toast notification. This logic is consistent with the intended design.
125-191: Robust Error Handling in onErrorThe error-handling routine uses a clear mapping to display user-friendly messages and falls back gracefully if no pattern is matched. This approach should provide good guidance for user corrections.
193-205: Verification Handler FunctionThe
handleVerifyfunction validates the 6-digit code accurately, updates state, displays appropriate toasts, and performs routing as expected.
207-412: Structured JSX for Conditional RenderingThe return statement cleanly separates the “claim” (signup form) and “verification” screens using conditional rendering, along with smooth animations from the motion components. The readability improvements via reformatting are beneficial.
414-427: Suspense Fallback and Component ExportWrapping the main component with a Suspense boundary and providing a fallback loading UI adheres to good practices for asynchronously loaded content.
apps/mail/components/icons/animated/search.tsx (8)
7-10: Interface Definition for Animation ControlThe
SearchIconHandleinterface clearly defines the public methods to start and stop the animation. The use of concise method signatures enhances clarity.
12-16: ForwardRef and Animation Control InitializationThe use of
forwardRefcombined with theuseAnimationhook and a control flag (isControlledRef) is well executed. This setup allows parent components to imperatively control the icon's animation.
17-24: Imperative Handle SetupThe implementation of
useImperativeHandlecorrectly exposes thestartAnimationandstopAnimationmethods, while also marking the component as controlled. This cleanly encapsulates the animation control logic.
26-35: Mouse Event Handling – Mouse EnterThe
handleMouseEntercallback checks if the ref is controlled before starting an animation. The conditional logic is clear and ensures that the appropriate handler is used when provided by the parent.
37-46: Mouse Event Handling – Mouse LeaveSimilarly, the
handleMouseLeavecallback correctly dispatches either the internal animation control or defers to a provided callback. This symmetry with the mouse enter logic enhances maintainability.
48-54: Component Rendering and Prop ForwardingThe returned JSX for the container
<div>and the embedded<motion.svg>is well formatted. The spread of additional props ({...props}) ensures flexibility, and the styling classes reinforce good UI practices.
55-80: Motion SVG Attributes and Animation VariantsThe SVG element is configured with clear animation variants (
normalandanimate) and smooth transition settings. The use of arrays for the x and y coordinates provides a fluid motion effect.
86-89: Setting Display Name and Export StatementAssigning a display name to the component aids debugging and clear component hierarchy. The export statement maintains consistency with the rest of the codebase.
apps/mail/components/create/ai-chat.tsx (8)
21-24: Auto-Resize Textarea Props InterfaceThe interface
UseAutoResizeTextareaPropsis succinct and precisely defines the required attributes for the auto-resizing functionality.
72-81: State Management and Hook Usage in AIChatThe multiple state variables (such as
value,isRecording,audioData, etc.) are initialized appropriately. The usage of refs for file input, audio context, analyser, and speech recognition reflects careful resource management.
87-101: Audio Visualization: updateAudioData CallbackThe
updateAudioDatafunction efficiently retrieves and normalizes frequency data from the analyser. Recursive scheduling viarequestAnimationFrameensures smooth updates. This implementation is both accurate and performance-conscious.
103-111: Textarea Key Down HandlerThe
handleKeyDownfunction gracefully intercepts the Enter key (without Shift) to submit the chat input, clearing the input and resetting the textarea height appropriately.
113-124: File Input HandlersBoth
handleFileClickandhandleFileChangeare aptly implemented for file upload interactions. The current placeholders (e.g., console.log) are acceptable for future file upload logic integration.
126-205: Microphone Access and Speech Recognition HandlerThe
handleMicClickfunction is robust in handling audio recording. It:
- Asynchronously acquires microphone access.
- Sets up an AudioContext with an AnalyserNode for real-time visualization.
- Initiates speech recognition if supported, updating the textarea with interim results.
- Properly falls back with an error toast if the browser does not support speech recognition.
- Includes handling for stopping and cleaning up resources.
Overall, the logic is comprehensive.
211-230: Cleanup useEffect for Resource ManagementThe useEffect hook dedicated to cleaning up animation frames, audio context, media streams, and speech recognition resources upon component unmount is well implemented. This proactive cleanup helps prevent memory leaks and unwanted side effects.
232-304: JSX Layout and Conditional Rendering in AIChatThe return block effectively structures the AIChat component UI:
- It conditionally renders either the live audio visualizer during recording or the AITextarea for input.
- The layout is cleanly organized with responsive styling.
- The integration of file upload and microphone toggle buttons provides a comprehensive user interaction experience.
The code is clear and maintains consistency in styling and functionality.
| return ( | ||
| <div className="min-h-screen w-full bg-white text-black dark:bg-neutral-950 dark:text-white"> | ||
| <div className="container mx-auto max-w-6xl px-4 py-8"> | ||
| {/* Header with theme toggle */} | ||
| <div className="mb-6 flex justify-end"> | ||
| <ThemeToggle /> | ||
| </div> | ||
|
|
||
| {/* Project Stats */} | ||
| <div className="mb-8 overflow-hidden rounded-xl border bg-gradient-to-b from-white/50 to-white/10 p-6 backdrop-blur-sm dark:border-neutral-700 dark:from-neutral-900/50 dark:to-neutral-900/30"> | ||
| <div className="flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center"> | ||
| <div className="space-y-1"> | ||
| <div className="flex items-center gap-2"> | ||
| <Link href="/"> | ||
| <div className="relative h-8 w-8"> | ||
| <Image | ||
| src="/black-icon.svg" | ||
| alt="0.email Logo" | ||
| fill | ||
| className="object-contain dark:hidden" | ||
| /> | ||
| <Image | ||
| src="/white-icon.svg" | ||
| alt="0.email Logo" | ||
| fill | ||
| className="hidden object-contain dark:block" | ||
| /> | ||
| </div> | ||
| </Link> | ||
| </div> | ||
| <p className="text-sm text-neutral-500 dark:text-neutral-400"> | ||
| An open source email app built with modern technologies | ||
| </p> | ||
| </div> | ||
| <div className="flex gap-2"> | ||
| <Button | ||
| asChild | ||
| variant="outline" | ||
| size="sm" | ||
| className="gap-2 border-neutral-200 bg-white/50 text-neutral-700 hover:bg-neutral-100 hover:text-neutral-900 dark:border-neutral-700 dark:bg-neutral-900/50 dark:text-neutral-200 dark:hover:bg-neutral-800 dark:hover:text-white" | ||
| > | ||
| <Link href={`https://github.com/${REPOSITORY}`} target="_blank"> | ||
| <Github className="h-4 w-4" /> | ||
| View on GitHub | ||
| </Link> | ||
| </Button> | ||
| </div> | ||
| </div> | ||
|
|
||
| <Separator className="my-6 dark:bg-neutral-700" /> | ||
|
|
||
| <div className="flex flex-wrap items-center divide-x divide-neutral-200 dark:divide-neutral-700"> | ||
| <div className="flex items-center gap-3 px-3 first:pl-0 last:pr-0 sm:px-4"> | ||
| <Star className="h-4 w-4 text-neutral-600 dark:text-neutral-400" /> | ||
| <div className="flex items-baseline gap-1"> | ||
| <span className="text-base font-bold text-neutral-900 sm:text-lg dark:text-white"> | ||
| {repoStats.stars} | ||
| </span> | ||
| <span className="hidden text-xs text-neutral-500 sm:inline dark:text-neutral-400"> | ||
| stars | ||
| </span> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="flex items-center gap-3 px-3 first:pl-0 last:pr-0 sm:px-4"> | ||
| <GitFork className="h-4 w-4 text-neutral-600 dark:text-neutral-400" /> | ||
| <div className="flex items-baseline gap-1"> | ||
| <span className="text-base font-bold text-neutral-900 sm:text-lg dark:text-white"> | ||
| {repoStats.forks} | ||
| </span> | ||
| <span className="hidden text-xs text-neutral-500 sm:inline dark:text-neutral-400"> | ||
| forks | ||
| </span> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="hidden items-center gap-3 px-3 first:pl-0 last:pr-0 sm:flex sm:px-4"> | ||
| <Github className="h-4 w-4 text-neutral-600 dark:text-neutral-400" /> | ||
| <div className="flex items-baseline gap-1"> | ||
| <span className="text-base font-bold text-neutral-900 sm:text-lg dark:text-white"> | ||
| {repoStats.watchers} | ||
| </span> | ||
| <span className="text-xs text-neutral-500 dark:text-neutral-400"> | ||
| watchers | ||
| </span> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="flex items-center gap-3 px-3 first:pl-0 last:pr-0 sm:px-4"> | ||
| <MessageCircle className="h-4 w-4 text-neutral-600 dark:text-neutral-400" /> | ||
| <div className="flex items-baseline gap-1"> | ||
| <span className="text-base font-bold text-neutral-900 sm:text-lg dark:text-white"> | ||
| {repoStats.openIssues} | ||
| </span> | ||
| <span className="hidden text-xs text-neutral-500 sm:inline dark:text-neutral-400"> | ||
| issues | ||
| </span> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="flex items-center gap-3 px-3 first:pl-0 last:pr-0 sm:px-4"> | ||
| <GitPullRequest className="h-4 w-4 text-neutral-600 dark:text-neutral-400" /> | ||
| <div className="flex items-baseline gap-1"> | ||
| <span className="text-base font-bold text-neutral-900 sm:text-lg dark:text-white"> | ||
| {repoStats.openPRs} | ||
| </span> | ||
| <span className="hidden text-xs text-neutral-500 sm:inline dark:text-neutral-400"> | ||
| PRs | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="mt-6 grid gap-4 lg:grid-cols-3"> | ||
| {/* Repository Growth */} | ||
| <Card className="col-span-full border-neutral-100 bg-white/50 p-4 transition-all hover:bg-white/60 lg:col-span-2 dark:border-neutral-800 dark:bg-neutral-900/50 dark:hover:bg-neutral-900/60"> | ||
| <h3 className="mb-4 text-sm font-medium text-neutral-600 dark:text-neutral-400"> | ||
| Repository Growth | ||
| </h3> | ||
| <ResponsiveContainer width="100%" height={240}> | ||
| <AreaChart data={timelineData} className="-mx-5 mt-2"> | ||
| <defs> | ||
| <linearGradient id="stars" x1="0" y1="0" x2="0" y2="1"> | ||
| <stop offset="5%" stopColor="rgb(64, 64, 64)" stopOpacity={0.3} /> | ||
| <stop offset="95%" stopColor="rgb(64, 64, 64)" stopOpacity={0} /> | ||
| </linearGradient> | ||
| <linearGradient id="starsDark" x1="0" y1="0" x2="0" y2="1"> | ||
| <stop offset="5%" stopColor="rgb(255, 255, 255)" stopOpacity={0.4} /> | ||
| <stop offset="95%" stopColor="rgb(255, 255, 255)" stopOpacity={0} /> | ||
| </linearGradient> | ||
| <linearGradient id="forks" x1="0" y1="0" x2="0" y2="1"> | ||
| <stop offset="5%" stopColor="rgb(64, 64, 64)" stopOpacity={0.3} /> | ||
| <stop offset="95%" stopColor="rgb(64, 64, 64)" stopOpacity={0} /> | ||
| </linearGradient> | ||
| <linearGradient id="forksDark" x1="0" y1="0" x2="0" y2="1"> | ||
| <stop offset="5%" stopColor="rgb(200, 200, 200)" stopOpacity={0.3} /> | ||
| <stop offset="95%" stopColor="rgb(200, 200, 200)" stopOpacity={0} /> | ||
| </linearGradient> | ||
| </defs> | ||
| <XAxis | ||
| dataKey="date" | ||
| stroke="currentColor" | ||
| fontSize={12} | ||
| tickLine={false} | ||
| axisLine={false} | ||
| className="text-neutral-600 dark:text-neutral-400" | ||
| /> | ||
| <YAxis | ||
| stroke="currentColor" | ||
| fontSize={12} | ||
| tickLine={false} | ||
| axisLine={false} | ||
| tickFormatter={(value) => `${value}`} | ||
| className="text-neutral-600 dark:text-neutral-400" | ||
| /> | ||
| <Tooltip | ||
| content={({ active, payload }) => { | ||
| if (active && payload && payload.length) { | ||
| return ( | ||
| <div className="rounded-lg border border-neutral-200 bg-white p-3 shadow-lg dark:border-neutral-800 dark:bg-neutral-900"> | ||
| <div className="grid gap-2"> | ||
| <div className="flex items-center gap-2"> | ||
| <Star className="h-4 w-4 text-neutral-900 dark:text-white" /> | ||
| <span className="text-sm text-neutral-600 dark:text-neutral-400"> | ||
| Stars: | ||
| </span> | ||
| <span className="font-medium text-neutral-900 dark:text-white"> | ||
| {payload[0]?.value} | ||
| </span> | ||
| </div> | ||
| <div className="flex items-center gap-2"> | ||
| <GitFork className="h-4 w-4 text-neutral-700 dark:text-neutral-300" /> | ||
| <span className="text-sm text-neutral-600 dark:text-neutral-400"> | ||
| Forks: | ||
| </span> | ||
| <span className="font-medium text-neutral-900 dark:text-white"> | ||
| {payload[1]?.value} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
| return null; | ||
| }} | ||
| /> | ||
| <Area | ||
| type="monotone" | ||
| dataKey="stars" | ||
| stroke="rgb(64, 64, 64)" | ||
| strokeWidth={2} | ||
| fill="url(#stars)" | ||
| className="dark:fill-[url(#starsDark)] dark:stroke-white" | ||
| /> | ||
| <Area | ||
| type="monotone" | ||
| dataKey="forks" | ||
| stroke="rgb(64, 64, 64)" | ||
| strokeWidth={2} | ||
| fill="url(#forks)" | ||
| className="dark:fill-[url(#forksDark)] dark:stroke-neutral-300" | ||
| /> | ||
| </AreaChart> | ||
| </ResponsiveContainer> | ||
| </Card> | ||
|
|
||
| {/* Activity Chart */} | ||
| <Card className="col-span-full border-neutral-200 bg-white/50 p-4 transition-all hover:bg-white/60 lg:col-span-1 dark:border-neutral-800 dark:bg-neutral-900/50 dark:hover:bg-neutral-900/60"> | ||
| <h3 className="mb-4 text-sm font-medium text-neutral-600 dark:text-neutral-400"> | ||
| Recent Activity | ||
| </h3> | ||
| <ResponsiveContainer width="100%" height={240}> | ||
| <BarChart data={activityData} className="-mx-5 mt-2" layout="horizontal"> | ||
| <XAxis | ||
| dataKey="date" | ||
| stroke="currentColor" | ||
| fontSize={12} | ||
| tickLine={false} | ||
| axisLine={false} | ||
| className="text-neutral-600 dark:text-neutral-400" | ||
| interval={0} | ||
| /> | ||
| <YAxis | ||
| stroke="currentColor" | ||
| fontSize={12} | ||
| tickLine={false} | ||
| axisLine={false} | ||
| className="text-neutral-600 dark:text-neutral-400" | ||
| /> | ||
| <Tooltip | ||
| content={({ active, payload }) => { | ||
| if (active && payload && payload.length) { | ||
| return ( | ||
| <div className="rounded-lg border border-neutral-200 bg-white p-3 shadow-lg dark:border-neutral-800 dark:bg-neutral-900"> | ||
| <div className="grid gap-2"> | ||
| <div className="flex items-center gap-2"> | ||
| <GitGraph className="h-4 w-4 text-neutral-900 dark:text-white" /> | ||
| <span className="text-sm text-neutral-600 dark:text-neutral-400"> | ||
| Commits: | ||
| </span> | ||
| <span className="font-medium text-neutral-900 dark:text-white"> | ||
| {payload[0]?.value} | ||
| </span> | ||
| </div> | ||
| <div className="flex items-center gap-2"> | ||
| <MessageCircle className="h-4 w-4 text-neutral-700 dark:text-neutral-300" /> | ||
| <span className="text-sm text-neutral-600 dark:text-neutral-400"> | ||
| Issues: | ||
| </span> | ||
| <span className="font-medium text-neutral-900 dark:text-white"> | ||
| {payload[1]?.value} | ||
| </span> | ||
| </div> | ||
| <div className="flex items-center gap-2"> | ||
| <GitPullRequest className="h-4 w-4 text-neutral-500 dark:text-neutral-500" /> | ||
| <span className="text-sm text-neutral-600 dark:text-neutral-400"> | ||
| PRs: | ||
| </span> | ||
| <span className="font-medium text-neutral-900 dark:text-white"> | ||
| {payload[2]?.value} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
| return null; | ||
| }} | ||
| /> | ||
| <Bar | ||
| dataKey="commits" | ||
| radius={[4, 4, 0, 0]} | ||
| className="fill-neutral-900 dark:fill-white" | ||
| /> | ||
| <Bar | ||
| dataKey="issues" | ||
| radius={[4, 4, 0, 0]} | ||
| className="fill-neutral-700 dark:fill-neutral-300" | ||
| /> | ||
| <Bar | ||
| dataKey="pullRequests" | ||
| radius={[4, 4, 0, 0]} | ||
| className="fill-neutral-500 dark:fill-neutral-500" | ||
| /> | ||
| </BarChart> | ||
| </ResponsiveContainer> | ||
| </Card> | ||
| </div> | ||
| </div> | ||
|
|
||
| {/* Core Team Section */} | ||
| <div className="mb-12 space-y-6"> | ||
| <div className="text-center"> | ||
| <h1 className="text-3xl font-semibold tracking-tight text-neutral-900/80 dark:text-white"> | ||
| Core Team | ||
| </h1> | ||
| <p className="text-muted-foreground mt-2">Meet the people behind 0.email</p> | ||
| </div> | ||
|
|
||
| <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"> | ||
| {filteredCoreTeam?.map((member, index) => ( | ||
| <div | ||
| key={member.login} | ||
| className="group relative flex items-center gap-4 rounded-xl border bg-white/50 p-4 transition-all hover:-translate-y-1 hover:bg-white hover:shadow-lg dark:border-neutral-800 dark:bg-neutral-900/50 dark:hover:bg-neutral-900 dark:hover:shadow-neutral-900/50" | ||
| style={{ | ||
| animationDelay: `${index * 100}ms`, | ||
| animation: 'fadeInUp 0.5s ease-out forwards', | ||
| opacity: 0, | ||
| transform: 'translateY(10px)', | ||
| }} | ||
| > | ||
| <Avatar className="h-16 w-16 rounded-full ring-2 ring-neutral-200 transition-transform group-hover:scale-105 group-hover:ring-neutral-300 dark:ring-neutral-800 dark:group-hover:ring-neutral-700"> | ||
| <AvatarImage | ||
| src={`https://github.com/${member.login}.png`} | ||
| alt={member.login} | ||
| className="object-cover" | ||
| /> | ||
| <AvatarFallback className="text-xs"> | ||
| {member.login.slice(0, 2).toUpperCase()} | ||
| </AvatarFallback> | ||
| </Avatar> | ||
|
|
||
| <div className="flex-1"> | ||
| <h3 className="text-lg font-medium text-neutral-900 transition-colors group-hover:text-neutral-700 dark:text-neutral-200 dark:group-hover:text-white"> | ||
| {member.login} | ||
| </h3> | ||
| <p className="text-xs text-neutral-500 dark:text-neutral-400"> | ||
| {specialRoles[member.login.toLowerCase()]?.role || 'Maintainer'} | ||
| </p> | ||
| <div className="mt-3 flex gap-2"> | ||
| <Link | ||
| href={`https://github.com/${member.login}`} | ||
| target="_blank" | ||
| className="rounded-md p-1 text-neutral-600 transition-colors hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-white" | ||
| > | ||
| <Github className="h-4 w-4" /> | ||
| </Link> | ||
| {specialRoles[member.login.toLowerCase()]?.twitter && ( | ||
| <Link | ||
| href={`https://twitter.com/${specialRoles[member.login.toLowerCase()]?.twitter}`} | ||
| target="_blank" | ||
| className="rounded-md p-1 text-neutral-600 transition-colors hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-white" | ||
| > | ||
| <Twitter className="h-4 w-4" /> | ||
| </Link> | ||
| )} | ||
| {specialRoles[member.login.toLowerCase()]?.website && ( | ||
| <Link | ||
| href={specialRoles[member.login.toLowerCase()]?.website || '#'} | ||
| target="_blank" | ||
| className="rounded-md p-1 text-neutral-600 transition-colors hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-white" | ||
| > | ||
| <svg | ||
| className="h-4 w-4" | ||
| fill="none" | ||
| stroke="currentColor" | ||
| viewBox="0 0 24 24" | ||
| aria-hidden="true" | ||
| > | ||
| <path | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth="2" | ||
| d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" | ||
| /> | ||
| </svg> | ||
| </Link> | ||
| )} | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ))} | ||
| </div> | ||
| </div> | ||
|
|
||
| {/* Contributors Section */} | ||
| <div className="mb-16 space-y-6"> | ||
| <div className="text-center"> | ||
| <h1 className="text-3xl font-semibold tracking-tight text-neutral-900/80 dark:text-white"> | ||
| Contributors | ||
| </h1> | ||
| <div className="text-muted-foreground mt-2 flex items-center justify-center gap-2"> | ||
| <span>Thank you to all the contributors who have helped make 0.email possible</span> | ||
| </div> | ||
| </div> | ||
|
|
||
| <style jsx global>{` | ||
| @keyframes fadeInUp { | ||
| from { | ||
| opacity: 0; | ||
| transform: translateY(10px); | ||
| } | ||
| to { | ||
| opacity: 1; | ||
| transform: translateY(0); | ||
| } | ||
| } | ||
| `}</style> | ||
|
|
||
| <div> | ||
| <Tabs defaultValue="grid" className="w-full"> | ||
| <div className="mb-6 flex justify-center"> | ||
| <TabsList className="grid h-full w-full grid-cols-2 border border-neutral-200 bg-white/50 p-1 sm:w-[200px] dark:border-neutral-800 dark:bg-neutral-900/50"> | ||
| <TabsTrigger | ||
| value="grid" | ||
| className="flex items-center gap-2 text-neutral-600 data-[state=active]:bg-white data-[state=active]:text-neutral-900 data-[state=active]:shadow-sm dark:text-neutral-400 dark:data-[state=active]:bg-neutral-800 dark:data-[state=active]:text-white" | ||
| > | ||
| <LayoutGrid className="h-4 w-4" /> | ||
| Grid | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="chart" | ||
| className="flex items-center gap-2 text-neutral-600 data-[state=active]:bg-white data-[state=active]:text-neutral-900 data-[state=active]:shadow-sm dark:text-neutral-400 dark:data-[state=active]:bg-neutral-800 dark:data-[state=active]:text-white" | ||
| > | ||
| <ChartAreaIcon className="h-4 w-4" /> | ||
| Chart | ||
| </TabsTrigger> | ||
| </TabsList> | ||
| </div> | ||
|
|
||
| <TabsContent value="grid"> | ||
| <div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6"> | ||
| {filteredContributors?.map((contributor, index) => ( | ||
| <Link | ||
| key={contributor.login} | ||
| href={contributor.html_url} | ||
| target="_blank" | ||
| className="group relative flex flex-col items-center rounded-xl border bg-white/50 p-4 transition-all hover:-translate-y-1 hover:bg-white hover:shadow-lg dark:border-neutral-800 dark:bg-neutral-900/50 dark:hover:bg-neutral-900 dark:hover:shadow-neutral-900/50" | ||
| style={{ | ||
| animationDelay: `${index * 50}ms`, | ||
| animation: 'fadeInUp 0.5s ease-out forwards', | ||
| opacity: 0, | ||
| transform: 'translateY(10px)', | ||
| }} | ||
| > | ||
| <Avatar className="h-16 w-16 rounded-full ring-2 ring-neutral-200 transition-transform group-hover:scale-105 group-hover:ring-neutral-300 dark:ring-neutral-800 dark:group-hover:ring-neutral-700"> | ||
| <AvatarImage | ||
| src={contributor.avatar_url} | ||
| alt={contributor.login} | ||
| className="object-cover" | ||
| /> | ||
| <AvatarFallback className="text-xs"> | ||
| {contributor.login.slice(0, 2).toUpperCase()} | ||
| </AvatarFallback> | ||
| </Avatar> | ||
|
|
||
| <div className="mt-3 text-center"> | ||
| <span className="block text-sm font-medium text-neutral-900 transition-colors group-hover:text-neutral-700 dark:text-neutral-200 dark:group-hover:text-white"> | ||
| {contributor.login} | ||
| </span> | ||
| <div className="mt-2 flex items-center justify-center gap-1"> | ||
| <GitGraph className="h-3 w-3 text-neutral-500 transition-colors group-hover:text-neutral-700 dark:text-neutral-400 dark:group-hover:text-neutral-300" /> | ||
| <span className="text-sm font-medium text-neutral-700 transition-colors group-hover:text-neutral-900 dark:text-neutral-300 dark:group-hover:text-white"> | ||
| {contributor.contributions} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </Link> | ||
| ))} | ||
| </div> | ||
| </TabsContent> | ||
|
|
||
| <TabsContent value="chart"> | ||
| <Card className="bg-white/50 p-6 dark:bg-neutral-900/50"> | ||
| <ChartControls | ||
| showAll={showAllContributors} | ||
| setShowAll={setShowAllContributors} | ||
| total={filteredContributors?.length || 0} | ||
| /> | ||
|
|
||
| <ResponsiveContainer width="100%" height={400}> | ||
| <BarChart | ||
| data={filteredContributors?.slice(0, showAllContributors ? undefined : 10)} | ||
| margin={{ top: 10, right: 10, bottom: 20, left: 10 }} | ||
| > | ||
| <XAxis | ||
| dataKey="login" | ||
| interval={0} | ||
| tick={(props) => { | ||
| const { x, y, payload } = props; | ||
| const contributor = allContributors?.find( | ||
| (c) => c.login === payload.value, | ||
| ); | ||
|
|
||
| return ( | ||
| <g transform={`translate(${x},${y})`}> | ||
| <foreignObject x="-12" y="8" width="24" height="24"> | ||
| <Avatar className="h-6 w-6 rounded-full ring-1 ring-neutral-200 dark:ring-neutral-800"> | ||
| <AvatarImage src={contributor?.avatar_url} /> | ||
| <AvatarFallback className="text-[8px]"> | ||
| {payload.value.slice(0, 2).toUpperCase()} | ||
| </AvatarFallback> | ||
| </Avatar> | ||
| </foreignObject> | ||
| </g> | ||
| ); | ||
| }} | ||
| height={60} | ||
| className="text-neutral-600 dark:text-neutral-400" | ||
| /> | ||
| <YAxis | ||
| stroke="currentColor" | ||
| fontSize={12} | ||
| tickLine={false} | ||
| axisLine={false} | ||
| tickFormatter={(value) => `${value}`} | ||
| className="text-neutral-600 dark:text-neutral-400" | ||
| /> | ||
| <Tooltip | ||
| cursor={{ fill: 'rgb(0 0 0 / 0.05)' }} | ||
| content={({ active, payload }) => { | ||
| if (active && payload && payload.length) { | ||
| const data = payload[0]?.payload; | ||
| return ( | ||
| <div className="rounded-lg border border-neutral-200 bg-white p-3 shadow-lg dark:border-neutral-800 dark:bg-neutral-900"> | ||
| <div className="flex items-center gap-2"> | ||
| <Avatar className="h-8 w-8 ring-1 ring-neutral-200 dark:ring-neutral-800"> | ||
| <AvatarImage src={data.avatar_url} /> | ||
| <AvatarFallback> | ||
| {data.login.slice(0, 2).toUpperCase()} | ||
| </AvatarFallback> | ||
| </Avatar> | ||
| <div> | ||
| <div className="text-sm font-medium text-neutral-900 dark:text-white"> | ||
| {data.login} | ||
| </div> | ||
| <div className="flex items-center gap-1 text-xs text-neutral-600 dark:text-neutral-400"> | ||
| <GitGraph className="h-3 w-3" /> | ||
| <span>{data.contributions} commits</span> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
| return null; | ||
| }} | ||
| /> | ||
| <Bar | ||
| dataKey="contributions" | ||
| className="fill-neutral-900 dark:fill-white" | ||
| radius={[4, 4, 0, 0]} | ||
| /> | ||
| </BarChart> | ||
| </ResponsiveContainer> | ||
| </Card> | ||
| </TabsContent> | ||
| </Tabs> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="mb-8"> | ||
| <div className="relative overflow-hidden rounded-xl border bg-gradient-to-br from-neutral-50 to-white shadow-sm dark:border-neutral-800 dark:from-neutral-900/80 dark:to-neutral-900/30"> | ||
| <div className="absolute inset-0 opacity-20 dark:opacity-20"></div> | ||
|
|
||
| <div className="relative p-6"> | ||
| <div className="flex flex-col items-center gap-8 md:flex-row"> | ||
| <div className="w-full md:w-2/3"> | ||
| <div className="inline-flex items-center rounded-full bg-neutral-900 px-3 py-1 text-xs font-medium text-white dark:bg-white dark:text-neutral-900"> | ||
| <Github className="mr-1.5 h-3.5 w-3.5" /> | ||
| We are open source | ||
| </div> | ||
| <h2 className="mt-3 text-2xl font-bold tracking-tight text-neutral-900 dark:text-white"> | ||
| Let's build the future of email together | ||
| </h2> | ||
| <p className="mt-3 text-neutral-600 dark:text-neutral-300"> | ||
| Whether you're fixing bugs, adding features, or improving documentation, | ||
| every contribution matters. | ||
| </p> | ||
| <div className="mt-5 flex flex-wrap gap-3"> | ||
| <Button | ||
| asChild | ||
| className="relative overflow-hidden bg-neutral-900 text-white transition-all hover:bg-neutral-800 dark:bg-white dark:text-neutral-900 dark:hover:bg-neutral-100" | ||
| > | ||
| <Link | ||
| href={`https://github.com/${REPOSITORY}/blob/main/.github/CONTRIBUTING.md`} | ||
| target="_blank" | ||
| > | ||
| <span className="relative z-10 flex items-center"> | ||
| <GitGraph className="mr-2 h-4 w-4" /> | ||
| Start Contributing | ||
| </span> | ||
| </Link> | ||
| </Button> | ||
| <Button | ||
| asChild | ||
| variant="outline" | ||
| className="gap-2 border-neutral-200 bg-white/80 text-neutral-700 hover:bg-neutral-100 hover:text-neutral-900 dark:border-neutral-700 dark:bg-neutral-900/50 dark:text-neutral-200 dark:hover:bg-neutral-800 dark:hover:text-white" | ||
| > | ||
| <Link href={`https://github.com/${REPOSITORY}/issues`} target="_blank"> | ||
| <MessageCircle className="h-4 w-4" /> | ||
| Open Issues | ||
| </Link> | ||
| </Button> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="hidden md:block md:w-1/3"> | ||
| <div className="space-y-4 rounded-xl border border-neutral-200 bg-white/80 p-5 backdrop-blur-sm dark:border-neutral-800 dark:bg-neutral-900/80"> | ||
| <div className="flex items-center gap-4"> | ||
| <div className="flex -space-x-2"> | ||
| {filteredContributors?.slice(0, 5).map((contributor) => ( | ||
| <Avatar | ||
| key={contributor.login} | ||
| className="h-8 w-8 border-2 border-white dark:border-neutral-900" | ||
| > | ||
| <AvatarImage src={contributor.avatar_url} alt={contributor.login} /> | ||
| <AvatarFallback className="text-xs"> | ||
| {contributor.login.slice(0, 2).toUpperCase()} | ||
| </AvatarFallback> | ||
| </Avatar> | ||
| ))} | ||
| {filteredContributors && filteredContributors.length > 5 && ( | ||
| <div className="flex h-8 w-8 items-center justify-center rounded-full border-2 border-white bg-neutral-100 text-xs font-medium text-neutral-800 dark:border-neutral-900 dark:bg-neutral-800 dark:text-neutral-200"> | ||
| +{filteredContributors.length - 5} | ||
| </div> | ||
| )} | ||
| </div> | ||
| <div className="text-sm text-neutral-600 dark:text-neutral-300"> | ||
| <span className="font-semibold text-neutral-900 dark:text-white"> | ||
| {filteredContributors?.length || 0} | ||
| </span>{' '} | ||
| contributors | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="grid grid-cols-2 gap-3"> | ||
| <div className="rounded-lg bg-neutral-50 p-2 dark:bg-neutral-800/50"> | ||
| <div className="text-xs text-neutral-500 dark:text-neutral-400">Stars</div> | ||
| <div className="mt-1 flex items-center gap-1"> | ||
| <Star className="h-3.5 w-3.5 text-neutral-700 dark:text-neutral-300" /> | ||
| <span className="text-sm font-semibold text-neutral-900 dark:text-white"> | ||
| {repoStats.stars} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| <div className="rounded-lg bg-neutral-50 p-2 dark:bg-neutral-800/50"> | ||
| <div className="text-xs text-neutral-500 dark:text-neutral-400">Forks</div> | ||
| <div className="mt-1 flex items-center gap-1"> | ||
| <GitFork className="h-3.5 w-3.5 text-neutral-700 dark:text-neutral-300" /> | ||
| <span className="text-sm font-semibold text-neutral-900 dark:text-white"> | ||
| {repoStats.forks} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="mb-6 mt-2 flex items-center justify-center gap-4"> | ||
| <Link | ||
| href="https://discord.gg/BCFr6FFt" | ||
| target="_blank" | ||
| className="text-neutral-500 transition-colors hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200" | ||
| aria-label="Join our Discord" | ||
| > | ||
| <Discord className="h-4 w-4" /> | ||
| </Link> | ||
| <Link | ||
| href="https://x.com/zerodotemail" | ||
| target="_blank" | ||
| className="text-neutral-500 transition-colors hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200" | ||
| aria-label="Follow us on X (Twitter)" | ||
| > | ||
| <Twitter className="h-4 w-4" /> | ||
| </Link> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Complex Component Rendering – Consider Refactoring
The component renders multiple sections for project stats, charts, core team, and contributors. Although functionally correct, the file is becoming quite large by handling data fetching, state management, and UI rendering all in one place. For long-term maintainability, consider splitting these responsibilities into smaller, dedicated subcomponents.
bulkSelectedthreadsSummary by CodeRabbit
These updates are entirely internal and do not affect the app’s functionality or user experience.