diff options
| author | Max Nanis | 2025-06-23 17:20:31 +0700 |
|---|---|---|
| committer | Max Nanis | 2025-06-23 17:20:31 +0700 |
| commit | 8138549f64403874eb7c7ddfbde1cc2cc2c03695 (patch) | |
| tree | ff16ff5bf7b0a5454fd181d178a6f799b9141d64 /src/pages | |
| parent | 5e8b1b89bfffd0202bc6c5f64aac943053d79d32 (diff) | |
| download | panel-ui-8138549f64403874eb7c7ddfbde1cc2cc2c03695.tar.gz panel-ui-8138549f64403874eb7c7ddfbde1cc2cc2c03695.zip | |
Typescript validation finally passes.
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/CashoutMethods.tsx | 1 | ||||
| -rw-r--r-- | src/pages/Community.tsx | 9 | ||||
| -rw-r--r-- | src/pages/Demographics.tsx | 4 | ||||
| -rw-r--r-- | src/pages/Offerwall.tsx | 50 | ||||
| -rw-r--r-- | src/pages/Questions.tsx | 36 | ||||
| -rw-r--r-- | src/pages/Support.tsx | 38 | ||||
| -rw-r--r-- | src/pages/TaskAttemptHistory.tsx | 2 | ||||
| -rw-r--r-- | src/pages/TransactionHistory.tsx | 6 |
8 files changed, 60 insertions, 86 deletions
diff --git a/src/pages/CashoutMethods.tsx b/src/pages/CashoutMethods.tsx index 9cb0f20..806c455 100644 --- a/src/pages/CashoutMethods.tsx +++ b/src/pages/CashoutMethods.tsx @@ -116,6 +116,7 @@ const CashoutMethodPreview: React.FC<{ cashout_method: CashoutMethodOut }> = ({c const [open, setOpen] = useState(false) const renderContent = () => { + // @ts-ignore switch (cashout_method.data.value_type) { case 'fixed': return <FixedCashoutMethodPreview cashout_method={cashout_method}/> diff --git a/src/pages/Community.tsx b/src/pages/Community.tsx index 9b49608..9313eb2 100644 --- a/src/pages/Community.tsx +++ b/src/pages/Community.tsx @@ -1,8 +1,7 @@ import React, {useEffect, useState} from 'react' -import {Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle} from "@/components/ui/card.tsx"; -import {CashoutMethodsResponse, WalletApi} from "@/api" -import {CashoutMethodOut} from "@/api"; +import {Card, CardContent, CardHeader} from "@/components/ui/card.tsx"; +import {CashoutMethodOut, CashoutMethodsResponse, WalletApi} from "@/api" import {useAppSelector} from "@/hooks.ts"; const CashoutMethodPreview: React.FC<{ cashout_method: CashoutMethodOut }> = ({cashout_method}) => { @@ -16,7 +15,7 @@ const CashoutMethodPreview: React.FC<{ cashout_method: CashoutMethodOut }> = ({c </CardHeader> <CardContent> - <img className="blur-xs grayscale" src={cashout_method.imageUrl}/> + <img className="blur-xs grayscale" src={cashout_method.image_url}/> </CardContent> </Card> ) @@ -41,7 +40,7 @@ const CommunityPage = () => { <div className="grid grid-cols-3 gap-1 p-1"> { cashoutMethods.map((m, index) => { - return <CashoutMethodPreview key={index} cashout_method={m} />; + return <CashoutMethodPreview key={index} cashout_method={m}/>; }) } </div> diff --git a/src/pages/Demographics.tsx b/src/pages/Demographics.tsx index f1de290..2031511 100644 --- a/src/pages/Demographics.tsx +++ b/src/pages/Demographics.tsx @@ -6,14 +6,14 @@ import { formatDistanceToNow } from 'date-fns' import {Card, CardContent, CardHeader} from "@/components/ui/card"; import {Calendar, MapPin, User, PersonStanding} from "lucide-react"; -import {BucketTask, UserProfile} from "@/api"; +import {UserProfileKnowledge, UserProfile} from "@/api"; import {ColumnDef, flexRender, getCoreRowModel, useReactTable} from "@tanstack/react-table"; import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table.tsx"; import {useAppSelector} from "@/hooks.ts"; export const UpkGrid = () => { - const columns: ColumnDef<BucketTask>[] = [ + const columns: ColumnDef<UserProfileKnowledge>[] = [ { accessorKey: "property_label", header: "Label", diff --git a/src/pages/Offerwall.tsx b/src/pages/Offerwall.tsx index 19c4515..1af7500 100644 --- a/src/pages/Offerwall.tsx +++ b/src/pages/Offerwall.tsx @@ -21,7 +21,7 @@ import {Card, CardContent, CardFooter} from "@/components/ui/card.tsx"; 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 {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"; @@ -47,7 +47,8 @@ const BucketStatus: React.FC<SoftPairBucket> = ({bucket}) => { } } -const ContentsGrid: React.FC<SoftPairBucket> = ({bucket}) => { +type ContentsGridProps = { bucket: SoftPairBucket }; +const ContentsGrid: React.FC<ContentsGridProps> = ({bucket}) => { const columns: ColumnDef<BucketTask>[] = [ { @@ -113,7 +114,9 @@ const ContentsGrid: React.FC<SoftPairBucket> = ({bucket}) => { ) } -const ConditionalQuestions: React.FC<SoftPairBucket> = ({bucket}) => { + +type ConditionalQuestionsProps = { bucket: SoftPairBucket }; +const ConditionalQuestions: React.FC<ConditionalQuestionsProps> = ({bucket}) => { const dispatch = useAppDispatch() const questions = useSelector(makeSelectQuestionsByIds(bucket.missing_questions)) @@ -162,28 +165,35 @@ const ConditionalQuestions: React.FC<SoftPairBucket> = ({bucket}) => { Check Eligibility </Button> - <Sheet open={open} onOpenChange={setOpen}> + <Sheet + open={open} + onOpenChange={setOpen} + > <SheetContent side="right" - className="md:w-[900px], lg:w-[1000px] p-5"> - + className="p-5" + > <SheetHeader> - <SheetTitle>Bucket Questions</SheetTitle> + <SheetTitle> + Bucket Questions + </SheetTitle> <SheetDescription> This survey has some unanswered questions. Answer these to determine if you're eligible for the Survey Bucket </SheetDescription> </SheetHeader> - { - questions.map(q => { - return <ProfileQuestionFull - key={q.question_id} - question={q} - submitAnswerEvt={submitEvt} - className="mt-4 m-2"/> - }) - } + <div className="h-full overflow-y-auto pr-5"> + { + questions.map(q => { + return <ProfileQuestionFull + key={q.question_id} + question={q} + submitAnswerEvt={submitEvt} + /> + }) + } + </div> </SheetContent> </Sheet> @@ -191,13 +201,14 @@ const ConditionalQuestions: React.FC<SoftPairBucket> = ({bucket}) => { ) } -const CallToAction: React.FC<SoftPairBucket> = ({bucket}) => { +type CallToActionProps = { bucket: SoftPairBucket }; +const CallToAction: React.FC<CallToActionProps> = ({bucket}) => { switch (bucket.eligibility) { case "unconditional": return ( <div className="absolute bottom-2 left-1/2 transform -translate-x-1/2 w-[90%]"> <Link - href={bucket.uri} + href={bucket.uri.toString()} target="_blank" className="w-full h-8 cursor-pointer" > @@ -231,7 +242,8 @@ const CallToAction: React.FC<SoftPairBucket> = ({bucket}) => { } } -const ConditionalBucket: React.FC<SoftPairBucket> = ({bucket}) => { +type ConditionalBucketProps = { bucket: SoftPairBucket }; +const ConditionalBucket: React.FC<ConditionalBucketProps> = ({bucket}) => { const [tab, setTab] = useState("bucket_cta") const toggleTab = () => setTab(tab === "bucket_cta" ? "bucket_details" : "bucket_cta") diff --git a/src/pages/Questions.tsx b/src/pages/Questions.tsx index 06374b2..92b9505 100644 --- a/src/pages/Questions.tsx +++ b/src/pages/Questions.tsx @@ -1,10 +1,10 @@ -import React from 'react' import { BodySubmitProfilingQuestionsProductIdProfilingQuestionsPost, ProfilingQuestionsApiFactory, UpkQuestionChoice, - UserQuestionAnswerIn + UserQuestionAnswerIn, } from "@/api"; +import React from "react" import {Card, CardContent, CardFooter, CardHeader, CardTitle} from "@/components/ui/card.tsx"; import {useAppDispatch, useAppSelector} from "@/hooks.ts"; import {addAnswer, Answer, saveAnswer, selectAnswerForQuestion, submitAnswer} from "@/models/answerSlice.ts"; @@ -30,6 +30,7 @@ import { } from "@/models/questionSlice.ts"; import {assert} from "@/lib/utils.ts"; import {motion} from "framer-motion" +import {App} from "../models/app"; const TextEntry: React.FC<{ question: ProfileQuestion }> = ({question}) => { const dispatch = useAppDispatch() @@ -38,8 +39,9 @@ const TextEntry: React.FC<{ question: ProfileQuestion }> = ({question}) => { const answer: Answer | undefined = useSelector(selectAnswerForQuestion(question)); const error: Boolean = answer?.error_msg.length > 0 - const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => { - dispatch(addAnswer({question: question, val: event.target.value})) + const handleInputChange = (event: React.KeyboardEvent<HTMLInputElement>) => { + const target = event.target as HTMLInputElement; + dispatch(addAnswer({question, val: target.value as string})) }; return ( @@ -119,7 +121,7 @@ export const ProfileQuestionFull: React.FC<{ // const selectAnswer = useMemo(() => selectAnswerForQuestion(question), [question]); // const answer: Answer = useSelector(selectAnswer); const answer: Answer | undefined = useSelector(selectAnswerForQuestion(question)); - const app = useAppSelector(state => state.app) + const app: App = useAppSelector(state => state.app) const provided_answer = answer?.values.length > 0 const error: Boolean = answer?.error_msg.length > 0 @@ -136,7 +138,7 @@ export const ProfileQuestionFull: React.FC<{ return ( - <Card className="@container/card relative overflow-hidden"> + <Card className="@container/card relative overflow-hidden my-4 p-5"> {answer && answer.processing && ( <motion.div className="absolute top-0 left-0 h-0.5 bg-gray-300" @@ -150,9 +152,9 @@ export const ProfileQuestionFull: React.FC<{ <Badge className="absolute top-2 right-2 h-5 min-w-5 rounded-full px-1 font-mono tabular-nums cursor-pointer" variant="outline" - title={`Currently ${(question.task_count ?? 0).toLocaleString()} surveys use this profiling question`} + title={`Currently ${(question.importance.task_count ?? 0).toLocaleString()} surveys use this profiling question`} > - {(question.task_count ?? 0).toLocaleString()} + {(question.importance?.task_count ?? 0).toLocaleString()} </Badge> <CardHeader> @@ -183,7 +185,7 @@ const PaginationIcon: React.FC<{ const answers = useAppSelector(state => state.answers) const completed: Boolean = Boolean(answers[question.question_id]?.complete) - const setQuestion = (evt) => { + const setQuestion = (evt: React.MouseEvent<HTMLAnchorElement>) => { if (completed) { evt.preventDefault() } else { @@ -197,7 +199,7 @@ const PaginationIcon: React.FC<{ href="#" title={question.question_text} isActive={question.active} - aria-disabled={completed} + aria-disabled={!!completed} onClick={setQuestion} className={clsx("cursor-pointer border border-gray-100", @@ -217,22 +219,24 @@ const QuestionsPage = () => { const dispatch = useAppDispatch() const questions = useSelector(selectQuestions) - const question = useSelector(selectFirstAvailableQuestion) + // @ts-ignore + const question: ProfileQuestion | null = useSelector(selectFirstAvailableQuestion) dispatch(setQuestionActive(question as ProfileQuestion)) // This is saved now, so that if they click next it's ready. It // cannot be done within the click handler. - const nextQuestion = useSelector(selectNextAvailableQuestion) + // @ts-ignore + const nextQuestion: ProfileQuestion | null = useSelector(selectNextAvailableQuestion) const answer: Answer | undefined = useSelector(selectAnswerForQuestion(question)); - const app = useAppSelector(state => state.app) + const app: App = useAppSelector(state => state.app) const clickNext = () => { // TODO: if nextQuestion was already submitted, skip it! if (nextQuestion) { // TS is not smart enough to know that the if statement above // prevents this from ever being null - dispatch(setQuestionActive(nextQuestion as ProfileQuestion)) + dispatch(setQuestionActive(nextQuestion)) } else { // What do we do now... no more questions left to do. } @@ -278,7 +282,7 @@ const QuestionsPage = () => { } as UserQuestionAnswerIn ] } - new ProfilingQuestionsApiFactory().submitProfilingQuestionsProductIdProfilingQuestionsPost(app.bpid, app.bpuid, body) + ProfilingQuestionsApiFactory().submitProfilingQuestionsProductIdProfilingQuestionsPost(app.bpid, app.bpuid, body) .then(res => { if (res.status == 200) { dispatch(saveAnswer({question: question})) @@ -318,7 +322,7 @@ const QuestionsPage = () => { key={question.question_id} question={question} submitAnswerEvt={submitAnswerEvt} - className="mt-4 mb-4"/> + /> </> ) } diff --git a/src/pages/Support.tsx b/src/pages/Support.tsx deleted file mode 100644 index 4746b77..0000000 --- a/src/pages/Support.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { useEffect } from 'react'; - -const ChatwootLoader = () => { - useEffect(() => { - const loadChatwoot = () => { - const BASE_URL = "https://chat.g-r-l.com"; - const script = document.createElement('script'); - script.src = `${BASE_URL}/packs/js/sdk.js`; - script.defer = true; - script.async = true; - - script.onload = () => { - if (window.chatwootSDK) { - window.chatwootSDK.run({ - websiteToken: 'dEEw3fcexQvnQ5tesJPKFjSb', - baseUrl: BASE_URL, - }); - } - }; - - document.body.appendChild(script); - }; - - loadChatwoot(); - - // Clean up script when the component unmounts - return () => { - const existingScript = document.querySelector(`script[src="https://app.chatwoot.com/packs/js/sdk.js"]`); - if (existingScript) { - document.body.removeChild(existingScript); - } - }; - }, []); - - return null; -}; - -export {ChatwootLoader};
\ No newline at end of file diff --git a/src/pages/TaskAttemptHistory.tsx b/src/pages/TaskAttemptHistory.tsx index 311c32e..0014893 100644 --- a/src/pages/TaskAttemptHistory.tsx +++ b/src/pages/TaskAttemptHistory.tsx @@ -14,7 +14,7 @@ export const TaskAttemptTable = () => { { accessorKey: "started", header: "Started", - cell: ({getValue}) => formatDistanceToNow(new Date(getValue()), {addSuffix: true}) + cell: ({getValue}) => formatDistanceToNow(new Date(getValue() as string), {addSuffix: true}) }, { accessorKey: "finished", diff --git a/src/pages/TransactionHistory.tsx b/src/pages/TransactionHistory.tsx index a99dd8b..6f30b14 100644 --- a/src/pages/TransactionHistory.tsx +++ b/src/pages/TransactionHistory.tsx @@ -1,7 +1,4 @@ import {useAppDispatch, useAppSelector} from "@/hooks.ts"; -import {Pagination, PaginationContent, PaginationItem, PaginationNext} from "@/components/ui/pagination.tsx"; -import React from "react"; -import {ProfileQuestionFull} from "@/pages/Questions.tsx"; const TransactionHistoryPage = () => { const dispatch = useAppDispatch() @@ -11,8 +8,7 @@ const TransactionHistoryPage = () => { return ( <> { - transactionHistory.map(th => { - + transactionHistory.map(() => { }) } </> |
