feat: reward cards, menu#257
Conversation
WalkthroughAdd a rewards feature and navigation/menu updates: new RewardCard, /point and /task pages, a /navigation page with external links and feedback, route renames from /points → /point, Reward type and Russian i18n keys, and minor ProspectiveBlock NuxtLink change. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant PB as ProspectiveBlock
participant Nuxt as Router/NuxtLink
participant Point as /point page
participant RC as RewardCard
U->>PB: click card
PB->>Nuxt: navigate to /point
Nuxt->>Point: render /point
Point->>RC: render RewardCard(s)
Note right of RC#color(##f0f4ff): displays name, optional description,\nand points button
sequenceDiagram
participant U as User
participant Nav as navigation.vue
participant Ext as External Link
participant FB as useFeedback
U->>Nav: click external item
Nav->>FB: vibrate()
Nav->>Ext: open link (target="_blank")
Note right of Nav#color(##fff7f0): external resources list with icons
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
💤 Files with no reviewable changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
apps/hub-telegram/app/pages/task/index.vue (1)
1-11: Use i18n for hardcoded text.The component uses hardcoded Russian strings instead of the i18n system. For consistency with the rest of the codebase, consider using translation keys.
Apply this diff to use i18n:
<template> <PageContainer> - <SectionTitle title="Задания" /> + <SectionTitle :title="$t('app.tasks')" /> <div class="flex flex-col gap-3.5"> <p class="text-muted"> - Активных нет + {{ $t('app.tasks-empty') }} </p> </div> </PageContainer> </template>Also add the missing key to
apps/hub-telegram/i18n/locales/ru-RU.json:"app": { "flow": "Поток", "navigation": "Меню", "rewards": "Награды", - "tasks": "Задания" + "tasks": "Задания", + "tasks-empty": "Активных нет" },apps/hub-telegram/app/pages/navigation.vue (1)
29-51: Consider using i18n for hardcoded labels.The navigation items use hardcoded Russian text. For consistency with the rest of the codebase and to support potential future internationalization, consider using the i18n system.
Example refactor:
const items = ref([ { - label: 'Помощь в WhatsApp', + label: t('app.navigation-whatsapp'), to: 'https://wa.me/message/DRMTOEKLZU2FJ1', target: '_blank', icon: 'i-lucide-heart-handshake', onClick: () => vibrate(), }, { - label: 'Наш Telegram канал', + label: t('app.navigation-telegram'), to: 'https://t.me/franshizasushi', target: '_blank', icon: 'simple-icons:telegram', onClick: () => vibrate(), }, { - label: 'Наша VK группа', + label: t('app.navigation-vk'), to: 'https://vk.com/franshizasushi', target: '_blank', icon: 'simple-icons:vk', onClick: () => vibrate(), }, ])And add corresponding keys to
ru-RU.json.apps/hub-telegram/app/components/RewardCard.vue (1)
18-24: Consider removing unnecessary toString() conversion.The
UButtonlabel prop can accept a number directly, making the explicit conversion unnecessary.Apply this diff:
<UButton variant="solid" size="xl" class="text-xl/5 font-bold justify-center min-w-24" trailing-icon="i-lucide-coins" - :label="reward.points.toString()" + :label="String(reward.points)" />apps/hub-telegram/app/pages/point/index.vue (1)
11-23: Use i18n for hardcoded text.The component contains several hardcoded Russian strings that should use the i18n system for consistency with the rest of the codebase.
Apply this diff to use i18n:
- <SectionTitle :title="`У вас ${userStore.prospectivePoints} ${pluralizationRu(userStore.prospectivePoints, ['Балл', 'Балла', 'Баллов'])}`" /> + <SectionTitle :title="$t('app.rewards-balance', { points: userStore.prospectivePoints, unit: pluralizationRu(userStore.prospectivePoints, ['Балл', 'Балла', 'Баллов']) })" /> <p class="text-base/5"> - Выбирайте награду! Список регулярно обновляется. + {{ $t('app.rewards-description') }} </p> <UButton to="/task" variant="solid" size="xl" class="font-bold w-full justify-center" - label="Хочу еще" + :label="$t('app.rewards-more-button')" />And add the corresponding keys to
ru-RU.json:"app": { "flow": "Поток", "navigation": "Меню", "rewards": "Награды", - "tasks": "Задания" + "tasks": "Задания", + "rewards-balance": "У вас {points} {unit}", + "rewards-description": "Выбирайте награду! Список регулярно обновляется.", + "rewards-more-button": "Хочу еще" },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
apps/hub-telegram/app/components/ProspectiveBlock.vue(1 hunks)apps/hub-telegram/app/components/RewardCard.vue(1 hunks)apps/hub-telegram/app/composables/useNavigation.ts(1 hunks)apps/hub-telegram/app/pages/navigation.vue(1 hunks)apps/hub-telegram/app/pages/point/index.vue(1 hunks)apps/hub-telegram/app/pages/points/index.vue(0 hunks)apps/hub-telegram/app/pages/task/index.vue(1 hunks)apps/hub-telegram/i18n/locales/ru-RU.json(1 hunks)apps/hub-telegram/shared/types/index.ts(1 hunks)
💤 Files with no reviewable changes (1)
- apps/hub-telegram/app/pages/points/index.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (5)
apps/hub-telegram/app/components/ProspectiveBlock.vue (1)
3-7: LGTM! Route update and improved link structure.The route change from
/pointsto/pointaligns with the navigation refactoring, and wrapping theActiveCardinsideNuxtLinkproperly makes the entire card clickable.apps/hub-telegram/shared/types/index.ts (1)
21-26: LGTM! Clean type definition.The
Rewardtype is well-defined with appropriate fields for the rewards feature.apps/hub-telegram/i18n/locales/ru-RU.json (1)
23-28: LGTM! Localization keys added correctly.The new i18n keys for navigation, rewards, and tasks are properly structured and support the new features.
apps/hub-telegram/app/pages/point/index.vue (1)
41-60: Hardcoded mock data is acceptable for initial implementation.The hardcoded rewards array is fine for the initial feature implementation. When ready to integrate with backend data, this can be replaced with API calls.
apps/hub-telegram/app/composables/useNavigation.ts (1)
16-32: LGTM! Navigation routes updated correctly.The navigation routes have been properly updated to reflect the new page structure with correct i18n usage throughout. The changes align well with the new
/point,/task, and/navigationpages.
| <div | ||
| v-if="reward.description" | ||
| class="w-full text-base/5 font-normal whitespace-pre-wrap wrap-break-word line-clamp-8" | ||
| > | ||
| {{ reward.description }} | ||
| </div> |
There was a problem hiding this comment.
Invalid Tailwind CSS class name.
Line 12 uses wrap-break-word which is not a valid Tailwind utility class. This should be break-words.
Apply this diff:
<div
v-if="reward.description"
- class="w-full text-base/5 font-normal whitespace-pre-wrap wrap-break-word line-clamp-8"
+ class="w-full text-base/5 font-normal whitespace-pre-wrap break-words line-clamp-8"
>
{{ reward.description }}
</div>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| v-if="reward.description" | |
| class="w-full text-base/5 font-normal whitespace-pre-wrap wrap-break-word line-clamp-8" | |
| > | |
| {{ reward.description }} | |
| </div> | |
| <div | |
| v-if="reward.description" | |
| class="w-full text-base/5 font-normal whitespace-pre-wrap break-words line-clamp-8" | |
| > | |
| {{ reward.description }} | |
| </div> |
🤖 Prompt for AI Agents
In apps/hub-telegram/app/components/RewardCard.vue around lines 10 to 15, the
Tailwind class "wrap-break-word" on the description div is invalid; replace
"wrap-break-word" with the correct Tailwind utility "break-words" so the class
list becomes valid and word-wrapping behaves as intended.
|



Summary by CodeRabbit
New Features
Improvements
Chores