diff --git a/public/lang/en.json b/public/lang/en.json index ff4ebe33..5cfbff2c 100644 --- a/public/lang/en.json +++ b/public/lang/en.json @@ -364,6 +364,16 @@ "message": "The order has been successfully deleted." } }, + "blacklist_order": { + "error": { + "title": "Blacklist Error", + "message": "An error occurred while trying to blacklist the item." + }, + "success": { + "title": "Blacklist Success", + "message": "The item has been blacklisted and its listing removed." + } + }, "delete_all_orders": { "error": { "title": "Delete All Orders Error", @@ -473,6 +483,12 @@ "cancel": "Cancel", "confirm": "Confirm" }, + "blacklist_item": { + "title": "Blacklist item?", + "message": "This will remove your listing from Warframe Market and add the item to your blacklist. This action cannot be undone.", + "cancel": "Cancel", + "confirm": "Blacklist" + }, "delete_multiple_items": { "title": "Are you sure?", "message": "Are you sure you want to delete these {{count}} items? This action cannot be undone.", @@ -2101,6 +2117,7 @@ "refresh_tooltip": "Refresh the order list", "delete_all_tooltip": "Delete all orders", "delete_tooltip": "Delete this order", + "blacklist_tooltip": "Blacklist item and remove listing", "info_tooltip": "View order details", "sell_manual": { "buy_tooltip": "Bought manually", diff --git a/src/pages/warframe_market/Tabs/Orders/index.tsx b/src/pages/warframe_market/Tabs/Orders/index.tsx index 99637f6a..298679bc 100644 --- a/src/pages/warframe_market/Tabs/Orders/index.tsx +++ b/src/pages/warframe_market/Tabs/Orders/index.tsx @@ -6,7 +6,17 @@ import { Loading } from "@components/Shared/Loading"; import { PaginationFooter } from "@components/Shared/PaginationFooter"; import { PreviewCard } from "@components/Shared/PreviewCard/PreviewCard"; import { TextTranslate } from "@components/Shared/TextTranslate"; -import { faArrowDown, faArrowUp, faCartShopping, faInfoCircle, faPen, faRefresh, faSackDollar, faTrashCan } from "@fortawesome/free-solid-svg-icons"; +import { + faArrowDown, + faArrowUp, + faBan, + faCartShopping, + faInfoCircle, + faPen, + faRefresh, + faSackDollar, + faTrashCan, +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useHasAlert } from "@hooks/useHasAlert.hook"; import { useTauriEvent } from "@hooks/useTauriEvent.hook"; @@ -51,18 +61,20 @@ export const OrderPanel = ({ isActive }: OrderPanelProps) => { const { refetchQueries, paginationQuery, statusCountsQuery } = useStockQueries({ queryData, isActive }); // Mutations - const { refreshOrdersMutation, deleteAllOrdersMutation, deleteStockMutation, createStockMutation, sellStockMutation } = useStockMutations({ - refetchQueries, - setLoadingRows, - }); + const { refreshOrdersMutation, deleteAllOrdersMutation, deleteStockMutation, createStockMutation, sellStockMutation, blacklistOrderMutation } = + useStockMutations({ + refetchQueries, + setLoadingRows, + }); // Modals - const { OpenDeleteAllModal, OpenInfoModal, OpenDeleteModal, HandleModalOrder } = useStockModals({ + const { OpenDeleteAllModal, OpenInfoModal, OpenDeleteModal, OpenBlacklistModal, HandleModalOrder } = useStockModals({ createStockMutation, sellStockMutation, useTranslateBasePrompt, deleteStockMutation, deleteAllOrdersMutation, + blacklistOrderMutation, }); const handleRefresh = (_data: any) => { refetchQueries(true); @@ -304,6 +316,18 @@ export const OrderPanel = ({ isActive }: OrderPanelProps) => { OpenInfoModal(order); }} /> + { + e.stopPropagation(); + OpenBlacklistModal(order); + }} + /> string; deleteStockMutation: { mutateAsync: (id: string) => Promise; }; + blacklistOrderMutation: { + mutateAsync: (order: WFMarketTypes.Order) => Promise; + }; deleteAllOrdersMutation: { mutateAsync: (order_type?: WFMarketTypes.OrderType) => Promise; }; @@ -20,7 +24,13 @@ interface ModalHooks { }; } -export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, createStockMutation, sellStockMutation }: ModalHooks) => { +export const useStockModals = ({ + deleteStockMutation, + deleteAllOrdersMutation, + createStockMutation, + sellStockMutation, + blacklistOrderMutation, +}: ModalHooks) => { const OpenSellModal = (order: WFMarketTypes.Order) => { modals.openContextModal({ modal: "prompt", @@ -111,6 +121,17 @@ export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, c onConfirm: async () => await deleteStockMutation.mutateAsync(id), }); }; + const OpenBlacklistModal = (order: WFMarketTypes.Order) => { + modals.openConfirmModal({ + title: useTranslateCommon("prompts.blacklist_item.title"), + children: {useTranslateCommon("prompts.blacklist_item.message")}, + labels: { confirm: useTranslateCommon("prompts.blacklist_item.confirm"), cancel: useTranslateCommon("prompts.blacklist_item.cancel") }, + onConfirm: async () => { + await blacklistOrderMutation.mutateAsync(order); + SendTauriEvent(TauriTypes.Events.RefreshSettings); + }, + }); + }; const OpenDeleteAllModal = () => { modals.openContextModal({ modal: "prompt", @@ -145,6 +166,7 @@ export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, c return { HandleModalOrder, OpenDeleteModal, + OpenBlacklistModal, OpenDeleteAllModal, OpenInfoModal, }; diff --git a/src/pages/warframe_market/Tabs/Orders/mutations.ts b/src/pages/warframe_market/Tabs/Orders/mutations.ts index 224343da..075867f9 100644 --- a/src/pages/warframe_market/Tabs/Orders/mutations.ts +++ b/src/pages/warframe_market/Tabs/Orders/mutations.ts @@ -1,9 +1,11 @@ -import { WFMarketTypes } from "$types"; +import { TauriTypes, WFMarketTypes } from "$types"; import api from "@api/index"; +import { useAppContext } from "@contexts/app.context"; import { createGenericMutation, MutationHooks } from "@utils/genericMutation.helper"; export const useStockMutations = ({ refetchQueries, setLoadingRows }: MutationHooks) => { const hooks = { refetchQueries, setLoadingRows }; + const { settings } = useAppContext(); const refreshOrdersMutation = createGenericMutation( { @@ -73,11 +75,36 @@ export const useStockMutations = ({ refetchQueries, setLoadingRows }: MutationHo hooks, ); + const blacklistOrderMutation = createGenericMutation( + { + mutationFn: async (order: WFMarketTypes.Order) => { + if (!settings) throw new Error("Settings are not loaded"); + const wfm_id = order.properties?.wfm_id || order.itemId; + const allModes = [TauriTypes.TradeMode.Buy, TauriTypes.TradeMode.Sell, TauriTypes.TradeMode.Wishlist]; + const blacklist = settings.live_scraper.stock_item.blacklist || []; + const updatedBlacklist = [...blacklist.filter((b) => b.wfmId !== wfm_id), { wfmId: wfm_id, disabled_for: allModes }]; + await api.app.updateSettings({ + ...settings, + live_scraper: { + ...settings.live_scraper, + stock_item: { ...settings.live_scraper.stock_item, blacklist: updatedBlacklist }, + }, + }); + return api.order.deleteById(order.id); + }, + successKey: "blacklist_order", + errorKey: "blacklist_order", + getLoadingId: (order: WFMarketTypes.Order) => `${order.id}`, + }, + hooks, + ); + return { refreshOrdersMutation, deleteAllOrdersMutation, createStockMutation, sellStockMutation, deleteStockMutation, + blacklistOrderMutation, }; };