From a674d2e03de3bd048714d9c06e4bba9d9ecdb328 Mon Sep 17 00:00:00 2001 From: Max Nanis Date: Mon, 9 Jun 2025 04:44:45 +0700 Subject: Offerwall page - using datatables to show the bucket contents, setting up tabs to allow overview and detail insights of buckets, formatting of height and layout, playing with iqr, connection to conditionally eligible sidebar --- src/pages/Offerwall.tsx | 285 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 218 insertions(+), 67 deletions(-) (limited to 'src/pages/Offerwall.tsx') diff --git a/src/pages/Offerwall.tsx b/src/pages/Offerwall.tsx index 178e762..0d0534e 100644 --- a/src/pages/Offerwall.tsx +++ b/src/pages/Offerwall.tsx @@ -1,30 +1,46 @@ -import React from 'react' -import {Separator} from "@/components/ui/separator" +import React, {useState} from 'react' +import { motion } from "framer-motion"; +import {Badge} from "@/components/ui/badge" import {Link} from '@mui/material'; -import {useSelector} from "react-redux"; - -import {Card, CardContent, CardFooter, CardHeader, CardTitle} from "@/components/ui/card.tsx"; -import {ScrollArea} from "@/components/ui/scroll-area.tsx"; -import {makeSelectQuestionsByIds, setNextQuestion, setQuestions} from "@/models/questionSlice.ts" -import {CheckIcon, MessageCircleQuestionIcon, XIcon} from "lucide-react" +import {Tabs, TabsContent} from "@/components/ui/tabs" +import {Button} from "@/components/ui/button" import { BodyOfferwallSoftpairPostProductIdOfferwall37d1da64OfferwallIdPost, + BucketTask, OfferwallApi, SoftPairBucket, UserQuestionAnswerIn } from "@/api" + +import {ColumnDef, flexRender, getCoreRowModel, useReactTable,} from "@tanstack/react-table" + +import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from "@/components/ui/table" +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 {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, saveAnswer, selectAnswerForQuestion, submitAnswer} from "@/models/answerSlice.ts"; -import {assert} from "@/lib/utils.ts"; +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"; +interface DataTableProps { + columns: ColumnDef[] + data: TData[] +} + const BucketStatus: React.FC = ({bucket}) => { switch (bucket.eligibility) { - case "eligible": - return ; + case "unconditional": + return < + CheckIcon + xlinkTitle="you are good" + />; case "conditional": return ; case "ineligible": @@ -32,6 +48,72 @@ const BucketStatus: React.FC = ({bucket}) => { } } +const ContentsGrid: React.FC = ({bucket}) => { + + const columns: ColumnDef[] = [ + { + accessorKey: "loi", + header: "Length", + cell: ({ getValue }) => formatSeconds(getValue() as number), + }, + { + accessorKey: "payout", + header: "Payout", + cell: ({ getValue}) => formatCentsToUSD(getValue() as number) + }, + ] + + const data: BucketTask[] = bucket.contents + + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + }) + + return ( +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ) + })} + + ))} + + + + { + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + )) + } + +
+
+ ) +} + const ConditionalQuestions: React.FC = ({bucket}) => { const dispatch = useAppDispatch() @@ -102,14 +184,34 @@ const ConditionalQuestions: React.FC = ({bucket}) => { const CallToAction: React.FC = ({bucket}) => { switch (bucket.eligibility) { - case "eligible": - return - - ; + case "unconditional": + return ( +
+ + + +
+ ) case "conditional": - return + // return + return ( +
+ +
+ ) case "ineligible": return