Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Introduced new ContactAvatar and ContactAvatarPicker components for enhanced avatar management in contact views. - Updated ContactDetailView and ContactFormView to utilize the new avatar components, improving user experience when adding or editing contacts. - Enhanced ContactHoverCard and ContactRow components to display avatars, providing a more visually appealing interface. - Added loading and error states in ContactsListView for better user feedback during data fetching. - Implemented a new ContactsLoadState component to handle loading and error scenarios in the contacts list. - Updated package.json to include @formkit/auto-animate for improved UI animations.
59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
"use client"
|
|
|
|
import { Loader2, RefreshCw } from "lucide-react"
|
|
import { Button } from "@/components/ui/button"
|
|
import { ApiRequestError } from "@/lib/api/client"
|
|
import { CONTACTS_MUTED_TEXT } from "@/lib/contacts-chrome-classes"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
interface ContactsLoadStateProps {
|
|
isLoading: boolean
|
|
isError: boolean
|
|
error: unknown
|
|
onRetry: () => void
|
|
className?: string
|
|
}
|
|
|
|
function errorMessage(error: unknown): string {
|
|
if (error instanceof ApiRequestError) {
|
|
if (error.code === "contacts_unavailable") {
|
|
return "Connexion au carnet d'adresses indisponible. Réessayez dans quelques secondes."
|
|
}
|
|
if (error.code === "auth.unavailable") {
|
|
return "Service d'authentification indisponible. Vérifiez que le backend est démarré."
|
|
}
|
|
return error.message
|
|
}
|
|
if (error instanceof Error) return error.message
|
|
return "Impossible de charger les contacts."
|
|
}
|
|
|
|
export function ContactsLoadState({
|
|
isLoading,
|
|
isError,
|
|
error,
|
|
onRetry,
|
|
className,
|
|
}: ContactsLoadStateProps) {
|
|
if (isLoading) {
|
|
return (
|
|
<div className={cn("flex items-center justify-center gap-2 py-12 text-sm", CONTACTS_MUTED_TEXT, className)}>
|
|
<Loader2 className="h-4 w-4 animate-spin" />
|
|
Chargement des contacts…
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (!isError) return null
|
|
|
|
return (
|
|
<div className={cn("flex flex-col items-center gap-3 px-6 py-12 text-center", className)}>
|
|
<p className={cn("text-sm", CONTACTS_MUTED_TEXT)}>{errorMessage(error)}</p>
|
|
<Button type="button" variant="outline" size="sm" className="rounded-full" onClick={onRetry}>
|
|
<RefreshCw className="mr-1.5 h-4 w-4" />
|
|
Réessayer
|
|
</Button>
|
|
</div>
|
|
)
|
|
}
|