From 74890e251dee3e0f195583431cb48b9f3a58ecc9 Mon Sep 17 00:00:00 2001 From: Max Nanis Date: Mon, 9 Jun 2025 16:05:52 +0700 Subject: Cashout Methods page: adding walletSlice and cashoutmethodsSlice so they're in the stored state. Iterating with fix vs variable filters. Pulling old validators from old code and setting up the wallet fetch. --- src/pages/CashoutMethods.tsx | 207 +++++++++++++++++++++++++++++++++++++------ src/pages/Offerwall.tsx | 89 +++++++++++-------- 2 files changed, 232 insertions(+), 64 deletions(-) (limited to 'src/pages') diff --git a/src/pages/CashoutMethods.tsx b/src/pages/CashoutMethods.tsx index 9656087..fca6af0 100644 --- a/src/pages/CashoutMethods.tsx +++ b/src/pages/CashoutMethods.tsx @@ -1,45 +1,202 @@ -import React, {useEffect, useState} from 'react' +import React, {useState} from 'react' +import {Card, CardContent, CardHeader,} from "@/components/ui/card" +import {Tabs, TabsContent, TabsList, TabsTrigger,} from "@/components/ui/tabs" +import {Badge} from "@/components/ui/badge" + +import {selectFixedCashoutMethods, selectVariableCashoutMethods} from "@/models/cashoutMethodSlice.ts"; +import {CashoutMethodOut, UserWalletBalance} from "@/api" +import {formatCentsToUSD} from "@/lib/utils.ts"; +import {useSelector} from 'react-redux' +import {motion} from "framer-motion"; +import {Drawer, DrawerContent, DrawerDescription, DrawerHeader, DrawerTitle,} from "@/components/ui/drawer" +import {useAppSelector} from "@/hooks.ts"; + +const CashoutAcknowledgement = () => { + return ( + <> +

Your request has been successfully submitted!

+
+ + + Request Status: + Pending +
+

Your redemption link will be on the history page.

+ + ) +} + +const CashoutReview: React.FC<{ cashout_method: CashoutMethodOut }> = ({cashout_method}) => { + return ( + <> +

You are about to redeem to a card.

+ ... +

{cashout_method.name}

+ {/*

{data.terms}

*/} + + +

+ + ) +} + +const VariableCashoutMethodPreview: React.FC<{ cashout_method: CashoutMethodOut }> = ({cashout_method}) => { + return ( + <> + + {cashout_method.name} + + + + {formatCentsToUSD(cashout_method.min_value)} – {formatCentsToUSD(cashout_method.max_value)} + + + ) +} + +const FixedCashoutMethodPreview: React.FC<{ cashout_method: CashoutMethodOut }> = ({cashout_method}) => { + return ( + <> + + {cashout_method.name} + + + ) +} -import {Card, CardContent, CardHeader} from "@/components/ui/card.tsx"; -import {CashoutMethodOut, CashoutMethodsResponse, WalletApi} from "@/api" const CashoutMethodPreview: React.FC<{ cashout_method: CashoutMethodOut }> = ({cashout_method}) => { + const [open, setOpen] = useState(false) + + const renderContent = () => { + switch (cashout_method.data.value_type) { + case 'fixed': + return + case 'variable': + return + } + }; + return ( - + - {cashout_method.name} + {renderContent()} - + Cashout method + + setOpen(true)} + >Details + + + + + + {cashout_method.name} Details + +
+ + + + + ) } -const CashoutMethodsPage: React.FC = ({settings}) => { - const [cashoutMethods, setCashoutMethods] = useState([]); - useEffect(() => { - const x = new WalletApi(); - x.getCashoutMethodsProductIdCashoutMethodsGet(settings.bpid, settings.bpuid) - .then(res => { - const data: CashoutMethodsResponse = res.data; - setCashoutMethods(data.cashout_methods); - }) - .catch(err => console.log(err)); - }, []); // ← empty array means "run once" +const CashoutMethodsPage = () => { + const variableCashoutMethods = useSelector(selectVariableCashoutMethods) + const fixedCashoutMethods = useSelector(selectFixedCashoutMethods) + const wallet: UserWalletBalance = useAppSelector(state => state.wallet) + return ( -
- { - cashoutMethods.map((m, index) => { - return ; - }) - } -
- ); + <> +

