{"version":3,"sources":["../src/components/toast/toast-provider.tsx"],"sourcesContent":["import { GraphQLError } from \"@vn-sdk/runtime-client-gql\";\nimport React, { createContext, useContext, useState, useCallback } from \"react\";\nimport { PartialBy, AiSDKError, Severity } from \"@vn-sdk/shared\";\n\ninterface Toast {\n  id: string;\n  message: string | React.ReactNode;\n  type: \"info\" | \"success\" | \"warning\" | \"error\";\n  duration?: number;\n}\n\ninterface ToastContextValue {\n  toasts: Toast[];\n  addToast: (toast: PartialBy<Toast, \"id\">) => void;\n  addGraphQLErrorsToast: (errors: GraphQLError[]) => void;\n  removeToast: (id: string) => void;\n  enabled: boolean;\n  // Banner management\n  bannerError: AiSDKError | null;\n  setBannerError: (error: AiSDKError | null) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\n// Helper functions for error banner styling\ntype ErrorSeverity = \"critical\" | \"warning\" | \"info\";\n\ninterface ErrorColors {\n  background: string;\n  border: string;\n  text: string;\n  icon: string;\n}\n\nfunction getErrorSeverity(error: AiSDKError): ErrorSeverity {\n  // Use structured error severity if available\n  if (error.severity) {\n    switch (error.severity) {\n      case Severity.CRITICAL:\n        return \"critical\";\n      case Severity.WARNING:\n        return \"warning\";\n      case Severity.INFO:\n        return \"info\";\n      default:\n        return \"info\";\n    }\n  }\n\n  // Fallback: Check for API key errors which should always be critical\n  const message = error.message.toLowerCase();\n  if (\n    message.includes(\"api key\") ||\n    message.includes(\"401\") ||\n    message.includes(\"unauthorized\") ||\n    message.includes(\"authentication\") ||\n    message.includes(\"incorrect api key\")\n  ) {\n    return \"critical\";\n  }\n\n  // Default to info level\n  return \"info\";\n}\n\nfunction getErrorColors(severity: ErrorSeverity): ErrorColors {\n  switch (severity) {\n    case \"critical\":\n      return {\n        background: \"#fee2e2\",\n        border: \"#dc2626\",\n        text: \"#7f1d1d\",\n        icon: \"#dc2626\",\n      };\n    case \"warning\":\n      return {\n        background: \"#fef3c7\",\n        border: \"#d97706\",\n        text: \"#78350f\",\n        icon: \"#d97706\",\n      };\n    case \"info\":\n      return {\n        background: \"#dbeafe\",\n        border: \"#2563eb\",\n        text: \"#1e3a8a\",\n        icon: \"#2563eb\",\n      };\n  }\n}\n\nexport function useToast() {\n  const context = useContext(ToastContext);\n  if (!context) {\n    throw new Error(\"useToast must be used within a ToastProvider\");\n  }\n  return context;\n}\n\nexport function ToastProvider({\n  enabled,\n  children,\n}: {\n  enabled: boolean;\n  children: React.ReactNode;\n}) {\n  const [toasts, setToasts] = useState<Toast[]>([]);\n  const [bannerError, setBannerErrorState] = useState<AiSDKError | null>(null);\n\n  const removeToast = useCallback((id: string) => {\n    setToasts((prev) => prev.filter((toast) => toast.id !== id));\n  }, []);\n\n  const addToast = useCallback(\n    (toast: PartialBy<Toast, \"id\">) => {\n      // Respect the enabled flag for ALL toasts\n      if (!enabled) {\n        return;\n      }\n\n      const id = toast.id ?? Math.random().toString(36).substring(2, 9);\n\n      setToasts((currentToasts) => {\n        if (currentToasts.find((toast) => toast.id === id)) return currentToasts;\n        return [...currentToasts, { ...toast, id }];\n      });\n\n      if (toast.duration) {\n        setTimeout(() => {\n          removeToast(id);\n        }, toast.duration);\n      }\n    },\n    [enabled, removeToast],\n  );\n\n  const setBannerError = useCallback(\n    (error: AiSDKError | null) => {\n      // Respect the enabled flag for ALL errors\n      if (!enabled && error !== null) {\n        return;\n      }\n      setBannerErrorState(error);\n    },\n    [enabled],\n  );\n\n  const addGraphQLErrorsToast = useCallback((errors: GraphQLError[]) => {\n    // DEPRECATED: All errors now route to banners for consistency\n    console.warn(\"addGraphQLErrorsToast is deprecated. All errors now show as banners.\");\n    // Function kept for backward compatibility - does nothing\n  }, []);\n\n  const value = {\n    toasts,\n    addToast,\n    addGraphQLErrorsToast,\n    removeToast,\n    enabled,\n    bannerError,\n    setBannerError,\n  };\n\n  return (\n    <ToastContext.Provider value={value}>\n      {/* Banner Error Display */}\n      {bannerError &&\n        (() => {\n          const severity = getErrorSeverity(bannerError);\n          const colors = getErrorColors(severity);\n\n          return (\n            <div\n              style={{\n                position: \"fixed\",\n                bottom: \"20px\",\n                left: \"50%\",\n                transform: \"translateX(-50%)\",\n                zIndex: 9999,\n                backgroundColor: colors.background,\n                border: `1px solid ${colors.border}`,\n                borderLeft: `4px solid ${colors.border}`,\n                borderRadius: \"8px\",\n                padding: \"12px 16px\",\n                fontSize: \"13px\",\n                boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n                backdropFilter: \"blur(8px)\",\n                maxWidth: \"min(90vw, 700px)\",\n                width: \"100%\",\n                boxSizing: \"border-box\",\n                overflow: \"hidden\",\n              }}\n            >\n              <div\n                style={{\n                  display: \"flex\",\n                  justifyContent: \"space-between\",\n                  alignItems: \"center\",\n                  gap: \"10px\",\n                }}\n              >\n                <div\n                  style={{\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    gap: \"8px\",\n                    flex: 1,\n                    minWidth: 0,\n                  }}\n                >\n                  <div\n                    style={{\n                      width: \"12px\",\n                      height: \"12px\",\n                      borderRadius: \"50%\",\n                      backgroundColor: colors.border,\n                      flexShrink: 0,\n                    }}\n                  />\n                  <div\n                    style={{\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: \"10px\",\n                      flex: 1,\n                      minWidth: 0,\n                    }}\n                  >\n                    <div\n                      style={{\n                        color: colors.text,\n                        lineHeight: \"1.4\",\n                        fontWeight: \"400\",\n                        fontSize: \"13px\",\n                        flex: 1,\n                        wordBreak: \"break-all\",\n                        overflowWrap: \"break-word\",\n                        maxWidth: \"550px\",\n                        overflow: \"hidden\",\n                        display: \"-webkit-box\",\n                        WebkitLineClamp: 10,\n                        WebkitBoxOrient: \"vertical\",\n                      }}\n                    >\n                      {(() => {\n                        let message = bannerError.message;\n\n                        // Try to extract the useful message from JSON first\n                        const jsonMatch = message.match(/'message':\\s*'([^']+)'/);\n                        if (jsonMatch) {\n                          return jsonMatch[1]; // Return the actual error message\n                        }\n\n                        // Strip technical garbage but keep the meaningful message\n                        message = message.split(\" - \")[0]; // Remove everything after \" - {\"\n                        message = message.split(\": Error code\")[0]; // Remove \": Error code: 401\"\n                        message = message.replace(/:\\s*\\d{3}$/, \"\"); // Remove trailing \": 401\"\n                        message = message.replace(/See more:.*$/g, \"\"); // Remove \"See more\" links\n                        message = message.trim();\n\n                        // If it's still garbage (contains { or '), use fallback\n                        // if (message.includes(\"{\") || message.includes(\"'\")) {\n                        //   return \"Configuration error.... Please check your setup.\";\n                        // }\n\n                        return message || \"Configuration error occurred.\";\n                      })()}\n                    </div>\n\n                    {(() => {\n                      const message = bannerError.message;\n                      const markdownLinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n                      const plainUrlRegex = /(https?:\\/\\/[^\\s)]+)/g;\n\n                      // Extract the first URL found\n                      let url = null;\n                      let buttonText = \"See More\";\n\n                      // Check for markdown links first\n                      const markdownMatch = markdownLinkRegex.exec(message);\n                      if (markdownMatch) {\n                        url = markdownMatch[2];\n                        buttonText = \"See More\";\n                      } else {\n                        // Check for plain URLs\n                        const urlMatch = plainUrlRegex.exec(message);\n                        if (urlMatch) {\n                          url = urlMatch[0].replace(/[.,;:'\"]*$/, \"\"); // Remove trailing punctuation\n                          buttonText = \"See More\";\n                        }\n                      }\n\n                      if (!url) return null;\n\n                      return (\n                        <button\n                          onClick={() => window.open(url, \"_blank\", \"noopener,noreferrer\")}\n                          style={{\n                            background: colors.border,\n                            color: \"white\",\n                            border: \"none\",\n                            borderRadius: \"5px\",\n                            padding: \"4px 10px\",\n                            fontSize: \"11px\",\n                            fontWeight: \"500\",\n                            cursor: \"pointer\",\n                            transition: \"all 0.2s ease\",\n                            flexShrink: 0,\n                          }}\n                          onMouseEnter={(e) => {\n                            e.currentTarget.style.opacity = \"0.9\";\n                            e.currentTarget.style.transform = \"translateY(-1px)\";\n                          }}\n                          onMouseLeave={(e) => {\n                            e.currentTarget.style.opacity = \"1\";\n                            e.currentTarget.style.transform = \"translateY(0)\";\n                          }}\n                        >\n                          {buttonText}\n                        </button>\n                      );\n                    })()}\n                  </div>\n                </div>\n                <button\n                  onClick={() => setBannerError(null)}\n                  style={{\n                    background: \"transparent\",\n                    border: \"none\",\n                    color: colors.text,\n                    cursor: \"pointer\",\n                    padding: \"2px\",\n                    borderRadius: \"3px\",\n                    fontSize: \"14px\",\n                    lineHeight: \"1\",\n                    opacity: 0.6,\n                    transition: \"all 0.2s ease\",\n                    flexShrink: 0,\n                  }}\n                  title=\"Dismiss\"\n                  onMouseEnter={(e) => {\n                    e.currentTarget.style.opacity = \"1\";\n                    e.currentTarget.style.background = \"rgba(0, 0, 0, 0.05)\";\n                  }}\n                  onMouseLeave={(e) => {\n                    e.currentTarget.style.opacity = \"0.6\";\n                    e.currentTarget.style.background = \"transparent\";\n                  }}\n                >\n                  ×\n                </button>\n              </div>\n            </div>\n          );\n        })()}\n\n      {/* Toast Display - Deprecated: All errors now show as banners */}\n      {children}\n    </ToastContext.Provider>\n  );\n}\n\n// Toast component removed - all errors now show as banners for consistency\n"],"mappings":"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","names":["toast"]}