keywrods libarry update
This commit is contained in:
185
frontend/src/components/keywords-library/BulkAddConfirmation.tsx
Normal file
185
frontend/src/components/keywords-library/BulkAddConfirmation.tsx
Normal file
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* BulkAddConfirmation - Confirmation modal for bulk adding keywords
|
||||
* Shows preview of keywords to be added and handles the bulk add action
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Modal } from '../ui/modal';
|
||||
import Button from '../ui/button/Button';
|
||||
import { PlusIcon, CheckCircleIcon, AlertIcon } from '../../icons';
|
||||
import { Spinner } from '../ui/spinner/Spinner';
|
||||
|
||||
interface BulkAddConfirmationProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onConfirm: () => Promise<{ added: number; skipped: number; total_requested: number }>;
|
||||
keywordCount: number;
|
||||
sectorName?: string;
|
||||
statTypeLabel?: string;
|
||||
}
|
||||
|
||||
export default function BulkAddConfirmation({
|
||||
isOpen,
|
||||
onClose,
|
||||
onConfirm,
|
||||
keywordCount,
|
||||
sectorName,
|
||||
statTypeLabel,
|
||||
}: BulkAddConfirmationProps) {
|
||||
const [isAdding, setIsAdding] = useState(false);
|
||||
const [result, setResult] = useState<{ added: number; skipped: number; total_requested: number } | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const handleConfirm = async () => {
|
||||
setIsAdding(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const response = await onConfirm();
|
||||
setResult(response);
|
||||
} catch (err: any) {
|
||||
setError(err.message || 'Failed to add keywords');
|
||||
} finally {
|
||||
setIsAdding(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setResult(null);
|
||||
setError(null);
|
||||
onClose();
|
||||
};
|
||||
|
||||
// Success state
|
||||
if (result) {
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={handleClose} showCloseButton={true}>
|
||||
<div className="p-6 text-center">
|
||||
<div className="mx-auto w-14 h-14 rounded-full bg-success-100 dark:bg-success-900/30 flex items-center justify-center mb-4">
|
||||
<CheckCircleIcon className="w-8 h-8 text-success-600 dark:text-success-400" />
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
||||
Keywords Added Successfully!
|
||||
</h3>
|
||||
|
||||
<div className="space-y-2 mb-6">
|
||||
<p className="text-3xl font-bold text-success-600 dark:text-success-400">
|
||||
{result.added}
|
||||
</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
keywords added to your site
|
||||
</p>
|
||||
|
||||
{result.skipped > 0 && (
|
||||
<p className="text-sm text-amber-600 dark:text-amber-400">
|
||||
{result.skipped} keywords were skipped (already exist)
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Button onClick={handleClose} variant="primary">
|
||||
Done
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
// Error state
|
||||
if (error) {
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={handleClose} showCloseButton={true}>
|
||||
<div className="p-6 text-center">
|
||||
<div className="mx-auto w-14 h-14 rounded-full bg-error-100 dark:bg-error-900/30 flex items-center justify-center mb-4">
|
||||
<AlertIcon className="w-8 h-8 text-error-600 dark:text-error-400" />
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
||||
Failed to Add Keywords
|
||||
</h3>
|
||||
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
|
||||
{error}
|
||||
</p>
|
||||
|
||||
<div className="flex gap-3 justify-center">
|
||||
<Button onClick={handleClose} variant="outline">
|
||||
Close
|
||||
</Button>
|
||||
<Button onClick={handleConfirm} variant="primary">
|
||||
Try Again
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
// Confirmation state
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={handleClose} showCloseButton={!isAdding}>
|
||||
<div className="p-6">
|
||||
<div className="text-center mb-6">
|
||||
<div className="mx-auto w-14 h-14 rounded-full bg-brand-100 dark:bg-brand-900/30 flex items-center justify-center mb-4">
|
||||
<PlusIcon className="w-8 h-8 text-brand-600 dark:text-brand-400" />
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
||||
Add Keywords to Your Site
|
||||
</h3>
|
||||
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
You're about to add keywords to your site's keyword list.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Summary */}
|
||||
<div className="bg-gray-50 dark:bg-gray-800/50 rounded-lg p-4 mb-6">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-sm text-gray-600 dark:text-gray-400">Keywords to add:</span>
|
||||
<span className="text-lg font-bold text-gray-900 dark:text-white">{keywordCount}</span>
|
||||
</div>
|
||||
|
||||
{sectorName && (
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-sm text-gray-600 dark:text-gray-400">Sector:</span>
|
||||
<span className="text-sm font-medium text-gray-900 dark:text-white">{sectorName}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{statTypeLabel && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-gray-600 dark:text-gray-400">Category:</span>
|
||||
<span className="text-sm font-medium text-gray-900 dark:text-white">{statTypeLabel}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex gap-3 justify-end">
|
||||
<Button onClick={handleClose} variant="outline" disabled={isAdding}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleConfirm}
|
||||
variant="primary"
|
||||
disabled={isAdding}
|
||||
>
|
||||
{isAdding ? (
|
||||
<span className="flex items-center gap-2">
|
||||
<Spinner size="sm" />
|
||||
Adding...
|
||||
</span>
|
||||
) : (
|
||||
<span className="flex items-center gap-2">
|
||||
<PlusIcon className="w-4 h-4" />
|
||||
Add {keywordCount} Keywords
|
||||
</span>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user