chore: some new blocks#196
Conversation
WalkthroughUpdates CI to use Node LTS in GitHub Actions. Adds global smooth scrolling CSS and fixes a missing brace. Introduces new Vue components (About, Questions, Results). Modifies header to include a navigation menu with anchor links. Adjusts several components (Hero date/id, Countdown target date, Footer layout, SpeakerCard props/layout, Speakers data/layout). Updates the index page composition. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Header as Header (UNavigationMenu)
participant Browser as Browser (Scroll)
participant Sections as Page Sections (Hero/Speakers/Results/About/Questions)
participant Timer as CountdownTimer
User->>Header: Click in-page nav link (#hero/#for/#speakers/#faq)
Header-->>Browser: Anchor navigation
Browser->>Browser: Smooth scroll (CSS scroll-behavior)
Browser-->>Sections: Bring target section into view
note over Timer: Target: 2025‑10‑30 12:00:00
Timer->>User: Updates remaining time periodically
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests
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 (8)
apps/webinar/app/components/Header.vue (1)
12-29: Consider usingconstinstead ofreffor static navigation items.The
itemsarray contains static navigation links that don't change at runtime. Usingref()adds unnecessary reactivity overhead.Apply this diff:
-const items = ref([ +const items = [ { label: 'Бесплатный вебинар', to: '#hero', }, { label: 'Кому подойдет', to: '#for', }, { label: 'Спикеры', to: '#speakers', }, { label: 'Вопросы и ответы', to: '#faq', }, -]) +]apps/webinar/app/components/Speakers.vue (1)
23-42: Consider usingconstfor static speaker data.Similar to the Header component, the
speakersarray contains static data that doesn't need reactivity.Apply this diff:
-const speakers = ref([ +const speakers = [ { name: 'Лидия Трошина', caption: 'Директор по маркетингу франшизы «Суши Love»', description: 'Покажет стратегии по привлечению гостей работающие в 2025 году', image: 'https://avatar.nextorders.ru/377188?emotion=8&gender=female&clothing=teal', }, { name: 'Татьяна Панасевич', caption: 'Основатель сети суши-баров «Суши Love»', description: 'Ответит на все вопросы по работе с франшизой', image: 'https://avatar.nextorders.ru/797837?emotion=6&gender=female&clothing=violet', }, { name: 'Анна Михалко', caption: 'Наставник партнеров и эксперт по открытию новых точек франшизы', description: 'Даст пошаговый план открытия, который используют все наши партнеры', image: 'https://avatar.nextorders.ru/887463?emotion=7&gender=female&clothing=pink', }, -]) +]apps/webinar/app/components/Results.vue (2)
7-11: Enhance key uniqueness for better v-for stability.Using
item.titleas the key assumes titles are unique and won't change. Consider adding explicit IDs to each item for more robust keying.Alternatively, if titles are guaranteed unique and stable, the current approach is acceptable.
29-45: Consider renaminglastSectionItemsfor clarity.The variable name "lastSectionItems" is ambiguous. A more descriptive name like
resultItemsorbenefitItemswould better convey the content's purpose.Also consider using
constinstead of a function call for static data:-const lastSectionItems = [ +const resultItems = [ { title: 'Поймете', description: 'Из чего складывается прибыль и как ее считать', icon: 'i-lucide-chart-spline', }, { title: 'Узнаете', description: 'Как правильно подобрать помещение', icon: 'i-lucide-store', }, { title: 'Получите', description: 'Пошаговую инструкцию по открытию своего заведения', icon: 'i-lucide-book-marked', }, ]Don't forget to update the template reference as well.
apps/webinar/app/components/Questions.vue (1)
19-28: Consider usingconstfor static FAQ data.The
itemsarray contains static FAQ content that doesn't require reactivity.Apply this diff:
-const items = ref([ +const items = [ { label: 'А если у меня нет опыта в общепите?', content: 'Именно для новичков и проводится этот вебинар. После его просмотра у вас появится план действий и начальные знания в общепите.', }, { label: 'Я боюсь больших вложений. Есть ли варианты?', content: 'Доставку роллов и пиццы можно открыть с вложениями до 1 млн. рублей. На вебинаре подробнее рассмотрим финансовый калькулятор.', }, -]) +]apps/webinar/app/components/About.vue (3)
7-11: Enhance key uniqueness for better v-for stability.Using
item.titleas the key assumes titles are unique and won't change. Consider adding explicit IDs to each item for more robust keying.Alternatively, if titles are guaranteed unique and stable, the current approach is acceptable.
26-39: Consider renaminglastSectionItemsand usingconst.The variable name "lastSectionItems" is ambiguous and doesn't describe the content (company achievements/stats). Consider renaming to
achievementItemsorstatsItems.Also use
constinstead of a function call for static data:-const lastSectionItems = [ +const achievementItems = [ { title: '12 лет на рынке', icon: 'i-lucide-calendar-heart', }, { title: 'Более 100 успешных заведений по РФ и СНГ', icon: 'i-lucide-map-pinned', }, { title: 'Средняя окупаемость по сети — 3 месяца', icon: 'i-lucide-banknote-arrow-up', }, ]Don't forget to update the template reference.
1-23: Consider extracting shared component to reduce duplication.Both
About.vueandResults.vueshare nearly identical template structures for rendering icon-title-description cards in a grid. This pattern could be extracted into a reusable component.Consider creating a generic component like
IconCardGrid.vue:<template> <UPageSection :id="sectionId" :title="title" orientation="vertical" > <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 md:gap-10"> <div v-for="item in items" :key="item.title" class="px-6 py-6 w-full h-full flex flex-col gap-2.5 items-center text-center bg-muted rounded-lg motion-preset-slide-right" > <UIcon v-if="item.icon" :name="item.icon" class="size-12 text-secondary" /> <h4 class="text-2xl/7 font-bold"> {{ item.title }} </h4> <p v-if="item.description" class="text-base/5"> {{ item.description }} </p> </div> </div> </UPageSection> </template> <script lang="ts" setup> interface CardItem { title: string icon?: string description?: string } defineProps<{ sectionId?: string title: string items: CardItem[] }>() </script>This would eliminate duplication and make it easier to maintain consistent styling across sections.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
.github/workflows/ci.yml(1 hunks)apps/webinar/app/assets/css/styles.css(1 hunks)apps/webinar/app/components/About.vue(1 hunks)apps/webinar/app/components/CountdownTimer.vue(1 hunks)apps/webinar/app/components/Footer.vue(1 hunks)apps/webinar/app/components/Header.vue(1 hunks)apps/webinar/app/components/Hero.vue(1 hunks)apps/webinar/app/components/Questions.vue(1 hunks)apps/webinar/app/components/Results.vue(1 hunks)apps/webinar/app/components/SpeakerCard.vue(1 hunks)apps/webinar/app/components/Speakers.vue(3 hunks)apps/webinar/app/pages/index.vue(3 hunks)
⏰ 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 (15)
apps/webinar/app/components/CountdownTimer.vue (1)
11-11: LGTM! Date update aligns with Hero.The countdown target date has been updated to October 30, 2025, which matches the date displayed in Hero.vue.
apps/webinar/app/assets/css/styles.css (2)
3-3: Good catch—missing brace fixed.The closing brace for the h1–h6 font-family rule was missing and is now correctly added.
5-7: Smooth scrolling enabled for anchor navigation.The addition of
scroll-behavior: smoothaligns well with the new in-page navigation and anchor links introduced in the Header and other sections.apps/webinar/app/components/Hero.vue (3)
3-3: Anchor ID added for navigation.The
id="hero"attribute enables smooth scroll navigation to this section, consistent with the new navigation menu.
10-10: Spacing adjustment for large screens.The
lg:pt-24container padding improves layout on larger viewports.
18-18: Date updated to match countdown.The displayed date now shows October 30, 2025, consistent with the CountdownTimer target date.
apps/webinar/app/components/Footer.vue (1)
5-5: Grid layout adjusted for fewer items.The grid columns have been updated from 4 to 3, matching the reduction from three contact items to two (phone contact removed).
apps/webinar/app/pages/index.vue (3)
7-7: Section anchor added for navigation.The
id="for"attribute enables smooth scroll navigation to this section from the header menu.
104-104: Page title enhanced for SEO.The title now includes the webinar topic and date (October 2025), improving search engine visibility and user context.
32-34: Components existence and basic structure verified
Results.vue, About.vue, and Questions.vue are present in apps/webinar/app/components and include<template>tags.apps/webinar/app/components/Speakers.vue (2)
3-3: LGTM! Anchor ID aligns with navigation.The
id="speakers"attribute correctly matches the anchor link in the Header navigation menu.
12-12: Good responsive grid implementation.The progressive grid layout (1 column → 2 columns → 3 columns) provides appropriate speaker card display across device sizes.
apps/webinar/app/components/Questions.vue (1)
3-3: LGTM! Anchor ID aligns with navigation.The
id="faq"attribute correctly matches the anchor link in the Header navigation menu.apps/webinar/app/components/SpeakerCard.vue (2)
11-21: LGTM!The content layout is well-structured with appropriate visual hierarchy. The name, caption, and description fields are properly differentiated through typography and color.
26-26: LGTM!The prop type definition correctly includes all fields used in the template and aligns with the data structure mentioned in the context.
| <img | ||
| :src="speaker.image" | ||
| alt="" | ||
| class="w-full h-full object-cover rounded-lg" | ||
| > |
There was a problem hiding this comment.
Add descriptive alt text for speaker image.
The image has an empty alt attribute, which harms accessibility. Screen reader users won't receive any information about the speaker's photo.
Apply this diff to fix the accessibility issue:
<img
:src="speaker.image"
- alt=""
+ :alt="speaker.name"
class="w-full h-full object-cover rounded-lg"
>🤖 Prompt for AI Agents
In apps/webinar/app/components/SpeakerCard.vue around lines 4 to 8, the img
currently has an empty alt attribute; replace it with a descriptive, dynamic alt
that uses the speaker's name when available (e.g. "Photo of <speaker name>") and
falls back to a generic label like "Speaker photo" so screen readers get
meaningful information; keep the alt reactive (bind it) to speaker data and
avoid leaving it empty unless the image is purely decorative.



Summary by CodeRabbit
New Features
Enhancements
Style
Chores