refactor: replace Loader2 with Spinner component across various components for consistent loading indicators

This commit is contained in:
Anish Sarkar 2026-02-08 12:39:06 +05:30
parent ac394e78cc
commit 5ab672b8ff
8 changed files with 46 additions and 43 deletions

View file

@ -11,7 +11,6 @@ import {
Clock,
FileText,
FileX,
Loader2,
Network,
Plus,
User,
@ -361,7 +360,7 @@ export function DocumentsTableShell({
<TableHead className="w-[15%] min-w-[100px] max-w-[170px] border-r border-border/40">
<Skeleton className="h-3 w-14" />
</TableHead>
)}
)}
{columnVisibility.created_by && (
<TableHead className="w-36 border-r border-border/40">
<Skeleton className="h-3 w-10" />
@ -773,7 +772,7 @@ export function DocumentsTableShell({
<div className="mt-4">
{viewingLoading ? (
<div className="flex items-center justify-center py-12">
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
<Spinner size="lg" className="text-muted-foreground" />
</div>
) : (
<MarkdownViewer content={viewingContent} />

View file

@ -2,12 +2,13 @@
import { IconCalendar, IconMailFilled } from "@tabler/icons-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Check, ExternalLink, Gift, Loader2, Mail, Star } from "lucide-react";
import { Check, ExternalLink, Gift, Mail, Star } from "lucide-react";
import { motion } from "motion/react";
import Link from "next/link";
import { useEffect } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { Card, CardContent } from "@/components/ui/card";
import {
Dialog,
@ -144,7 +145,7 @@ export default function MorePagesPage() {
className="gap-1"
>
{completeMutation.isPending ? (
<Loader2 className="h-3 w-3 animate-spin" />
<Spinner size="xs" />
) : (
<>
Go

View file

@ -1,10 +1,11 @@
"use client";
import { BadgeCheck, Loader2, LogOut } from "lucide-react";
import { BadgeCheck, LogOut } from "lucide-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import {
DropdownMenu,
DropdownMenuContent,
@ -97,9 +98,9 @@ export function UserDropdown({
className="text-xs md:text-sm"
disabled={isLoggingOut}
>
{isLoggingOut ? (
<Loader2 className="mr-2 h-3.5 w-3.5 md:h-4 md:w-4 animate-spin" />
) : (
{isLoggingOut ? (
<Spinner size="sm" className="mr-2" />
) : (
<LogOut className="mr-2 h-3.5 w-3.5 md:h-4 md:w-4" />
)}
{isLoggingOut ? "Logging out..." : "Log out"}

View file

@ -19,7 +19,6 @@ import {
ChevronRightIcon,
CopyIcon,
DownloadIcon,
Loader2,
RefreshCwIcon,
SquareIcon,
} from "lucide-react";
@ -61,6 +60,7 @@ import {
} from "@/components/new-chat/document-mention-picker";
import type { ThinkingStep } from "@/components/tool-ui/deepagent-thinking";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import type { Document } from "@/contracts/types/document.types";
import { useCommentsElectric } from "@/hooks/use-comments-electric";
import { cn } from "@/lib/utils";
@ -542,7 +542,7 @@ const ComposerAction: FC<ComposerActionProps> = ({ isBlockedByOtherUser = false
{/* Show processing indicator when attachments are being processed */}
{hasProcessingAttachments && (
<div className="flex items-center gap-1.5 text-muted-foreground text-xs">
<Loader2 className="size-3 animate-spin" />
<Spinner size="xs" />
<span>Processing...</span>
</div>
)}

View file

@ -1,7 +1,8 @@
import { FileJson, Loader2 } from "lucide-react";
import { FileJson } from "lucide-react";
import React from "react";
import { defaultStyles, JsonView } from "react-json-view-lite";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import {
Dialog,
DialogContent,
@ -58,7 +59,7 @@ export function JsonMetadataViewer({
<div className="mt-2 sm:mt-4 p-2 sm:p-4 bg-muted/30 rounded-md text-xs sm:text-sm">
{loading ? (
<div className="flex items-center justify-center py-12">
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
<Spinner size="lg" className="text-muted-foreground" />
</div>
) : (
<JsonView data={jsonData} style={defaultStyles} />

View file

@ -5,7 +5,6 @@ import {
ChevronUp,
Languages,
Laptop,
Loader2,
LogOut,
Moon,
Settings,
@ -27,6 +26,7 @@ import {
} from "@/components/ui/dropdown-menu";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { useLocaleContext } from "@/contexts/LocaleContext";
import { Spinner } from "@/components/ui/spinner";
import { cn } from "@/lib/utils";
import type { User } from "../../types/layout.types";
@ -264,18 +264,18 @@ export function SidebarUserProfile({
<DropdownMenuSeparator />
<DropdownMenuItem onClick={handleLogout} disabled={isLoggingOut}>
{isLoggingOut ? (
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
) : (
<LogOut className="mr-2 h-4 w-4" />
)}
{isLoggingOut ? t("loggingOut") : t("logout")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
);
<DropdownMenuItem onClick={handleLogout} disabled={isLoggingOut}>
{isLoggingOut ? (
<Spinner size="sm" className="mr-2" />
) : (
<LogOut className="mr-2 h-4 w-4" />
)}
{isLoggingOut ? t("loggingOut") : t("logout")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
);
}
// Expanded view
@ -386,16 +386,16 @@ export function SidebarUserProfile({
<DropdownMenuSeparator />
<DropdownMenuItem onClick={handleLogout} disabled={isLoggingOut}>
{isLoggingOut ? (
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
) : (
<LogOut className="mr-2 h-4 w-4" />
)}
{isLoggingOut ? t("loggingOut") : t("logout")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<DropdownMenuItem onClick={handleLogout} disabled={isLoggingOut}>
{isLoggingOut ? (
<Spinner size="sm" className="mr-2" />
) : (
<LogOut className="mr-2 h-4 w-4" />
)}
{isLoggingOut ? t("loggingOut") : t("logout")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
);
}

View file

@ -1,10 +1,11 @@
"use client";
import { Copy, Loader2 } from "lucide-react";
import { Copy } from "lucide-react";
import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { publicChatApiService } from "@/lib/apis/public-chat-api.service";
import { getBearerToken } from "@/lib/auth-utils";
@ -61,9 +62,9 @@ export function PublicChatFooter({ shareToken }: PublicChatFooterProps) {
};
return (
<div className="mx-auto flex max-w-(--thread-max-width) items-center justify-center px-4 py-4">
<Button size="lg" onClick={handleCopyAndContinue} disabled={isCloning} className="gap-2">
{isCloning ? <Loader2 className="size-4 animate-spin" /> : <Copy className="size-4" />}
<div className="fixed bottom-6 left-1/2 z-50 -translate-x-1/2">
<Button size="lg" onClick={handleCopyAndContinue} disabled={isCloning} className="gap-2 rounded-full px-6 shadow-lg transition-all duration-200 hover:scale-[1.02] hover:shadow-xl hover:brightness-110 hover:bg-primary">
{isCloning ? <Spinner size="sm" /> : <Copy className="size-4" />}
Copy and continue this chat
</Button>
</div>

View file

@ -1,8 +1,8 @@
"use client";
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { Loader2 } from "lucide-react";
import { Navbar } from "@/components/homepage/navbar";
import { Spinner } from "@/components/ui/spinner";
import { DisplayImageToolUI } from "@/components/tool-ui/display-image";
import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
import { LinkPreviewToolUI } from "@/components/tool-ui/link-preview";
@ -26,7 +26,7 @@ export function PublicChatView({ shareToken }: PublicChatViewProps) {
<main className="min-h-screen bg-linear-to-b from-gray-50 to-gray-100 text-gray-900 dark:from-black dark:to-gray-900 dark:text-white overflow-x-hidden">
<Navbar />
<div className="flex h-screen items-center justify-center">
<Loader2 className="size-8 animate-spin text-muted-foreground" />
<Spinner size="lg" className="text-muted-foreground" />
</div>
</main>
);