Files
stripstream-librarian/apps/backoffice/app/components/ui/Badge.tsx
Froidefond Julien e64848a216 feat: implement thumbnail generation and management
- Remove unused image dependencies from Cargo.lock.
- Update API to handle thumbnail generation and checkup processes.
- Introduce new routes for rebuilding and regenerating thumbnails.
- Enhance job tracking with progress indicators for thumbnail jobs.
- Update front-end components to display thumbnail job status and progress.
- Add backend logic for managing thumbnail jobs and integrating with the API.
- Refactor existing code to accommodate new thumbnail functionalities.
2026-03-08 20:55:12 +01:00

130 lines
3.5 KiB
TypeScript

import { ReactNode } from "react";
type BadgeVariant =
| "default"
| "primary"
| "secondary"
| "destructive"
| "outline"
| "success"
| "warning"
| "error"
| "muted"
| "unread"
| "in-progress"
| "completed";
interface BadgeProps {
children: ReactNode;
variant?: BadgeVariant;
className?: string;
}
const variantStyles: Record<BadgeVariant, string> = {
// shadcn/ui compatible
default: "bg-primary/90 text-primary-foreground border-transparent hover:bg-primary/80 backdrop-blur-md",
secondary: "bg-secondary/80 text-secondary-foreground border-transparent hover:bg-secondary/60 backdrop-blur-md",
destructive: "bg-destructive/90 text-destructive-foreground border-transparent hover:bg-destructive/80 backdrop-blur-md",
outline: "text-foreground border-border bg-background/50",
// Legacy + Additional variants
primary: "bg-primary/90 text-primary-foreground backdrop-blur-md",
success: "bg-success/90 text-success-foreground backdrop-blur-md",
warning: "bg-warning/90 text-white backdrop-blur-md",
error: "bg-destructive/90 text-destructive-foreground backdrop-blur-md",
muted: "bg-muted/60 text-muted-foreground backdrop-blur-md",
// Status badges from StripStream
unread: "badge-unread backdrop-blur-md",
"in-progress": "badge-in-progress backdrop-blur-md",
completed: "badge-completed backdrop-blur-md",
};
export function Badge({ children, variant = "default", className = "" }: BadgeProps) {
return (
<span className={`
inline-flex items-center
px-2.5 py-0.5
rounded-full
text-xs font-semibold
border
transition-colors duration-200
${variantStyles[variant]}
${className}
`}>
{children}
</span>
);
}
// Status badge for jobs/tasks
const statusVariants: Record<string, BadgeVariant> = {
running: "in-progress",
generating_thumbnails: "in-progress",
success: "completed",
completed: "completed",
failed: "error",
cancelled: "muted",
pending: "warning",
unread: "unread",
};
const statusLabels: Record<string, string> = {
generating_thumbnails: "Thumbnails",
};
interface StatusBadgeProps {
status: string;
className?: string;
}
export function StatusBadge({ status, className = "" }: StatusBadgeProps) {
const key = status.toLowerCase();
const variant = statusVariants[key] || "default";
const label = statusLabels[key] ?? status;
return <Badge variant={variant} className={className}>{label}</Badge>;
}
// Job type badge
const jobTypeVariants: Record<string, BadgeVariant> = {
rebuild: "primary",
full_rebuild: "warning",
thumbnail_rebuild: "secondary",
thumbnail_regenerate: "warning",
};
const jobTypeLabels: Record<string, string> = {
thumbnail_rebuild: "Thumbnails",
thumbnail_regenerate: "Regenerate",
};
interface JobTypeBadgeProps {
type: string;
className?: string;
}
export function JobTypeBadge({ type, className = "" }: JobTypeBadgeProps) {
const key = type.toLowerCase();
const variant = jobTypeVariants[key] || "default";
const label = jobTypeLabels[key] ?? type;
return <Badge variant={variant} className={className}>{label}</Badge>;
}
// Progress badge (shows percentage)
interface ProgressBadgeProps {
progress: number;
className?: string;
}
export function ProgressBadge({ progress, className = "" }: ProgressBadgeProps) {
let variant: BadgeVariant = "unread";
if (progress === 100) variant = "completed";
else if (progress > 0) variant = "in-progress";
return (
<Badge variant={variant} className={className}>
{progress}%
</Badge>
);
}