diff options
| -rw-r--r-- | jb-ui/src/JBApp.tsx | 13 | ||||
| -rw-r--r-- | jb-ui/src/pages/Preview.tsx | 142 | ||||
| -rw-r--r-- | jb-ui/src/pages/Transfer.tsx | 13 | ||||
| -rw-r--r-- | 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 ( <div className="flex flex-col min-h-screen"> @@ -225,9 +233,8 @@ function JBApp() { <Route element={<Layout />}> <Route path="/" element={<Work />} /> <Route path="/auth/magic-link/" element={<MagicLink />} /> - {/* <Route path="/work/" element={<Work />} /> */} - <Route path="/preview/" element={<Preview />} /> + <Route path="/preview/" element={<Transfer />} /> <Route path="/work/" element={<Transfer />} /> <Route path="/result/" element={<Result />} /> </Route> 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<RequestState>("idle"); + + // const dispatch = useAppDispatch(); + const submit = async (event: FormEvent<HTMLFormElement>) => { + 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 ( + <> + <form className="w-full" onSubmit={submit}> + <div className="flex items-center border-b-4 border-blue-700 py-2"> + <input + className="appearance-none bg-transparent border-none w-full text-gray-700 mr-3 py-1 px-2 leading-tight focus:outline-none font-semibold" + type="email" + autoComplete="email" + required + value={email} + onChange={(event) => setEmail(event.target.value)} + placeholder="hello@jamesbillings67.com" + aria-label="Email address" + /> + + <button + className="flex-shrink-0 bg-blue-700 hover:bg-blue-800 text-white py-1 px-2 rounded cursor-pointer font-semibold" + type="submit" + disabled={state === "working"} + > + {state === "working" ? "Sending…" : "Login / Signup"} + </button> + </div> + </form> + + {state === "failed" && <p>Unable to send the link. Please try again.</p>} + </> + ); +}; + +const LoginSent = function () { + return ( + <div className="my-1"> + <h2 + className=" + bg-emerald-400 rounded py-2 + text-white text-l font-semibold text-center" + > + Please check your email. + </h2> + <p className="text-slate-800 text-xs font-semibold text-center my-1 py-2"> + If you don't recieve anything, please check your spam folder, or try + again shortly. + </p> + </div> + ); +}; + +const Login = () => { + const [submitted, setSubmitted] = useState(false); + + return ( + <> + {submitted ? ( + <LoginSent /> + ) : ( + <LoginForm onSubmitSuccess={() => setSubmitted(true)} /> + )} + </> + ); +}; + // Preview Component const Preview = () => { /** @@ -267,33 +360,32 @@ const Preview = () => { ); return ( - <div className="max-h-[calc(100vh-10rem)] overflow-y-auto"> - <div className="bg-zinc-100 rounded py-2 m-0"> - <p className="text-center text-sm italic text-zinc-600"> - {users_f} people are actively attempting {surveys_f} available surveys - right now. - </p> - </div> + <> + <Login /> + + <div className="max-h-[calc(100vh-10rem)] overflow-y-auto"> + <div className="bg-zinc-100 rounded py-2 m-0"> + <p className="text-center text-sm italic text-zinc-600"> + {users_f} people are actively attempting {surveys_f} available + surveys right now. + </p> + </div> - <Leaderboards /> - - <div className="bg-zinc-100 rounded py-2 px-6 m-0 text-xs text-center"> - <p className="py-1"> - 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. - </p> - <p className="py-1"> - 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. - </p> + <Leaderboards /> + + <div className="bg-zinc-100 rounded py-2 px-6 m-0 text-xs text-center"> + <p className="py-1"> + 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. + </p> + </div> </div> - </div> + </> ); }; 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 ( <p className="text-center text-2xl py-3 text-red-800 font-semibold"> No Worker ID found. Please access this page through the Amazon @@ -145,15 +145,6 @@ const Transfer = function () { ); } - if (!assignment_id) { - return ( - <p className="text-center text-2xl py-3 text-red-800 font-semibold"> - No Assignment ID found. Please access this page through the Amazon - Mechanical Turk platform. - </p> - ); - } - 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<RequestState>("idle"); - - // const dispatch = useAppDispatch(); - const submit = async (event: FormEvent<HTMLFormElement>) => { - 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 ( - <div className="px-6 my-6"> - <h2 - className=" - bg-blue-700 rounded py-2 - text-white text-2xl font-semibold text-center" - > - Please Login - </h2> - - <form onSubmit={submit}> - <input - className="w-full rounded-md border-3 border-slate-700 px-3 py-2 font-semibold my-5" - type="email" - autoComplete="email" - required - value={email} - onChange={(event) => setEmail(event.target.value)} - placeholder="hello@jamesbillings67.com" - /> - <Button - className="w-1/2 font-semibold bg-slate-600 cursor-pointer hover:bg-blue-950" - type="submit" - disabled={state === "working"} - > - {state === "working" ? "Sending…" : "Login"} - </Button> - </form> - - {state === "sent" && ( - <h4 - className=" - mt-2 - bg-slate-500 rounded py-2 - text-white text-l font-semibold text-center" - > - Check your email to login. - </h4> - )} - - {state === "failed" && <p>Unable to send the link. Please try again.</p>} - </div> - ); -}; - 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 <div>Loading...</div>; if (isError || !user) { - return <Login />; + return <Preview />; } return <>{entered ? <SurveyMonitor /> : <SurveyEnter />}</>; |
