import { useState } from "react"; import { cn } from "~/lib/utils"; import { Bell, TrendingUp, TrendingDown, Droplets, Users, Wallet, X, Check } from "lucide-react"; import { Button } from "@/routes/ui/button"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/routes/ui/dialog"; export type AlertType = "price_above" | "price_below" | "price_change" | "volume" | "whale" | "liquidity" | "holder_concentration"; export interface AlertConfig { /** Alert type */ type: AlertType; /** Threshold value */ threshold: number; /** Whether alert is enabled */ enabled: boolean; } export interface AlertConfigModalProps { /** Whether modal is open */ open: boolean; /** Callback when modal is closed */ onOpenChange: (open: boolean) => void; /** Token symbol */ tokenSymbol: string; /** Current price for reference */ currentPrice?: string; /** Existing alert configurations */ existingAlerts?: AlertConfig[]; /** Callback when alerts are saved */ onSave: (alerts: AlertConfig[]) => void; } const ALERT_TYPES: Array<{ type: AlertType; label: string; description: string; icon: typeof Bell; unit: string; defaultThreshold: number; }> = [ { type: "price_above", label: "Price Above", description: "Alert when price rises above threshold", icon: TrendingUp, unit: "$", defaultThreshold: 0, }, { type: "price_below", label: "Price Below", description: "Alert when price drops below threshold", icon: TrendingDown, unit: "$", defaultThreshold: 0, }, { type: "price_change", label: "Price Change", description: "Alert on significant price movement", icon: TrendingUp, unit: "%", defaultThreshold: 10, }, { type: "volume", label: "Volume Spike", description: "Alert on unusual trading volume", icon: TrendingUp, unit: "x", defaultThreshold: 3, }, { type: "whale", label: "Whale Activity", description: "Alert on large transactions", icon: Wallet, unit: "$", defaultThreshold: 10000, }, { type: "liquidity", label: "Liquidity Change", description: "Alert on liquidity pool changes", icon: Droplets, unit: "%", defaultThreshold: 20, }, { type: "holder_concentration", label: "Holder Concentration", description: "Alert if top holders exceed threshold", icon: Users, unit: "%", defaultThreshold: 50, }, ]; /** * AlertConfigModal - Configure alerts for a token * * Features: * - Multiple alert types (price, volume, whale, liquidity, holders) * - Threshold configuration per alert type * - Enable/disable individual alerts * - Save all configurations at once */ export function AlertConfigModal({ open, onOpenChange, tokenSymbol, currentPrice, existingAlerts = [], onSave, }: AlertConfigModalProps) { // Initialize alerts state from existing or defaults const [alerts, setAlerts] = useState(() => { return ALERT_TYPES.map(alertType => { const existing = existingAlerts.find(a => a.type === alertType.type); return existing || { type: alertType.type, threshold: alertType.defaultThreshold, enabled: false, }; }); }); const handleToggleAlert = (type: AlertType) => { setAlerts(prev => prev.map(alert => alert.type === type ? { ...alert, enabled: !alert.enabled } : alert )); }; const handleThresholdChange = (type: AlertType, value: number) => { setAlerts(prev => prev.map(alert => alert.type === type ? { ...alert, threshold: value } : alert )); }; const handleSave = () => { onSave(alerts.filter(a => a.enabled)); onOpenChange(false); }; const enabledCount = alerts.filter(a => a.enabled).length; return ( Configure Alerts for {tokenSymbol} {currentPrice && (

Current price: {currentPrice}

)}
{/* Alert types list */}
{ALERT_TYPES.map((alertType) => { const alert = alerts.find(a => a.type === alertType.type)!; const Icon = alertType.icon; return (
{/* Toggle button */} {/* Alert info */}
{alertType.label}

{alertType.description}

{/* Threshold input (only when enabled) */} {alert.enabled && (
Threshold:
{alertType.unit === "$" && ( $ )} handleThresholdChange( alertType.type, parseFloat(e.target.value) || 0 )} className="w-24 px-2 py-1 text-sm border rounded bg-background" min={0} step={alertType.unit === "%" ? 1 : 0.01} /> {alertType.unit !== "$" && ( {alertType.unit} )}
)}
); })}
{/* Footer with save button */}

{enabledCount} alert{enabledCount !== 1 ? "s" : ""} enabled

); }