ui: replace custom loading spinners with IconSpinner component across multiple files
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import {Button} from '@plunk/ui';
|
||||
import {Button, IconSpinner} from '@plunk/ui';
|
||||
import type {Activity, CursorPaginatedResponse} from '@plunk/types';
|
||||
import {network} from '../lib/network';
|
||||
import {ActivityItem} from './ActivityItem';
|
||||
import {EmptyState} from './EmptyState';
|
||||
import {Activity as ActivityIcon, Loader2} from 'lucide-react';
|
||||
import {Activity as ActivityIcon} from 'lucide-react';
|
||||
import {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
|
||||
export interface ActivityFeedProps {
|
||||
@@ -169,7 +169,7 @@ export function ActivityFeed({typeFilter, dateRangeDays = 30, contactId}: Activi
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-neutral-400" />
|
||||
<IconSpinner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -215,7 +215,7 @@ export function ActivityFeed({typeFilter, dateRangeDays = 30, contactId}: Activi
|
||||
<Button onClick={loadMore} variant="outline" disabled={isLoadingMore}>
|
||||
{isLoadingMore ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin mr-2" />
|
||||
<IconSpinner size="sm" className="mr-2" />
|
||||
Loading...
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Alert, Card, CardContent, CardDescription, CardHeader, CardTitle} from '@plunk/ui';
|
||||
import {Alert, Card, CardContent, CardDescription, CardHeader, CardTitle, IconSpinner} from '@plunk/ui';
|
||||
import {AlertCircle, Coins, TrendingUp} from 'lucide-react';
|
||||
import {useBillingConsumption} from '../lib/hooks/useBillingConsumption';
|
||||
import {useConfig} from '../lib/hooks/useConfig';
|
||||
@@ -67,7 +67,9 @@ export function BillingConsumption({projectId, hasSubscription}: BillingConsumpt
|
||||
<CardDescription>View your current month email consumption and costs</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-neutral-500">Loading...</p>
|
||||
<div className="flex items-center justify-center py-4">
|
||||
<IconSpinner size="sm" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Alert, Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle} from '@plunk/ui';
|
||||
import {Alert, Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, IconSpinner} from '@plunk/ui';
|
||||
import {AlertCircle, Download, ExternalLink, FileText} from 'lucide-react';
|
||||
import {useBillingInvoices} from '../lib/hooks/useBillingInvoices';
|
||||
|
||||
@@ -41,7 +41,9 @@ export function BillingInvoices({projectId, hasSubscription, onManageBilling}: B
|
||||
<CardDescription>View and download your billing history</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-neutral-500">Loading...</p>
|
||||
<div className="flex items-center justify-center py-4">
|
||||
<IconSpinner size="sm" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
IconSpinner,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
@@ -146,7 +147,9 @@ export function BillingLimits({projectId, hasSubscription, billingEnabled}: Bill
|
||||
<CardDescription>Set monthly limits for each email category</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-neutral-500">Loading...</p>
|
||||
<div className="flex items-center justify-center py-4">
|
||||
<IconSpinner size="sm" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
IconSpinner,
|
||||
SelectValue,
|
||||
} from '@plunk/ui';
|
||||
import type {Campaign} from '@plunk/db';
|
||||
@@ -167,22 +168,7 @@ export function CampaignSelectionDialog({open, onOpenChange, onSelectCampaign}:
|
||||
<div className="flex-1 overflow-y-auto space-y-3">
|
||||
{isLoading && (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<div className="text-center">
|
||||
<svg
|
||||
className="h-8 w-8 animate-spin mx-auto text-neutral-900"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
||||
<path
|
||||
className="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
/>
|
||||
</svg>
|
||||
<p className="mt-2 text-sm text-neutral-500">Loading campaigns...</p>
|
||||
</div>
|
||||
<IconSpinner />
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -20,8 +20,9 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
IconSpinner,
|
||||
} from '@plunk/ui';
|
||||
import {AlertCircle, Database, Loader2, Trash2, Zap} from 'lucide-react';
|
||||
import {AlertCircle, Database, Trash2, Zap} from 'lucide-react';
|
||||
import {EmptyState} from './EmptyState';
|
||||
import {toast} from 'sonner';
|
||||
import useSWR from 'swr';
|
||||
@@ -345,7 +346,7 @@ export function DataManagementSettings() {
|
||||
isDeleting || (!!selectedField && !fieldUsage?.canDelete) || (!!selectedEvent && !eventUsage?.canDelete)
|
||||
}
|
||||
>
|
||||
{isDeleting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
{isDeleting && <IconSpinner size="sm" className="mr-2" />}
|
||||
Delete
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
@@ -17,10 +17,11 @@ import {
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
IconSpinner,
|
||||
Input,
|
||||
} from '@plunk/ui';
|
||||
import {AnimatePresence, motion} from 'framer-motion';
|
||||
import {Check, CheckCircle2, ChevronDown, Copy, Globe, Loader2, RefreshCw, Trash2, XCircle} from 'lucide-react';
|
||||
import {Check, CheckCircle2, ChevronDown, Copy, Globe, RefreshCw, Trash2, XCircle} from 'lucide-react';
|
||||
import {EmptyState} from './EmptyState';
|
||||
import {useConfig} from '../lib/hooks/useConfig';
|
||||
import {useAddDomain, useCheckDomainVerification, useDomains, useRemoveDomain} from '../lib/hooks/useDomains';
|
||||
@@ -322,7 +323,7 @@ export function DomainsSettings({projectId}: DomainsSettingsProps) {
|
||||
<CardContent>
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-neutral-400" />
|
||||
<IconSpinner />
|
||||
</div>
|
||||
) : !domains || domains.length === 0 ? (
|
||||
<EmptyState
|
||||
@@ -360,7 +361,7 @@ export function DomainsSettings({projectId}: DomainsSettingsProps) {
|
||||
className="min-w-[80px]"
|
||||
>
|
||||
{checkingVerification === domain.id ? (
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
<IconSpinner size="sm" />
|
||||
) : (cooldownSeconds[domain.id] ?? 0) > 0 ? (
|
||||
<span className="text-xs">{cooldownSeconds[domain.id]}s</span>
|
||||
) : (
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
IconSpinner,
|
||||
} from '@plunk/ui';
|
||||
import {MembershipSchemas} from '@plunk/shared';
|
||||
import {MoreVertical, Trash2, UserPlus} from 'lucide-react';
|
||||
@@ -221,7 +222,7 @@ export function TeamSettings({projectId, currentUserRole, currentUserId}: TeamSe
|
||||
<CardContent>
|
||||
{isLoading ? (
|
||||
<div className="flex justify-center py-8">
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-neutral-200 border-t-neutral-900" />
|
||||
<IconSpinner />
|
||||
</div>
|
||||
) : members.length === 0 ? (
|
||||
<div className="py-8 text-center text-sm text-neutral-500">No members found</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
IconSpinner,
|
||||
Input,
|
||||
Label,
|
||||
} from '@plunk/ui';
|
||||
@@ -205,25 +206,9 @@ export function TemplateSelectionDialog({open, onOpenChange, onSelectTemplate}:
|
||||
<div className="flex-1 overflow-y-auto space-y-3">
|
||||
{isLoading && (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<div className="text-center">
|
||||
<svg
|
||||
className="h-8 w-8 animate-spin mx-auto text-neutral-900"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
||||
<path
|
||||
className="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
/>
|
||||
</svg>
|
||||
<p className="mt-2 text-sm text-neutral-500">Loading templates...</p>
|
||||
</div>
|
||||
<IconSpinner />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isLoading && data?.data.length === 0 && (
|
||||
<EmptyState
|
||||
icon={FileText}
|
||||
|
||||
Reference in New Issue
Block a user