Skip to content

Conversation

@YanVictorSN
Copy link
Contributor

@YanVictorSN YanVictorSN commented Feb 11, 2026

Description

A component that show claimers a set of tasks they can complete.

About #228

  • There is always a main task highlighted
  • Alternative tasks should show, but in a less prominent way
  • Should fit existing styling/design.
  • UX/UI should be intuitive.
  • should be able to dismiss tasks (not show) for the next 4 days.
  • tasks can have rewards associated (only UI, no payments are triggered)
  • tasks will have durations for how long they will show

Summary by Sourcery

Add a new user tasks experience for claimers, including a main highlighted task, secondary tasks, and modal/card presentations driven by sample data and local state.

New Features:

  • Introduce a ClaimerTasksCard/ClaimerTasksCompact UI that surfaces a primary task and secondary tasks with rewards and actions for users to complete.
  • Persist task dismissal and completion status in local storage so tasks can be snoozed for several days and completed tasks are hidden from future views.
  • Provide a task details modal with rewards-focused call-to-action buttons and optional inline card rendering instead of a modal.
  • Add sample task definitions and a Storybook story to showcase the new claimer tasks UI as a modal.

Enhancements:

  • Integrate basic UX flows for dismissing all visible tasks at once and automatically opening the tasks modal when relevant tasks are available.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The ClaimerTasksCard component accepts a tasks prop but useClaimerTasks is hard‑wired to SAMPLE_TASKS, so the storybook data and any caller-provided tasks are ignored; consider wiring the hook to accept a task list or using the tasks prop directly.
  • Several props and values appear unused or redundant (e.g. type on ManagerTask, dismissTask from useClaimerTasks), which makes the API harder to understand; consider removing or implementing these to better reflect the intended behavior.
  • Some user-facing copy strings have awkward punctuation such as "More ways to use G$:!." and "All caught up!."; cleaning these up will improve the UX and avoid confusing translations.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `ClaimerTasksCard` component accepts a `tasks` prop but `useClaimerTasks` is hard‑wired to `SAMPLE_TASKS`, so the storybook data and any caller-provided tasks are ignored; consider wiring the hook to accept a task list or using the `tasks` prop directly.
- Several props and values appear unused or redundant (e.g. `type` on `ManagerTask`, `dismissTask` from `useClaimerTasks`), which makes the API harder to understand; consider removing or implementing these to better reflect the intended behavior.
- Some user-facing copy strings have awkward punctuation such as `"More ways to use G$:!."` and `"All caught up!."`; cleaning these up will improve the UX and avoid confusing translations.

## Individual Comments

