restrict watchlist & price alerts
This commit is contained in:
parent
b071412f29
commit
93a9ae46ab
@ -94,7 +94,8 @@
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toast.error("Only for Pro Members", {
|
toast.error("Only for Pro Members", {
|
||||||
style: "border-radius: 200px; background: #2A2E39; color: #fff;",
|
style:
|
||||||
|
"border-radius: 5px; background: #fff; color: #000; border-color: #4B5563; font-size: 15px;",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,11 @@ import { serialize } from "object-to-formdata";
|
|||||||
|
|
||||||
export const POST: RequestHandler = async ({ request, locals }) => {
|
export const POST: RequestHandler = async ({ request, locals }) => {
|
||||||
const data = await request.json();
|
const data = await request.json();
|
||||||
const { pb } = locals;
|
const { pb, user } = locals;
|
||||||
|
|
||||||
let output;
|
let output;
|
||||||
|
|
||||||
|
if(user?.tier === 'Pro') {
|
||||||
try {
|
try {
|
||||||
// Ensure itemIdList is always an array.
|
// Ensure itemIdList is always an array.
|
||||||
const itemIdList = Array.isArray(data?.itemIdList)
|
const itemIdList = Array.isArray(data?.itemIdList)
|
||||||
@ -48,4 +49,11 @@ export const POST: RequestHandler = async ({ request, locals }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Response(JSON.stringify(output?.id));
|
return new Response(JSON.stringify(output?.id));
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return new Response(JSON.stringify("failure"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,39 +5,95 @@ export const POST = (async ({ request, locals }) => {
|
|||||||
const { user, pb } = locals;
|
const { user, pb } = locals;
|
||||||
const data = await request.json();
|
const data = await request.json();
|
||||||
|
|
||||||
const ticker = data?.ticker; // This can be a string (single ticker) or an array (list of tickers)
|
// `tickerInput` can be a string (single ticker) or an array (list of tickers)
|
||||||
|
const tickerInput = data?.ticker || [];
|
||||||
const watchListId = data?.watchListId;
|
const watchListId = data?.watchListId;
|
||||||
let output;
|
let output;
|
||||||
|
|
||||||
|
|
||||||
|
// Determine the ticker limit: 50 for Pro users, 5 for non-Pro users.
|
||||||
|
const isProUser = user?.tier === "Pro";
|
||||||
|
const tickerLimit = isProUser ? 100 : 5;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const watchList = await pb.collection("watchlist").getOne(watchListId);
|
const watchList = await pb.collection("watchlist").getOne(watchListId);
|
||||||
|
// Ensure current tickers are in an array.
|
||||||
|
let currentTickers = watchList?.ticker;
|
||||||
|
if (typeof currentTickers === "string") {
|
||||||
|
try {
|
||||||
|
currentTickers = JSON.parse(currentTickers);
|
||||||
|
} catch (err) {
|
||||||
|
currentTickers = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentTickers = currentTickers || [];
|
||||||
|
|
||||||
if (Array.isArray(ticker)) {
|
if (Array.isArray(tickerInput)) {
|
||||||
// If `ticker` is a list, update the watchlist directly with the new list of tickers.
|
// When replacing the entire ticker list:
|
||||||
|
if(data?.mode === 'delete') {
|
||||||
output = await pb.collection("watchlist").update(watchListId, {
|
output = await pb.collection("watchlist").update(watchListId, {
|
||||||
ticker: ticker,
|
ticker: tickerInput,
|
||||||
});
|
});
|
||||||
} else if (watchList?.ticker?.includes(ticker)) {
|
|
||||||
// Remove single ticker from the watchlist if it's already present.
|
|
||||||
const newTickerList = watchList?.ticker.filter((item) => item !== ticker);
|
|
||||||
output = await pb
|
|
||||||
.collection("watchlist")
|
|
||||||
.update(watchListId, { ticker: newTickerList });
|
|
||||||
} else {
|
} else {
|
||||||
// Add single ticker to the watchlist if it's not present.
|
|
||||||
const newTickerList = [...watchList?.ticker, ticker];
|
if (tickerInput.length > tickerLimit) {
|
||||||
output = await pb
|
return new Response(
|
||||||
.collection("watchlist")
|
JSON.stringify({
|
||||||
.update(watchListId, { ticker: newTickerList });
|
error: isProUser
|
||||||
|
? `You can only have up to ${tickerLimit} stocks in your watchlist.`
|
||||||
|
: `Upgrade to Pro to add unlimited stocks!`,
|
||||||
|
}),
|
||||||
|
{ status: 403 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
output = await pb.collection("watchlist").update(watchListId, {
|
||||||
|
ticker: tickerInput,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Single ticker update.
|
||||||
|
if (currentTickers?.includes(tickerInput)) {
|
||||||
|
// Remove the ticker if it's already present.
|
||||||
|
const newTickerList = currentTickers?.filter((item) => item !== tickerInput);
|
||||||
|
output = await pb.collection("watchlist").update(watchListId, { ticker: newTickerList });
|
||||||
|
} else {
|
||||||
|
// Add the ticker if not already present.
|
||||||
|
const newTickerList = [...currentTickers, tickerInput];
|
||||||
|
if (newTickerList.length > tickerLimit) {
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
error: isProUser
|
||||||
|
? `You can only have up to ${tickerLimit} stocks in your watchlist.`
|
||||||
|
: `Upgrade to Pro to add unlimited stocks`,
|
||||||
|
}),
|
||||||
|
{ status: 403 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
output = await pb.collection("watchlist").update(watchListId, { ticker: newTickerList });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If the watchlist doesn't exist, create a new one with either the single ticker or list.
|
// If the watchlist doesn't exist, create a new one.
|
||||||
|
const tickersArray = Array.isArray(tickerInput) ? tickerInput : [tickerInput];
|
||||||
|
if (tickersArray.length > tickerLimit) {
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
error: isProUser
|
||||||
|
? `You can only have up to ${tickerLimit} stocks in your watchlist.`
|
||||||
|
: `Upgrade to Pro to add unlimited stocks!`,
|
||||||
|
}),
|
||||||
|
{ status: 403 }
|
||||||
|
);
|
||||||
|
}
|
||||||
output = await pb.collection("watchlist").create(
|
output = await pb.collection("watchlist").create(
|
||||||
serialize({
|
serialize({
|
||||||
user: user?.id,
|
user: user?.id,
|
||||||
ticker: Array.isArray(ticker)
|
ticker: JSON.stringify(tickersArray),
|
||||||
? JSON.stringify(ticker)
|
|
||||||
: JSON.stringify([ticker]),
|
|
||||||
title: "Favorites",
|
title: "Favorites",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@ -83,57 +83,65 @@
|
|||||||
|
|
||||||
async function toggleUserWatchlist(watchListId: string) {
|
async function toggleUserWatchlist(watchListId: string) {
|
||||||
try {
|
try {
|
||||||
isTickerIncluded = !isTickerIncluded;
|
// Find the index of the watchlist
|
||||||
|
|
||||||
const watchlistIndex = userWatchList?.findIndex(
|
const watchlistIndex = userWatchList?.findIndex(
|
||||||
(item) => item?.id === watchListId,
|
(item) => item?.id === watchListId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (watchlistIndex !== -1) {
|
if (watchlistIndex !== -1 && watchlistIndex !== undefined) {
|
||||||
const existingTickerIndex =
|
const watchlist = userWatchList[watchlistIndex];
|
||||||
userWatchList[watchlistIndex]?.ticker?.indexOf($etfTicker);
|
const existingTickerIndex = watchlist?.ticker?.indexOf($etfTicker);
|
||||||
|
|
||||||
|
let updatedTickers = [...(watchlist?.ticker || [])]; // Ensure we don't mutate directly
|
||||||
|
|
||||||
if (existingTickerIndex !== -1) {
|
if (existingTickerIndex !== -1) {
|
||||||
// If the $etfTicker exists, remove it from the array
|
// Remove the ticker if it exists
|
||||||
userWatchList[watchlistIndex]?.ticker?.splice(existingTickerIndex, 1);
|
updatedTickers.splice(existingTickerIndex, 1);
|
||||||
} else {
|
} else {
|
||||||
// If the $etfTicker doesn't exist, add it to the array
|
// Add the ticker if it doesn't exist
|
||||||
userWatchList[watchlistIndex]?.ticker?.push($etfTicker);
|
updatedTickers.push($etfTicker);
|
||||||
|
|
||||||
|
// Check tier limits
|
||||||
|
if (data?.user?.tier !== "Pro" && updatedTickers.length > 5) {
|
||||||
|
toast.error("Upgrade to Pro to add unlimited stocks!", {
|
||||||
|
style:
|
||||||
|
"border-radius: 5px; background: #fff; color: #000; border-color: #4B5563; font-size: 15px;",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the userWatchList
|
// Update the local state immutably
|
||||||
userWatchList = [...userWatchList];
|
userWatchList = userWatchList.map((item, idx) =>
|
||||||
}
|
idx === watchlistIndex ? { ...item, ticker: updatedTickers } : item,
|
||||||
|
);
|
||||||
const postData = {
|
|
||||||
watchListId: watchListId,
|
|
||||||
ticker: $etfTicker,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// Send API request
|
||||||
const response = await fetch("/api/update-watchlist", {
|
const response = await fetch("/api/update-watchlist", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: { "Content-Type": "application/json" },
|
||||||
"Content-Type": "application/json",
|
body: JSON.stringify({ watchListId, ticker: $etfTicker }),
|
||||||
},
|
|
||||||
body: JSON.stringify(postData),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Network response was not ok");
|
|
||||||
}
|
|
||||||
|
|
||||||
const output = await response.json();
|
const output = await response.json();
|
||||||
|
|
||||||
// Update the userWatchList with the response from the server
|
// Update userWatchList based on API response
|
||||||
if (watchlistIndex !== -1) {
|
userWatchList = userWatchList.map((item) =>
|
||||||
userWatchList[watchlistIndex] = output;
|
item.id === watchListId ? output : item,
|
||||||
userWatchList = [...userWatchList];
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// If watchlist doesn't exist, create a new entry
|
||||||
|
const response = await fetch("/api/update-watchlist", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ watchListId, ticker: $etfTicker }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const output = await response.json();
|
||||||
userWatchList = [...userWatchList, output];
|
userWatchList = [...userWatchList, output];
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("An error occurred:", error);
|
console.error("An error occurred:", error);
|
||||||
// Handle the error appropriately (e.g., show an error message to the user)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -81,57 +81,65 @@
|
|||||||
|
|
||||||
async function toggleUserWatchlist(watchListId: string) {
|
async function toggleUserWatchlist(watchListId: string) {
|
||||||
try {
|
try {
|
||||||
isTickerIncluded = !isTickerIncluded;
|
// Find the index of the watchlist
|
||||||
|
|
||||||
const watchlistIndex = userWatchList?.findIndex(
|
const watchlistIndex = userWatchList?.findIndex(
|
||||||
(item) => item?.id === watchListId,
|
(item) => item?.id === watchListId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (watchlistIndex !== -1) {
|
if (watchlistIndex !== -1 && watchlistIndex !== undefined) {
|
||||||
const existingTickerIndex =
|
const watchlist = userWatchList[watchlistIndex];
|
||||||
userWatchList[watchlistIndex]?.ticker?.indexOf($indexTicker);
|
const existingTickerIndex = watchlist?.ticker?.indexOf($indexTicker);
|
||||||
|
|
||||||
|
let updatedTickers = [...(watchlist?.ticker || [])]; // Ensure we don't mutate directly
|
||||||
|
|
||||||
if (existingTickerIndex !== -1) {
|
if (existingTickerIndex !== -1) {
|
||||||
// If the $indexTicker exists, remove it from the array
|
// Remove the ticker if it exists
|
||||||
userWatchList[watchlistIndex]?.ticker?.splice(existingTickerIndex, 1);
|
updatedTickers.splice(existingTickerIndex, 1);
|
||||||
} else {
|
} else {
|
||||||
// If the $indexTicker doesn't exist, add it to the array
|
// Add the ticker if it doesn't exist
|
||||||
userWatchList[watchlistIndex]?.ticker?.push($indexTicker);
|
updatedTickers.push($indexTicker);
|
||||||
|
|
||||||
|
// Check tier limits
|
||||||
|
if (data?.user?.tier !== "Pro" && updatedTickers.length > 5) {
|
||||||
|
toast.error("Upgrade to Pro to add unlimited stocks!", {
|
||||||
|
style:
|
||||||
|
"border-radius: 5px; background: #fff; color: #000; border-color: #4B5563; font-size: 15px;",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the userWatchList
|
// Update the local state immutably
|
||||||
userWatchList = [...userWatchList];
|
userWatchList = userWatchList.map((item, idx) =>
|
||||||
}
|
idx === watchlistIndex ? { ...item, ticker: updatedTickers } : item,
|
||||||
|
);
|
||||||
const postData = {
|
|
||||||
watchListId: watchListId,
|
|
||||||
ticker: $indexTicker,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// Send API request
|
||||||
const response = await fetch("/api/update-watchlist", {
|
const response = await fetch("/api/update-watchlist", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: { "Content-Type": "application/json" },
|
||||||
"Content-Type": "application/json",
|
body: JSON.stringify({ watchListId, ticker: $indexTicker }),
|
||||||
},
|
|
||||||
body: JSON.stringify(postData),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Network response was not ok");
|
|
||||||
}
|
|
||||||
|
|
||||||
const output = await response.json();
|
const output = await response.json();
|
||||||
|
|
||||||
// Update the userWatchList with the response from the server
|
// Update userWatchList based on API response
|
||||||
if (watchlistIndex !== -1) {
|
userWatchList = userWatchList.map((item) =>
|
||||||
userWatchList[watchlistIndex] = output;
|
item.id === watchListId ? output : item,
|
||||||
userWatchList = [...userWatchList];
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// If watchlist doesn't exist, create a new entry
|
||||||
|
const response = await fetch("/api/update-watchlist", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ watchListId, ticker: $indexTicker }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const output = await response.json();
|
||||||
userWatchList = [...userWatchList, output];
|
userWatchList = [...userWatchList, output];
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("An error occurred:", error);
|
console.error("An error occurred:", error);
|
||||||
// Handle the error appropriately (e.g., show an error message to the user)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +325,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$: isTickerIncluded = userWatchList?.some(
|
$: isTickerIncluded = userWatchList?.some(
|
||||||
(item) => item.user === data?.user?.id && item.ticker?.includes($indexTicker),
|
(item) =>
|
||||||
|
item.user === data?.user?.id && item.ticker?.includes($indexTicker),
|
||||||
);
|
);
|
||||||
|
|
||||||
$: charNumber = $screenWidth < 640 ? 25 : 40;
|
$: charNumber = $screenWidth < 640 ? 25 : 40;
|
||||||
@ -372,7 +381,10 @@
|
|||||||
class="flex-1 flex-shrink-0 flex flex-row items-center justify-between -mt-2"
|
class="flex-1 flex-shrink-0 flex flex-row items-center justify-between -mt-2"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href={/^\/(stocks|etf|index)/.test($previousPage || "") ? "/" : $previousPage || "/"}>
|
href={/^\/(stocks|etf|index)/.test($previousPage || "")
|
||||||
|
? "/"
|
||||||
|
: $previousPage || "/"}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="w-5 h-5 inline-block"
|
class="w-5 h-5 inline-block"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -425,7 +437,9 @@
|
|||||||
<label
|
<label
|
||||||
class="mr-4"
|
class="mr-4"
|
||||||
on:click={() =>
|
on:click={() =>
|
||||||
shareContent("https://stocknear.com/index/" + $indexTicker)}
|
shareContent(
|
||||||
|
"https://stocknear.com/index/" + $indexTicker,
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
class="w-6 h-6 inline-block"
|
class="w-6 h-6 inline-block"
|
||||||
@ -880,8 +894,6 @@
|
|||||||
Options
|
Options
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={`/index/${$indexTicker}/history`}
|
href={`/index/${$indexTicker}/history`}
|
||||||
on:click={() => changeSection("history")}
|
on:click={() => changeSection("history")}
|
||||||
|
|||||||
@ -92,57 +92,65 @@
|
|||||||
|
|
||||||
async function toggleUserWatchlist(watchListId: string) {
|
async function toggleUserWatchlist(watchListId: string) {
|
||||||
try {
|
try {
|
||||||
isTickerIncluded = !isTickerIncluded;
|
// Find the index of the watchlist
|
||||||
|
|
||||||
const watchlistIndex = userWatchList?.findIndex(
|
const watchlistIndex = userWatchList?.findIndex(
|
||||||
(item) => item?.id === watchListId,
|
(item) => item?.id === watchListId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (watchlistIndex !== -1) {
|
if (watchlistIndex !== -1 && watchlistIndex !== undefined) {
|
||||||
const existingTickerIndex =
|
const watchlist = userWatchList[watchlistIndex];
|
||||||
userWatchList[watchlistIndex]?.ticker?.indexOf($stockTicker);
|
const existingTickerIndex = watchlist?.ticker?.indexOf($stockTicker);
|
||||||
|
|
||||||
|
let updatedTickers = [...(watchlist?.ticker || [])]; // Ensure we don't mutate directly
|
||||||
|
|
||||||
if (existingTickerIndex !== -1) {
|
if (existingTickerIndex !== -1) {
|
||||||
// If the $stockTicker exists, remove it from the array
|
// Remove the ticker if it exists
|
||||||
userWatchList[watchlistIndex]?.ticker?.splice(existingTickerIndex, 1);
|
updatedTickers.splice(existingTickerIndex, 1);
|
||||||
} else {
|
} else {
|
||||||
// If the $stockTicker doesn't exist, add it to the array
|
// Add the ticker if it doesn't exist
|
||||||
userWatchList[watchlistIndex]?.ticker?.push($stockTicker);
|
updatedTickers.push($stockTicker);
|
||||||
|
|
||||||
|
// Check tier limits
|
||||||
|
if (data?.user?.tier !== "Pro" && updatedTickers.length > 5) {
|
||||||
|
toast.error("Upgrade to Pro to add unlimited stocks!", {
|
||||||
|
style:
|
||||||
|
"border-radius: 5px; background: #fff; color: #000; border-color: #4B5563; font-size: 15px;",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the userWatchList
|
// Update the local state immutably
|
||||||
userWatchList = [...userWatchList];
|
userWatchList = userWatchList.map((item, idx) =>
|
||||||
}
|
idx === watchlistIndex ? { ...item, ticker: updatedTickers } : item,
|
||||||
|
);
|
||||||
const postData = {
|
|
||||||
watchListId: watchListId,
|
|
||||||
ticker: $stockTicker,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// Send API request
|
||||||
const response = await fetch("/api/update-watchlist", {
|
const response = await fetch("/api/update-watchlist", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: { "Content-Type": "application/json" },
|
||||||
"Content-Type": "application/json",
|
body: JSON.stringify({ watchListId, ticker: $stockTicker }),
|
||||||
},
|
|
||||||
body: JSON.stringify(postData),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Network response was not ok");
|
|
||||||
}
|
|
||||||
|
|
||||||
const output = await response.json();
|
const output = await response.json();
|
||||||
|
|
||||||
// Update the userWatchList with the response from the server
|
// Update userWatchList based on API response
|
||||||
if (watchlistIndex !== -1) {
|
userWatchList = userWatchList.map((item) =>
|
||||||
userWatchList[watchlistIndex] = output;
|
item.id === watchListId ? output : item,
|
||||||
userWatchList = [...userWatchList];
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// If watchlist doesn't exist, create a new entry
|
||||||
|
const response = await fetch("/api/update-watchlist", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ watchListId, ticker: $stockTicker }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const output = await response.json();
|
||||||
userWatchList = [...userWatchList, output];
|
userWatchList = [...userWatchList, output];
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("An error occurred:", error);
|
console.error("An error occurred:", error);
|
||||||
// Handle the error appropriately (e.g., show an error message to the user)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +397,9 @@
|
|||||||
class="flex-1 flex-shrink-0 flex flex-row items-center justify-between -mt-2"
|
class="flex-1 flex-shrink-0 flex flex-row items-center justify-between -mt-2"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href={/^\/(stocks|etf|index)/.test($previousPage || "") ? "/" : $previousPage || "/"}
|
href={/^\/(stocks|etf|index)/.test($previousPage || "")
|
||||||
|
? "/"
|
||||||
|
: $previousPage || "/"}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
class="w-5 h-5 inline-block"
|
class="w-5 h-5 inline-block"
|
||||||
|
|||||||
@ -472,6 +472,7 @@
|
|||||||
const postData = {
|
const postData = {
|
||||||
ticker: watchList?.map((item) => item?.symbol),
|
ticker: watchList?.map((item) => item?.symbol),
|
||||||
watchListId: displayWatchList?.id,
|
watchListId: displayWatchList?.id,
|
||||||
|
mode: "delete",
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch("/api/update-watchlist", {
|
const response = await fetch("/api/update-watchlist", {
|
||||||
@ -513,57 +514,86 @@
|
|||||||
}
|
}
|
||||||
displayList = rawTabData?.slice(0, 8);
|
displayList = rawTabData?.slice(0, 8);
|
||||||
}
|
}
|
||||||
async function handleAddTicker(event, ticker) {
|
|
||||||
// Ensure inputValue is reset
|
|
||||||
|
|
||||||
if (!watchList?.some((item) => item?.symbol === ticker)) {
|
async function handleAddTicker(event, ticker) {
|
||||||
} else {
|
event.preventDefault(); // Prevent the default form submission behavior
|
||||||
toast.error(`This symbol is already in your watchlist`, {
|
|
||||||
|
// Check if the ticker is already in the watchlist.
|
||||||
|
if (watchList?.some((item) => item?.symbol === ticker)) {
|
||||||
|
toast.error("This symbol is already in your watchlist", {
|
||||||
style:
|
style:
|
||||||
"border-radius: 5px; background: #fff; color: #000; border-color: #4B5563; font-size: 15px;",
|
"border-radius: 5px; background: #fff; color: #000; border-color: #4B5563; font-size: 15px;",
|
||||||
});
|
});
|
||||||
|
|
||||||
inputValue = "";
|
inputValue = "";
|
||||||
event.preventDefault();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit edit mode
|
// Exit edit mode.
|
||||||
editMode = false;
|
editMode = false;
|
||||||
|
|
||||||
// Prepare the data to send to the API
|
// Prepare the data to send to the API.
|
||||||
const postData = {
|
const postData = {
|
||||||
ticker: ticker,
|
ticker: ticker,
|
||||||
watchListId: displayWatchList?.id,
|
watchListId: displayWatchList?.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send the updated watchlist to the server
|
// Create a promise for the fetch request.
|
||||||
const response = await fetch("/api/update-watchlist", {
|
const promise = fetch("/api/update-watchlist", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(postData),
|
body: JSON.stringify(postData),
|
||||||
|
}).then(async (response) => {
|
||||||
|
const output = await response.json();
|
||||||
|
// If the response is not OK, throw an error with the message from the API.
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(output.error || "Failed to update watchlist");
|
||||||
|
}
|
||||||
|
return output;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the allList with the new watchlist
|
// Use toast.promise to display notifications based on the promise's state.
|
||||||
|
toast.promise(
|
||||||
|
promise,
|
||||||
|
{
|
||||||
|
loading: "Updating watchlist...",
|
||||||
|
success: "Watchlist updated successfully!",
|
||||||
|
error: (err) => err.message || "Failed to update watchlist",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
style:
|
||||||
|
"border-radius: 5px; background: #fff; color: #000; border-color: #4B5563; font-size: 15px;",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Await the promise, which returns the updated watchlist data.
|
||||||
|
const updatedData = await promise;
|
||||||
|
|
||||||
|
// Update the local allList with the updated watchlist.
|
||||||
|
// (Assuming updatedData.ticker contains the new ticker list.)
|
||||||
allList = allList?.map((item) => {
|
allList = allList?.map((item) => {
|
||||||
if (item?.id === displayWatchList?.id) {
|
if (item?.id === displayWatchList?.id) {
|
||||||
return { ...item, tickers: watchList }; // Update tickers in the watchlist
|
return { ...item, tickers: updatedData.ticker };
|
||||||
}
|
}
|
||||||
return item; // Return unchanged item
|
return item;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh the displayWatchList with the updated watchlist
|
// Refresh displayWatchList from the updated list.
|
||||||
displayWatchList = allList?.find(
|
displayWatchList = allList?.find(
|
||||||
(item) => item?.id === displayWatchList?.id,
|
(item) => item?.id === displayWatchList?.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fetch the updated watchlist data (assuming this function refreshes the UI or state)
|
// Refresh the watchlist data (UI or state refresh).
|
||||||
await getWatchlistData();
|
await getWatchlistData();
|
||||||
|
|
||||||
|
// Reset the input value.
|
||||||
inputValue = "";
|
inputValue = "";
|
||||||
event?.preventDefault();
|
} catch (error) {
|
||||||
|
console.error("Error updating watchlist:", error);
|
||||||
|
// Note: The error toast is already displayed by toast.promise.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleResetAll() {
|
async function handleResetAll() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user