From b2261f9101480afb31322cf620f028cdade0671c Mon Sep 17 00:00:00 2001 From: Max Nanis Date: Sat, 12 Sep 2026 14:30:31 -0700 Subject: new landing page that combines leaderboard + login. fixing worker_id assignment, it'll still be needed until transfer is finished --- jb-ui/src/JBApp.tsx | 13 +++- jb-ui/src/pages/Preview.tsx | 142 +++++++++++++++++++++++++++++++++++-------- jb-ui/src/pages/Transfer.tsx | 13 +--- jb-ui/src/pages/Work.tsx | 78 +----------------------- 4 files changed, 131 insertions(+), 115 deletions(-) diff --git a/jb-ui/src/JBApp.tsx b/jb-ui/src/JBApp.tsx index a69cc85..6c31164 100644 --- a/jb-ui/src/JBApp.tsx +++ b/jb-ui/src/JBApp.tsx @@ -78,6 +78,11 @@ function QueryParamProcessor() { 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 (user?.product_user_id) { dispatch(setProductUserID(user.product_user_id)); @@ -119,7 +124,10 @@ function QueryParamProcessor() { const Layout = () => { const location = useLocation(); - const isSpecialSubview = useMatch("/work/*"); + + const isWork = useMatch("/work*"); + const isPreview = useMatch("/preview*"); + const isSpecialSubview = Boolean(isWork || isPreview); return (
@@ -225,9 +233,8 @@ function JBApp() { }> } /> } /> - {/* } /> */} - } /> + } /> } /> } /> diff --git a/jb-ui/src/pages/Preview.tsx b/jb-ui/src/pages/Preview.tsx index 1926975..85e49f2 100644 --- a/jb-ui/src/pages/Preview.tsx +++ b/jb-ui/src/pages/Preview.tsx @@ -5,6 +5,7 @@ import { LeaderboardFrequency, LeaderboardRow, } from "@/api_fsb"; +import { Button } from "@/components/ui/button"; import { useAppSelector } from "@/hooks"; import { bpid, formatCentsToUSD, truncate } from "@/lib/utils"; import { activeSurveys, activeUsers, maxPayout } from "@/models/grlStatsSlice"; @@ -244,6 +245,98 @@ export const Leaderboards = () => { ); }; +type RequestState = "idle" | "working" | "failed"; + +const LoginForm = function ({ onSubmitSuccess }) { + const [email, setEmail] = useState(""); + const [state, setState] = useState("idle"); + + // const dispatch = useAppDispatch(); + const submit = async (event: FormEvent) => { + event.preventDefault(); + setState("working"); + + try { + const response = await fetch("/auth/magic-link/request", { + method: "POST", + credentials: "include", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + email: email, + }), + }); + + if (!response.ok) throw new Error("Account-link request failed"); + const body = (await response.json()) as { magic_link?: string }; + console.log(body.magic_link ?? null); + onSubmitSuccess(); + } catch { + setState("failed"); + } + }; + + return ( + <> +
+
+ setEmail(event.target.value)} + placeholder="hello@jamesbillings67.com" + aria-label="Email address" + /> + + +
+
+ + {state === "failed" &&

Unable to send the link. Please try again.

} + + ); +}; + +const LoginSent = function () { + return ( +
+

+ Please check your email. +

+

+ If you don't recieve anything, please check your spam folder, or try + again shortly. +

+
+ ); +}; + +const Login = () => { + const [submitted, setSubmitted] = useState(false); + + return ( + <> + {submitted ? ( + + ) : ( + setSubmitted(true)} /> + )} + + ); +}; + // Preview Component const Preview = () => { /** @@ -267,33 +360,32 @@ const Preview = () => { ); return ( -
-
-

- {users_f} people are actively attempting {surveys_f} available surveys - right now. -

-
+ <> + + +
+
+

+ {users_f} people are actively attempting {surveys_f} available + surveys right now. +

+
- - -
-

- Get paid to take surveys. Our algorithm attempts to pair you with the - highest paying survey available at the moment (right now, the highest - paying survey is {survey_max_cpi_f}) that you are eligible for, each - attempt is a valid HIT. Try as many as you can, our system will self - regulate you: we want to ensure you have a high chance of being paired - with a survey based on what surveys are available, as their - availability constantly changes. -

-

- Each HIT is paid when you attempt to take a survey and if you complete - the survey, you will be awarded a bonus equal to that in which the - survey pays out. -

+ + +
+

+ Get paid to take surveys. Our algorithm attempts to pair you with + the highest paying survey available at the moment (right now, the + highest paying survey is {survey_max_cpi_f}) that you are eligible + for, each attempt is a valid HIT. Try as many as you can, our system + will self regulate you: we want to ensure you have a high chance of + being paired with a survey based on what surveys are available, as + their availability constantly changes. +

+
-
+ ); }; export default Preview; diff --git a/jb-ui/src/pages/Transfer.tsx b/jb-ui/src/pages/Transfer.tsx index 4192eee..0d174c1 100644 --- a/jb-ui/src/pages/Transfer.tsx +++ b/jb-ui/src/pages/Transfer.tsx @@ -132,11 +132,11 @@ const TransferSubmit = function ({ onSubmitSuccess }) { }; const Transfer = function () { - const assignment_id = useAppSelector((state) => state.app.assignment_id); + const bpuid = useAppSelector((state) => state.app.bpuid); const { data: user, isLoading, isError } = useGetMeQuery(); const [submitted, setSubmitted] = useState(false); - if (!user?.product_user_id) { + if (!bpuid) { return (

No Worker ID found. Please access this page through the Amazon @@ -145,15 +145,6 @@ const Transfer = function () { ); } - if (!assignment_id) { - return ( -

- No Assignment ID found. Please access this page through the Amazon - Mechanical Turk platform. -

- ); - } - return ( <> {submitted ? ( diff --git a/jb-ui/src/pages/Work.tsx b/jb-ui/src/pages/Work.tsx index 84cb946..dbe3601 100644 --- a/jb-ui/src/pages/Work.tsx +++ b/jb-ui/src/pages/Work.tsx @@ -11,6 +11,7 @@ import { TaskStatusResponse, TopNPlusBlockOfferWall, } from "@/api_fsb"; +import Preview from "@/pages/Preview"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; @@ -793,81 +794,6 @@ const SurveyEnter = () => { ); }; -type RequestState = "idle" | "working" | "sent" | "failed"; - -const Login = () => { - const [email, setEmail] = useState(""); - const [state, setState] = useState("idle"); - - // const dispatch = useAppDispatch(); - const submit = async (event: FormEvent) => { - event.preventDefault(); - setState("working"); - - try { - const response = await fetch("/auth/magic-link/request", { - method: "POST", - credentials: "include", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - email: email, - }), - }); - - if (!response.ok) throw new Error("Account-link request failed"); - - const body = (await response.json()) as { magic_link?: string }; - console.log(body.magic_link ?? null); - } catch { - setState("failed"); - } - }; - - return ( -
-

- Please Login -

- -
- setEmail(event.target.value)} - placeholder="hello@jamesbillings67.com" - /> - -
- - {state === "sent" && ( -

- Check your email to login. -

- )} - - {state === "failed" &&

Unable to send the link. Please try again.

} -
- ); -}; - const Work = () => { const entered = useAppSelector((state) => state.app.currentBucketEntered); // const assignment_id = useAppSelector((state) => state.app.assignment_id); @@ -886,7 +812,7 @@ const Work = () => { if (isLoading) return
Loading...
; if (isError || !user) { - return ; + return ; } return <>{entered ? : }; -- cgit v1.2.3