- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8 - Actualizaciones de configuracion Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
110 lines
3.7 KiB
TypeScript
110 lines
3.7 KiB
TypeScript
import { HardDrive, Folder } from 'lucide-react';
|
|
import { useStorageUsage } from '@/hooks/useStorage';
|
|
|
|
interface StorageUsageCardProps {
|
|
className?: string;
|
|
}
|
|
|
|
function formatBytes(bytes: number): string {
|
|
if (bytes < 1024) return `${bytes} B`;
|
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
}
|
|
|
|
export function StorageUsageCard({ className = '' }: StorageUsageCardProps) {
|
|
const { data, isLoading, error } = useStorageUsage();
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className={`bg-white rounded-lg border p-6 ${className}`}>
|
|
<div className="animate-pulse">
|
|
<div className="h-4 bg-gray-200 rounded w-1/3 mb-4" />
|
|
<div className="h-8 bg-gray-200 rounded w-1/2 mb-4" />
|
|
<div className="h-2 bg-gray-200 rounded w-full" />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error || !data) {
|
|
return (
|
|
<div className={`bg-white rounded-lg border p-6 ${className}`}>
|
|
<p className="text-gray-500">Unable to load storage usage</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const usedPercent = data.maxBytes ? data.usagePercent : 0;
|
|
const progressColor =
|
|
usedPercent > 90 ? 'bg-red-500' : usedPercent > 70 ? 'bg-yellow-500' : 'bg-blue-500';
|
|
|
|
return (
|
|
<div className={`bg-white rounded-lg border p-6 ${className}`}>
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="p-2 bg-blue-100 rounded-lg">
|
|
<HardDrive className="w-5 h-5 text-blue-600" />
|
|
</div>
|
|
<h3 className="font-semibold text-gray-900">Storage Usage</h3>
|
|
</div>
|
|
|
|
{/* Usage stats */}
|
|
<div className="space-y-4">
|
|
<div>
|
|
<div className="flex justify-between text-sm mb-1">
|
|
<span className="text-gray-600">
|
|
{formatBytes(data.totalBytes)} used
|
|
</span>
|
|
{data.maxBytes && (
|
|
<span className="text-gray-500">
|
|
of {formatBytes(data.maxBytes)}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
{data.maxBytes && (
|
|
<div className="w-full bg-gray-200 rounded-full h-2">
|
|
<div
|
|
className={`${progressColor} h-2 rounded-full transition-all duration-300`}
|
|
style={{ width: `${Math.min(usedPercent, 100)}%` }}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Files count */}
|
|
<div className="flex justify-between text-sm">
|
|
<span className="text-gray-600">Total files</span>
|
|
<span className="font-medium">{data.totalFiles.toLocaleString()}</span>
|
|
</div>
|
|
|
|
{/* Max file size */}
|
|
{data.maxFileSize && (
|
|
<div className="flex justify-between text-sm">
|
|
<span className="text-gray-600">Max file size</span>
|
|
<span className="font-medium">{formatBytes(data.maxFileSize)}</span>
|
|
</div>
|
|
)}
|
|
|
|
{/* Files by folder */}
|
|
{Object.keys(data.filesByFolder).length > 0 && (
|
|
<div className="pt-4 border-t">
|
|
<h4 className="text-sm font-medium text-gray-900 mb-2">By Folder</h4>
|
|
<div className="space-y-2">
|
|
{Object.entries(data.filesByFolder).map(([folder, count]) => (
|
|
<div key={folder} className="flex items-center justify-between text-sm">
|
|
<div className="flex items-center gap-2 text-gray-600">
|
|
<Folder className="w-4 h-4" />
|
|
<span>{folder}</span>
|
|
</div>
|
|
<span className="font-medium">{count}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|