diff options
| author | Max Nanis | 2026-09-13 19:03:55 +0000 |
|---|---|---|
| committer | Max Nanis | 2026-09-13 19:03:55 +0000 |
| commit | 8fbe8d439b418796932aaa88297e006c714e4d13 (patch) | |
| tree | 6c800476edc1e771fc570b559d483df8d59d4324 /jb-ui/src/JBApp.tsx | |
| parent | 12f6fee851b68e86af658dfa17e4a0daed457dd1 (diff) | |
| parent | 2c94f248d2438071a918fa9a30bf114ef9aa29b4 (diff) | |
| download | amt-jb-8fbe8d439b418796932aaa88297e006c714e4d13.tar.gz amt-jb-8fbe8d439b418796932aaa88297e006c714e4d13.zip | |
Merges pull request #3
Off of Amazon!!!
Diffstat (limited to 'jb-ui/src/JBApp.tsx')
| -rw-r--r-- | jb-ui/src/JBApp.tsx | 405 |
1 files changed, 242 insertions, 163 deletions
diff --git a/jb-ui/src/JBApp.tsx b/jb-ui/src/JBApp.tsx index 76e3f29..c55cd73 100644 --- a/jb-ui/src/JBApp.tsx +++ b/jb-ui/src/JBApp.tsx @@ -1,29 +1,52 @@ import { - EventMessage, - EventType, - PingMessage, - PongMessage, - PongMessageKindEnum, - StatsMessage, - StatusApi, - SubscribeMessage, SubscribeMessageKindEnum, - TaskStatusResponse, - UserWalletBalance, - UserWalletBalanceResponse, - WalletApi + EventMessage, + EventType, + PingMessage, + PongMessage, + PongMessageKindEnum, + StatsMessage, + StatusApi, + SubscribeMessage, + SubscribeMessageKindEnum, + TaskStatusResponse, + UserWalletBalance, + UserWalletBalanceResponse, + UserLedgerWallets, + UserLedgerWalletAccountTypeEnum, + WalletApi, + CashoutMethodsResponse, } from "@/api_fsb"; import Footer from "@/components/Footer"; import { useAppDispatch } from "@/hooks"; import { bpid, routeBasename, tagManager } from "@/lib/utils"; -import { setAssignmentID, setProductUserID, setTurkSubmitTo } from "@/models/appSlice"; +import { useGetMeQuery } from "@/models/authAPI"; +import { + setAssignmentID, + setProductUserID, + setUserDisplayedWalletBalance, + setUserWallet, + setUserAttemptCreditWallet, +} from "@/models/appSlice"; + +import { addCashoutMethods } from "@/models/cashoutMethodsSlice"; + import { addEvent } from "@/models/grlEventsSlice"; import { addStatsData } from "@/models/grlStatsSlice"; -import Home from "@/pages/Home"; -import Preview from "@/pages/Preview"; +import MagicLink from "@/pages/MagicLink"; import Result from "@/pages/Result"; +import clsx from "clsx"; + import Work from "@/pages/Work"; -import { BrowserRouter, Outlet, Route, Routes, useSearchParams } from "react-router-dom"; -import useWebSocket from 'react-use-websocket'; +import Transfer from "@/pages/Transfer"; +import { + BrowserRouter, + Outlet, + useMatch, + Route, + Routes, + useSearchParams, +} from "react-router-dom"; +import useWebSocket from "react-use-websocket"; import NewsTicker from "./components/EventMarquee"; import { useEffect } from "react"; @@ -32,178 +55,234 @@ import Wallet from "@/components/Wallet"; import "@/index.css"; import { setTaskStatus, setUserWalletBalance } from "@/models/appSlice"; import { Profiling } from "./components/Profiling"; +import Redemption from "./components/Redemption"; -type Message = PingMessage | PongMessage | SubscribeMessage | EventMessage | StatsMessage; +type Message = + | PingMessage + | PongMessage + | SubscribeMessage + | EventMessage + | StatsMessage; function isStatsMessage(msg: Message): msg is StatsMessage { - return msg.kind === 'stats'; + return msg.kind === "stats"; } function isEventMessage(msg: Message): msg is EventMessage { - return msg.kind === 'event'; + return msg.kind === "event"; } function isPingMessage(msg: Message): msg is PingMessage { - return msg.kind === 'ping'; + return msg.kind === "ping"; } function QueryParamProcessor() { - const dispatch = useAppDispatch() - const [searchParams] = useSearchParams(); + const dispatch = useAppDispatch(); + const [searchParams] = useSearchParams(); + const { data: user } = useGetMeQuery(); - useEffect(() => { - const worker_id = searchParams.get('workerId'); - const assignment_id = searchParams.get('assignmentId'); - const tsid = searchParams.get('tsid'); - const turkSubmitTo = searchParams.get('turkSubmitTo'); + useEffect(() => { + if (user?.product_user_id) { + dispatch(setProductUserID(user.product_user_id)); - if (turkSubmitTo) { - dispatch(setTurkSubmitTo(turkSubmitTo)) - } + new WalletApi() + .getCashoutMethodsProductIdCashoutMethodsGet(bpid, user.product_user_id) + .then((res) => { + const response = res.data as CashoutMethodsResponse; + dispatch(addCashoutMethods(response.cashout_methods)); + }); - if (worker_id) { - dispatch(setProductUserID(worker_id)) - - new WalletApi().getUserWalletBalanceProductIdWalletGet( - bpid, // productId - worker_id, // bpuid - ).then(res => { - const response = res.data as UserWalletBalanceResponse; - const balance = response.wallet as UserWalletBalance; - dispatch(setUserWalletBalance(balance)); - }); - } + new WalletApi() + .getUserWalletBalanceProductIdWalletGet( + bpid, // productId + user.product_user_id, + ) + .then((res) => { + const response = res.data as UserWalletBalanceResponse; + const balance = response.wallet as UserWalletBalance; + dispatch(setUserWalletBalance(balance)); + }); - if (assignment_id) { - dispatch(setAssignmentID(assignment_id)) - } + new WalletApi() + .getUserWalletsProductIdWalletsGet(bpid, user.product_user_id) + .then((res) => { + const response = res.data as UserLedgerWallets; - if (tsid) { - new StatusApi().getTaskStatusProductIdStatusTsidGet( - bpid, // productId - tsid).then(res => { - const response: TaskStatusResponse = res.data; - dispatch(setTaskStatus(response)) - }).catch((error) => { - console.error("Error fetching task status:", error); - }); - } + if (response.displayed_balances) { + setUserDisplayedWalletBalance(response.displayed_balances[0]); + } - }, [searchParams]); + const userWallet = response.wallets?.find( + (w) => + w.account_type === UserLedgerWalletAccountTypeEnum.UserWallet, + ); + if (userWallet) { + setUserWallet(userWallet); + } - return <Outlet />; + const userAttemptCreditWallet = response.wallets?.find( + (w) => + w.account_type === + UserLedgerWalletAccountTypeEnum.UserAttemptCredit, + ); + if (userAttemptCreditWallet) { + setUserAttemptCreditWallet(userAttemptCreditWallet); + } + }); + } + }, [user]); + + useEffect(() => { + const assignment_id = searchParams.get("assignmentId"); + const tsid = searchParams.get("tsid"); + const worker_id = searchParams.get("workerId"); + + if (worker_id) { + dispatch(setProductUserID(worker_id)); + } + + if (assignment_id) { + dispatch(setAssignmentID(assignment_id)); + } + + if (tsid) { + new StatusApi() + .getTaskStatusProductIdStatusTsidGet( + bpid, // productId + tsid, + ) + .then((res) => { + const response: TaskStatusResponse = res.data; + dispatch(setTaskStatus(response)); + }) + .catch((error) => { + console.error("Error fetching task status:", error); + }); + } + }, [searchParams]); + + return <Outlet />; } const Layout = () => { - return ( - <div className="flex flex-col min-h-screen"> - <header className="bg-amber-400 text-amber-950 py-2 text-center"> - <a href="https://www.reddit.com/r/Marketresearch/comments/1s2tl0o/open_letter_to_cint_supplier_quality_issues/" target="_blank"> - <h4 className="text-[12px]"> - Letter to Cint: supplier quality issues, and malware-linked panels. - </h4> - </a> - </header> - - <main className="flex flex-1 bg-zinc-200"> - <div className="flex flex-col items-center justify-center flex-1"> - <div className=" - w-full max-w-full - p-2 bg-white shadow-lg - text-center space-y-4 - md:max-w-5/8 md:rounded-lg - rounded-none - "> - <Wallet /> - <Profiling /> - <Outlet /> - </div> - </div> - </main > - - <footer className="bg-slate-700 text-zinc-200 p-2 text-center font-mono"> - <NewsTicker /> - <Footer /> - </footer> - - </div > - ); + const isWork = useMatch("/work/*"); + const isPreview = useMatch("/preview/*"); + const isSpecialSubview = Boolean(isWork || isPreview); + + return ( + <div className="flex flex-col min-h-screen"> + <header className="bg-amber-400 text-amber-950 py-2 text-center"> + <a + href="https://www.reddit.com/r/Marketresearch/comments/1s2tl0o/open_letter_to_cint_supplier_quality_issues/" + target="_blank" + > + <h4 className="text-[12px]"> + Letter to Cint: supplier quality issues, and malware-linked panels. + </h4> + </a> + </header> + + <main className="flex flex-1 bg-zinc-200"> + <div className="flex flex-col items-center justify-center flex-1"> + <div + className={clsx( + "w-full max-w-full p-2 bg-white shadow-lg text-center space-y-4 md:max-w-5/8 md:rounded-lg rounded-none", + isSpecialSubview && "border-6 border-amber-400", + )} + > + <Wallet /> + <Profiling /> + <Redemption /> + <Outlet /> + </div> + </div> + </main> + + <footer className="bg-slate-700 text-zinc-200 p-2 text-center font-mono"> + <NewsTicker /> + <Footer /> + </footer> + </div> + ); }; function JBApp() { - const dispatch = useAppDispatch() - - const { sendJsonMessage, lastMessage } = useWebSocket( - "wss://fsb.generalresearch.com/ws/events/", { - onOpen: () => { - const subscribe: SubscribeMessage = { - "kind": SubscribeMessageKindEnum.Subscribe, - "product_id": bpid - } - sendJsonMessage(subscribe) + const dispatch = useAppDispatch(); + + const { sendJsonMessage, lastMessage } = useWebSocket( + "wss://fsb.generalresearch.com/ws/events/", + { + onOpen: () => { + const subscribe: SubscribeMessage = { + kind: SubscribeMessageKindEnum.Subscribe, + product_id: bpid, + }; + sendJsonMessage(subscribe); + }, + }, + ); + + useEffect(() => { + if (lastMessage !== null) { + let msg: Message = JSON.parse(lastMessage.data); + + if (isStatsMessage(msg)) { + dispatch(addStatsData(msg.data)); + } else if (isEventMessage(msg)) { + // For simplicity, we just log the event messages here. + // You can extend this to update the UI or trigger notifications as needed. + + switch (msg.data.event_type) { + case EventType.TaskEnter: + case EventType.TaskFinish: + case EventType.UserCreated: + dispatch(addEvent(msg.data)); + break; + + default: + // do nothing for now + break; } + } else if (isPingMessage(msg)) { + const pong: PongMessage = { + kind: PongMessageKindEnum.Pong, + }; + sendJsonMessage(pong); + } } - ); - - useEffect(() => { - if (lastMessage !== null) { - let msg: Message = JSON.parse(lastMessage.data); - - if (isStatsMessage(msg)) { - dispatch(addStatsData(msg.data)) - - } else if (isEventMessage(msg)) { - // For simplicity, we just log the event messages here. - // You can extend this to update the UI or trigger notifications as needed. - - switch (msg.data.event_type) { - case EventType.TaskEnter: - case EventType.TaskFinish: - case EventType.UserCreated: - dispatch(addEvent(msg.data)); - break - - default: - // do nothing for now - break; - } - - } else if (isPingMessage(msg)) { - const pong: PongMessage = { - "kind": PongMessageKindEnum.Pong, - } - sendJsonMessage(pong) - } - } - }, [lastMessage]); - - useEffect(() => { - if (!tagManager) return; - - var _mtm = window._mtm = window._mtm || []; - _mtm.push({ 'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start' }); - var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0]; - g.async = true; - g.src = tagManager; - if (s.parentNode) { - s.parentNode.insertBefore(g, s); - } - }, [tagManager]) - - return ( - <BrowserRouter basename={routeBasename}> - <Routes> - <Route element={<QueryParamProcessor />}> - <Route element={<Layout />}> - <Route path="/" element={<Home />} /> - <Route path="/preview/" element={<Preview />} /> - <Route path="/work/" element={<Work />} /> - <Route path="/result/" element={<Result />} /> - </Route> - </Route> - </Routes> - </BrowserRouter> - ) + }, [lastMessage]); + + useEffect(() => { + if (!tagManager) return; + + var _mtm = (window._mtm = window._mtm || []); + _mtm.push({ "mtm.startTime": new Date().getTime(), event: "mtm.Start" }); + var d = document, + g = d.createElement("script"), + s = d.getElementsByTagName("script")[0]; + g.async = true; + g.src = tagManager; + if (s.parentNode) { + s.parentNode.insertBefore(g, s); + } + }, [tagManager]); + + return ( + <BrowserRouter basename={routeBasename}> + <Routes> + <Route element={<QueryParamProcessor />}> + <Route element={<Layout />}> + <Route path="/" element={<Work />} /> + <Route path="/auth/magic-link/" element={<MagicLink />} /> + + <Route path="/preview/" element={<Transfer />} /> + <Route path="/work/" element={<Transfer />} /> + <Route path="/result/" element={<Result />} /> + </Route> + </Route> + </Routes> + </BrowserRouter> + ); } -export default JBApp;
\ No newline at end of file +export default JBApp; |