### Comment 1
<location> `packages/good-design/src/apps/usertasks/managerTaskCard.tsx:301-310` </location>
<code_context>
+  <TransText t={content} variant="sm-grey-650" paddingLeft={2} paddingRight={2} textAlign="center" />
+);
+
+const ManagerContentDismiss = () => (
+  <VStack space={2} paddingX={2}>
+    <TransText t="🎉" fontSize="4xl" textAlign="center" />
+    <TransText
+      t={/*i18n*/ "All caught up!."}
+      variant="sm-grey-650"
+      fontWeight="bold"
+      textAlign="center"
+    />
+    <TransText
+      t={/*i18n*/ "Check back later for new tasks and rewards."}
+      variant="sm-grey-650"
+      fontWeight="bold"
</code_context>

<issue_to_address>
**suggestion (typo):** Several user-facing strings have awkward punctuation (e.g. `"All caught up!."`).

In `ManagerContentDismiss` and related components, strings like `"All caught up!."` and `"More ways to use G$:!."` have incorrect punctuation (extra period, stray colon before `!`). Since these are user-facing and likely to go into translation catalogs, please clean them up (e.g. `"All caught up!"`, `"More ways to use G$!"`).

Suggested implementation:

```typescript
      t={/*i18n*/ "All caught up!"}

```

```typescript
      t={/*i18n*/ "More ways to use G$!"}

```

If there are any other similar strings in this file or related components (extra punctuation like `!.` or `:!.`), they should be normalized in the same way before translation: keep only the intended punctuation (e.g. `"..."!` or `"..."."` but not both).
</issue_to_address>

### Comment 2
<location> `packages/good-design/src/apps/usertasks/managerTaskCard.tsx:198` </location>
<code_context>
+          alignItems="center"
+          justifyContent="center"
+        >
+          <TransText 
+            t={task.icon || "🎯"} 
+            fontSize="3xl"
</code_context>

<issue_to_address>
**issue (complexity):** Consider extracting the repeated icon and reward rendering logic into small reusable helpers/components to reduce duplication and simplify the JSX structure.

You can trim a noticeable amount of accidental complexity by extracting the repeated reward/icon display logic into tiny helpers and reusing them across `TaskModalContent` and `TasksCardContent`.

Right now you have repeated patterns like:

```tsx
<TransText
  t={task.icon || "🎯"}
  fontSize="lg"
/>

<TransText
  t={task.rewardAmount || task.reward?.description || "+0 G$"}
  fontSize="md"
  fontWeight="bold"
  color={task.rewardColor || (task.rewardAmount?.includes('-') ? "red.500" : "green.500")}
/>
```

appearing in multiple components with slight variations. This both adds noise and makes changes to reward/icon behavior harder.

You can centralize this logic as small, focused components:

```tsx
// helpers (same file or a small ./TaskDisplay.tsx)
const getTaskRewardText = (task: ClaimerTask) =>
  task.rewardAmount || task.reward?.description || "+0 G$";

const getTaskRewardColor = (task: ClaimerTask) =>
  task.rewardColor || (task.rewardAmount?.includes("-") ? "red.500" : "green.500");

const TaskIcon: React.FC<{ task: ClaimerTask; size?: string | number }> = ({ task, size = "lg" }) => (
  <TransText t={task.icon || "🎯"} fontSize={size} />
);

const TaskRewardText: React.FC<{ task: ClaimerTask; fontSize?: string | number }> = ({
  task,
  fontSize = "md",
}) => (
  <TransText
    t={getTaskRewardText(task)}
    fontSize={fontSize}
    fontWeight="bold"
    color={getTaskRewardColor(task)}
  />
);
```

Then reuse them in the existing components:

```tsx
// TaskModalContent
<Box alignSelf="center">
  <Box
    w={16}
    h={16}
    borderRadius="full"
    bg="gray.100"
    alignItems="center"
    justifyContent="center"
  >
    <TaskIcon task={task} size="3xl" />
  </Box>
</Box>

{task.rewardAmount && (
  <HStack justifyContent="center" space={2} alignItems="center">
    <TransText t="Reward:" fontSize="sm" color="gray.500" />
    <TaskRewardText task={task} fontSize="lg" />
  </HStack>
)}
```

```tsx
// TasksCardContent secondary tasks list
<Box
  w={10}
  h={10}
  borderRadius="full"
  bg="gray.100"
  alignItems="center"
  justifyContent="center"
  flexShrink={0}
>
  <TaskIcon task={task} size="lg" />
</Box>

<VStack alignItems="flex-end" flexShrink={0}>
  <TaskRewardText task={task} fontSize="md" />
</VStack>
```

This keeps all behavior intact, but:

- Removes duplicated conditionals for reward text/color and icon fallback.
- Makes future changes to reward/icon behavior a single-point edit.
- Visually simplifies the JSX in `TaskModalContent` and `TasksCardContent`, lowering cognitive load without changing the public API.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +301 to +310
const ManagerContentDismiss = () => (
<VStack space={2} paddingX={2}>
<TransText t="🎉" fontSize="4xl" textAlign="center" />
<TransText
t={/*i18n*/ "All caught up!."}
variant="sm-grey-650"
fontWeight="bold"
textAlign="center"
/>
<TransText
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (typo): Several user-facing strings have awkward punctuation (e.g. "All caught up!.").

In ManagerContentDismiss and related components, strings like "All caught up!." and "More ways to use G$:!." have incorrect punctuation (extra period, stray colon before !). Since these are user-facing and likely to go into translation catalogs, please clean them up (e.g. "All caught up!", "More ways to use G$!").

Suggested implementation:

      t={/*i18n*/ "All caught up!"}
      t={/*i18n*/ "More ways to use G$!"}

If there are any other similar strings in this file or related components (extra punctuation like !. or :!.), they should be normalized in the same way before translation: keep only the intended punctuation (e.g. "..."! or "..."." but not both).

alignItems="center"
justifyContent="center"
>
<TransText
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider extracting the repeated icon and reward rendering logic into small reusable helpers/components to reduce duplication and simplify the JSX structure.

You can trim a noticeable amount of accidental complexity by extracting the repeated reward/icon display logic into tiny helpers and reusing them across TaskModalContent and TasksCardContent.

Right now you have repeated patterns like:

<TransText
  t={task.icon || "🎯"}
  fontSize="lg"
/>

<TransText
  t={task.rewardAmount || task.reward?.description || "+0 G$"}
  fontSize="md"
  fontWeight="bold"
  color={task.rewardColor || (task.rewardAmount?.includes('-') ? "red.500" : "green.500")}
/>

appearing in multiple components with slight variations. This both adds noise and makes changes to reward/icon behavior harder.

You can centralize this logic as small, focused components:

// helpers (same file or a small ./TaskDisplay.tsx)
const getTaskRewardText = (task: ClaimerTask) =>
  task.rewardAmount || task.reward?.description || "+0 G$";

const getTaskRewardColor = (task: ClaimerTask) =>
  task.rewardColor || (task.rewardAmount?.includes("-") ? "red.500" : "green.500");

const TaskIcon: React.FC<{ task: ClaimerTask; size?: string | number }> = ({ task, size = "lg" }) => (
  <TransText t={task.icon || "🎯"} fontSize={size} />
);

const TaskRewardText: React.FC<{ task: ClaimerTask; fontSize?: string | number }> = ({
  task,
  fontSize = "md",
}) => (
  <TransText
    t={getTaskRewardText(task)}
    fontSize={fontSize}
    fontWeight="bold"
    color={getTaskRewardColor(task)}
  />
);

Then reuse them in the existing components:

// TaskModalContent
<Box alignSelf="center">
  <Box
    w={16}
    h={16}
    borderRadius="full"
    bg="gray.100"
    alignItems="center"
    justifyContent="center"
  >
    <TaskIcon task={task} size="3xl" />
  </Box>
</Box>

{task.rewardAmount && (
  <HStack justifyContent="center" space={2} alignItems="center">
    <TransText t="Reward:" fontSize="sm" color="gray.500" />
    <TaskRewardText task={task} fontSize="lg" />
  </HStack>
)}
// TasksCardContent secondary tasks list
<Box
  w={10}
  h={10}
  borderRadius="full"
  bg="gray.100"
  alignItems="center"
  justifyContent="center"
  flexShrink={0}
>
  <TaskIcon task={task} size="lg" />
</Box>

<VStack alignItems="flex-end" flexShrink={0}>
  <TaskRewardText task={task} fontSize="md" />
</VStack>

This keeps all behavior intact, but:

  • Removes duplicated conditionals for reward text/color and icon fallback.
  • Makes future changes to reward/icon behavior a single-point edit.
  • Visually simplifies the JSX in TaskModalContent and TasksCardContent, lowering cognitive load without changing the public API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant