58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useTransition } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { RefreshCw } from 'lucide-react';
|
|
import { triggerPolicySync } from '@/lib/actions/policySettings';
|
|
import { toast } from 'sonner';
|
|
|
|
export function SyncButton() {
|
|
const [isPending, startTransition] = useTransition();
|
|
const [lastJobId, setLastJobId] = useState<string | null>(null);
|
|
|
|
const handleSync = () => {
|
|
startTransition(async () => {
|
|
try {
|
|
const result = await triggerPolicySync();
|
|
|
|
if (result.success && result.jobId) {
|
|
setLastJobId(result.jobId);
|
|
toast.success(result.message ?? `Sync queued (Job #${result.jobId})`);
|
|
} else {
|
|
toast.error(result.error ?? 'Failed to trigger sync');
|
|
}
|
|
} catch (error) {
|
|
toast.error('An unexpected error occurred');
|
|
}
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<Button
|
|
onClick={handleSync}
|
|
disabled={isPending}
|
|
variant="default"
|
|
size="default"
|
|
>
|
|
{isPending ? (
|
|
<>
|
|
<RefreshCw className="mr-2 h-4 w-4 animate-spin" />
|
|
Queuing...
|
|
</>
|
|
) : (
|
|
<>
|
|
<RefreshCw className="mr-2 h-4 w-4" />
|
|
Sync Policies
|
|
</>
|
|
)}
|
|
</Button>
|
|
{lastJobId && (
|
|
<span className="text-sm text-muted-foreground">
|
|
Last job: #{lastJobId}
|
|
</span>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|