Files
OpenStock/components/WatchlistButton.tsx
T
ravixalgorithmandClaude Opus 5.5 74cc4307b9 feat(ui): redesign the app in the dashboard-craft language
Floated shell with a dark sidebar and browser-style tabs, hatch shells, bento tiles,
warm OKLCH palette with OpenStock teal, Plus Jakarta Sans + IBM Plex Mono.
Rebuilt stock page (native header, streaming), watchlist (real table, alerts pane,
news rows), auth pages (live product preview, choice chips), search palette,
alert modal and donate popup. Removes Header/Footer/NavItems/UserDropdown/SirayBanner
and the unused watchlist widgets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:28:19 +05:30

63 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import React, { useState } from "react";
import { useRouter } from "next/navigation";
import { Star } from "lucide-react";
import { toast } from "sonner";
import { addToWatchlist, removeFromWatchlist } from "@/lib/actions/watchlist.actions";
import { cn } from "@/lib/utils";
interface WatchlistButtonProps {
symbol: string;
company: string;
isInWatchlist: boolean;
variant?: "button" | "icon";
onWatchlistChange?: (symbol: string, added: boolean) => void;
}
const WatchlistButton = ({ symbol, company, isInWatchlist, variant = "button", onWatchlistChange }: WatchlistButtonProps) => {
const router = useRouter();
const [added, setAdded] = useState(isInWatchlist);
const [loading, setLoading] = useState(false);
const handleClick = async (e: React.MouseEvent) => {
e.preventDefault(); // may sit inside a link
const next = !added;
setAdded(next); // optimistic
setLoading(true);
try {
if (next) await addToWatchlist(symbol, company);
else await removeFromWatchlist(symbol);
toast.success(next ? `${symbol} added to watchlist` : `${symbol} removed from watchlist`);
onWatchlistChange?.(symbol, next);
router.refresh(); // sidebar lists the watchlist from the layout
} catch (error) {
console.error("Watchlist action failed:", error);
setAdded(!next);
toast.error("Couldn’t update your watchlist");
} finally {
setLoading(false);
}
};
const label = added ? `Remove ${symbol} from watchlist` : `Add ${symbol} to watchlist`;
if (variant === "icon") {
return (
<button type="button" onClick={handleClick} disabled={loading} className={cn('icon-btn', added && 'is-on')} title={label} aria-label={label} aria-pressed={added}>
<Star fill={added ? 'currentColor' : 'none'} />
</button>
);
}
return (
<button type="button" onClick={handleClick} disabled={loading} className={cn('btn btn-ghost', added && 'is-on')} aria-pressed={added}>
<Star fill={added ? 'currentColor' : 'none'} />
{added ? 'Watching' : 'Watch'}
</button>
);
};
export default WatchlistButton;