Your balance is {formatCentsToUSD(wallet.amount)}.

+

You can redeem {formatCentsToUSD(wallet.redeemable_amount)} now.

+

(a portion of each survey is delayed by 30 days)

+ + + + Variable + Fixed + + + +
+ { + variableCashoutMethods.map((m, index) => { + return ; + }) + } +
+
+ +
+ { + fixedCashoutMethods.map((m, index) => { + return ; + }) + } +
+
+
+ + ) } + export {CashoutMethodsPage} \ No newline at end of file diff --git a/src/pages/Offerwall.tsx b/src/pages/Offerwall.tsx index 0d0534e..19c4515 100644 --- a/src/pages/Offerwall.tsx +++ b/src/pages/Offerwall.tsx @@ -1,5 +1,5 @@ import React, {useState} from 'react' -import { motion } from "framer-motion"; +import {motion} from "framer-motion"; import {Badge} from "@/components/ui/badge" import {Link} from '@mui/material'; import {Tabs, TabsContent} from "@/components/ui/tabs" @@ -18,14 +18,13 @@ import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from "@/ import {useSelector} from "react-redux"; import {Switch} from "@/components/ui/switch" import {Card, CardContent, CardFooter} from "@/components/ui/card.tsx"; -import {makeSelectQuestionsByIds, ProfileQuestion} from "@/models/questionSlice.ts" +import {makeSelectQuestionsByIds} from "@/models/questionSlice.ts" import {CheckIcon, MessageCircleQuestionIcon, XIcon} from "lucide-react" import {useAppDispatch, useAppSelector} from '@/hooks' import {Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger,} from "@/components/ui/sheet" import {ProfileQuestionFull} from "@/pages/Questions.tsx" import {Answer, selectAnswerForQuestion, submitAnswer} from "@/models/answerSlice.ts"; import {assert, formatCentsToUSD, formatSeconds} from "@/lib/utils.ts"; -import {IQRBoxPlot} from "@/lib/snippets.tsx" import {setAvailabilityCount, setOfferwallId} from "@/models/appSlice.ts"; import {setBuckets} from "@/models/bucketSlice.ts"; @@ -54,12 +53,12 @@ const ContentsGrid: React.FC = ({bucket}) => { { accessorKey: "loi", header: "Length", - cell: ({ getValue }) => formatSeconds(getValue() as number), + cell: ({getValue}) => formatSeconds(getValue() as number), }, { accessorKey: "payout", header: "Payout", - cell: ({ getValue}) => formatCentsToUSD(getValue() as number) + cell: ({getValue}) => formatCentsToUSD(getValue() as number) }, ] @@ -73,7 +72,7 @@ const ContentsGrid: React.FC = ({bucket}) => { return (
- +
{table.getHeaderGroups().map((headerGroup) => ( @@ -123,6 +122,7 @@ const ConditionalQuestions: React.FC = ({bucket}) => { const app = useAppSelector(state => state.app) console.log("Conditional bucket:", questions, question, answer) + const [open, setOpen] = useState(false) const submitEvt = () => { dispatch(submitAnswer({question: question})) @@ -153,32 +153,41 @@ const ConditionalQuestions: React.FC = ({bucket}) => { } return ( - - Open - - - - Bucket Questions - - This survey has some unanswered questions. Answer these to determine if you're - eligible for the Survey Bucket - - - - { - questions.map(q => { - return - }) - } + <> + + + + + + + Bucket Questions + + This survey has some unanswered questions. Answer these to determine if you're + eligible for the Survey Bucket + + - - + { + questions.map(q => { + return + }) + } + + + + ) } @@ -201,22 +210,24 @@ const CallToAction: React.FC = ({bucket}) => { ) case "conditional": - // return + return ( +
+ +
+ ) + + case "ineligible": return (
) - - case "ineligible": - return ; } } -- cgit v1.2.3