mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
feat(ui): survey/NudgePrompt to shadcn Button
- antd Button (primary + outlined-danger) \u2192 shadcn Button default + destructive-tinted outline variants. - Inline gray palette replaced with semantic bg-background/border- border/text-muted-foreground tokens. - Confirmation state's emerald check-mark tile uses categorical palette (existing overrides cover this). Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
parent
7b725e498f
commit
2b5034cab3
1 changed files with 40 additions and 26 deletions
|
|
@ -1,8 +1,12 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { X, LucideIcon, Check } from "lucide-react";
|
||||
import { Button } from "antd";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useDisableShowPrompts } from "@/app/(dashboard)/hooks/useDisableShowPrompts";
|
||||
import { setLocalStorageItem, emitLocalStorageChange } from "@/utils/localStorageUtils";
|
||||
import {
|
||||
setLocalStorageItem,
|
||||
emitLocalStorageChange,
|
||||
} from "@/utils/localStorageUtils";
|
||||
|
||||
interface NudgePromptProps {
|
||||
onOpen: () => void;
|
||||
|
|
@ -16,8 +20,8 @@ interface NudgePromptProps {
|
|||
buttonStyle?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const DISMISS_DURATION = 15000; // 15 seconds
|
||||
const CONFIRMATION_DURATION = 5000; // 5 seconds
|
||||
const DISMISS_DURATION = 15000;
|
||||
const CONFIRMATION_DURATION = 5000;
|
||||
|
||||
export function NudgePrompt({
|
||||
onOpen,
|
||||
|
|
@ -44,7 +48,10 @@ export function NudgePrompt({
|
|||
const startTime = Date.now();
|
||||
const interval = setInterval(() => {
|
||||
const elapsed = Date.now() - startTime;
|
||||
const remaining = Math.max(0, 100 - (elapsed / DISMISS_DURATION) * 100);
|
||||
const remaining = Math.max(
|
||||
0,
|
||||
100 - (elapsed / DISMISS_DURATION) * 100,
|
||||
);
|
||||
setProgress(remaining);
|
||||
|
||||
if (remaining <= 0) {
|
||||
|
|
@ -72,21 +79,25 @@ export function NudgePrompt({
|
|||
setShowConfirmation(true);
|
||||
};
|
||||
|
||||
// Show confirmation even if disableShowPrompts is true (since we just set it)
|
||||
if (showConfirmation) {
|
||||
return (
|
||||
<div
|
||||
className={`fixed bottom-6 right-6 z-40 w-80 bg-white rounded-lg shadow-xl border border-gray-200 overflow-hidden transform transition-all duration-300 ease-out ${isVisible ? "translate-y-0 opacity-100 scale-100" : "translate-y-4 opacity-0 scale-95"
|
||||
}`}
|
||||
className={cn(
|
||||
"fixed bottom-6 right-6 z-40 w-80 bg-background rounded-lg shadow-xl border border-border overflow-hidden transform transition-all duration-300 ease-out",
|
||||
isVisible
|
||||
? "translate-y-0 opacity-100 scale-100"
|
||||
: "translate-y-4 opacity-0 scale-95",
|
||||
)}
|
||||
>
|
||||
<div className="p-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-green-100 flex items-center justify-center">
|
||||
<Check className="h-5 w-5 text-green-600" />
|
||||
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-emerald-100 dark:bg-emerald-950 flex items-center justify-center">
|
||||
<Check className="h-5 w-5 text-emerald-600 dark:text-emerald-400" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="text-sm text-gray-700 font-medium">
|
||||
Got it, we will not ask again. Reactivate this at any time in the User Menu.
|
||||
<p className="text-sm text-foreground font-medium">
|
||||
Got it, we will not ask again. Reactivate this at any time in
|
||||
the User Menu.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -95,16 +106,18 @@ export function NudgePrompt({
|
|||
);
|
||||
}
|
||||
|
||||
// Don't show the prompt if disabled (unless we're showing confirmation)
|
||||
if (!isVisible || disableShowPrompts) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`fixed bottom-6 right-6 z-40 w-80 bg-white rounded-lg shadow-xl border border-gray-200 overflow-hidden transform transition-all duration-300 ease-out ${isVisible ? "translate-y-0 opacity-100 scale-100" : "translate-y-4 opacity-0 scale-95"
|
||||
}`}
|
||||
className={cn(
|
||||
"fixed bottom-6 right-6 z-40 w-80 bg-background rounded-lg shadow-xl border border-border overflow-hidden transform transition-all duration-300 ease-out",
|
||||
isVisible
|
||||
? "translate-y-0 opacity-100 scale-100"
|
||||
: "translate-y-4 opacity-0 scale-95",
|
||||
)}
|
||||
>
|
||||
{/* Progress bar at top showing time remaining */}
|
||||
<div className="h-1 bg-gray-100 w-full">
|
||||
<div className="h-1 bg-muted w-full">
|
||||
<div
|
||||
className="h-full transition-all duration-100 ease-linear"
|
||||
style={{ width: `${progress}%`, backgroundColor: accentColor }}
|
||||
|
|
@ -113,30 +126,32 @@ export function NudgePrompt({
|
|||
|
||||
<div className="p-4">
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<div className="flex items-center gap-2" style={{ color: accentColor }}>
|
||||
<div
|
||||
className="flex items-center gap-2"
|
||||
style={{ color: accentColor }}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
<span className="font-semibold text-sm">{title}</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={onDismiss}
|
||||
className="text-gray-400 hover:text-gray-600 transition-colors p-0.5 rounded hover:bg-gray-100"
|
||||
className="text-muted-foreground hover:text-foreground transition-colors p-0.5 rounded hover:bg-muted"
|
||||
aria-label="Dismiss"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-600 mb-3">{description}</p>
|
||||
<p className="text-sm text-muted-foreground mb-3">{description}</p>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Button type="primary" block onClick={onOpen} style={buttonStyle}>
|
||||
<Button className="w-full" onClick={onOpen} style={buttonStyle}>
|
||||
{buttonText}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
danger
|
||||
block
|
||||
variant="outline"
|
||||
className="w-full text-xs text-destructive border-destructive/30 hover:bg-destructive/10"
|
||||
onClick={handleDontAskAgain}
|
||||
className="text-xs"
|
||||
>
|
||||
Don't ask me again
|
||||
</Button>
|
||||
|
|
@ -145,4 +160,3 @@ export function NudgePrompt({
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue