DialogChatError.svelte 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <script lang="ts">
  2. import * as AlertDialog from '$lib/components/ui/alert-dialog';
  3. import { AlertTriangle, TimerOff } from '@lucide/svelte';
  4. interface Props {
  5. open: boolean;
  6. type: 'timeout' | 'server';
  7. message: string;
  8. onOpenChange?: (open: boolean) => void;
  9. }
  10. let { open = $bindable(), type, message, onOpenChange }: Props = $props();
  11. const isTimeout = $derived(type === 'timeout');
  12. const title = $derived(isTimeout ? 'TCP Timeout' : 'Server Error');
  13. const description = $derived(
  14. isTimeout
  15. ? 'The request did not receive a response from the server before timing out.'
  16. : 'The server responded with an error message. Review the details below.'
  17. );
  18. const iconClass = $derived(isTimeout ? 'text-destructive' : 'text-amber-500');
  19. const badgeClass = $derived(
  20. isTimeout
  21. ? 'border-destructive/40 bg-destructive/10 text-destructive'
  22. : 'border-amber-500/40 bg-amber-500/10 text-amber-600 dark:text-amber-400'
  23. );
  24. function handleOpenChange(newOpen: boolean) {
  25. open = newOpen;
  26. onOpenChange?.(newOpen);
  27. }
  28. </script>
  29. <AlertDialog.Root {open} onOpenChange={handleOpenChange}>
  30. <AlertDialog.Content>
  31. <AlertDialog.Header>
  32. <AlertDialog.Title class="flex items-center gap-2">
  33. {#if isTimeout}
  34. <TimerOff class={`h-5 w-5 ${iconClass}`} />
  35. {:else}
  36. <AlertTriangle class={`h-5 w-5 ${iconClass}`} />
  37. {/if}
  38. {title}
  39. </AlertDialog.Title>
  40. <AlertDialog.Description>
  41. {description}
  42. </AlertDialog.Description>
  43. </AlertDialog.Header>
  44. <div class={`rounded-lg border px-4 py-3 text-sm ${badgeClass}`}>
  45. <p class="font-medium">{message}</p>
  46. </div>
  47. <AlertDialog.Footer>
  48. <AlertDialog.Action onclick={() => handleOpenChange(false)}>Close</AlertDialog.Action>
  49. </AlertDialog.Footer>
  50. </AlertDialog.Content>
  51. </AlertDialog.Root>