From 5a0a91a601b681783f6903a79f4ca6317b6a5f27 Mon Sep 17 00:00:00 2001 From: Petr Glaser Date: Tue, 16 Dec 2025 14:39:54 +0100 Subject: [PATCH 1/2] fix: replace index-based React keys with stable identifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rating component: Use `star-${index}` for star rating items - Carousel component: Use `indicator-${index}` for carousel indicators - Slider component: Use `thumb-${index}` for slider thumbs - Skeleton component: Use `skeleton-text-${index}` for text lines - Navigation: Use slugified title as key instead of index - Product info: Use `badge-${variant}-${idx}` for badges - Stats section: Use `stat-${year}` for stat cards - Contact page: Use item label as key - Orders skeleton: Add prefixed keys for mobile/desktop skeletons - Product grid skeleton: Use `product-skeleton-${i}` prefix Closes #64 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- apps/frontend-demo/src/app/contact/page.tsx | 4 ++-- apps/frontend-demo/src/components/account/orders-skeleton.tsx | 4 ++-- apps/frontend-demo/src/components/molecules/navigation.tsx | 4 ++-- .../src/components/molecules/product-grid-skeleton.tsx | 2 +- apps/frontend-demo/src/components/organisms/product-info.tsx | 2 +- apps/frontend-demo/src/components/stats-section.tsx | 2 +- libs/ui/src/atoms/rating.tsx | 2 +- libs/ui/src/atoms/skeleton.tsx | 2 +- libs/ui/src/molecules/carousel.tsx | 2 +- libs/ui/src/molecules/slider.tsx | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/frontend-demo/src/app/contact/page.tsx b/apps/frontend-demo/src/app/contact/page.tsx index 50a64e2116..8621aaa7e6 100644 --- a/apps/frontend-demo/src/app/contact/page.tsx +++ b/apps/frontend-demo/src/app/contact/page.tsx @@ -139,9 +139,9 @@ export default function ContactPage() {

{info.title}

- {info.items.map((item, index) => ( + {info.items.map((item) => (
{maxItems.map((_, i) => (
@@ -67,7 +67,7 @@ export function OrdersSkeleton({ itemsCount }: { itemsCount: number }) {
{maxItems.map((_, i) => (
diff --git a/apps/frontend-demo/src/components/molecules/navigation.tsx b/apps/frontend-demo/src/components/molecules/navigation.tsx index eea1171aeb..408b5d8580 100644 --- a/apps/frontend-demo/src/components/molecules/navigation.tsx +++ b/apps/frontend-demo/src/components/molecules/navigation.tsx @@ -77,8 +77,8 @@ export function Navigation({ items, className, ...props }: NavigationProps) { return ( diff --git a/apps/frontend-demo/src/components/molecules/product-grid-skeleton.tsx b/apps/frontend-demo/src/components/molecules/product-grid-skeleton.tsx index 7ec6874acc..2e9b98169f 100644 --- a/apps/frontend-demo/src/components/molecules/product-grid-skeleton.tsx +++ b/apps/frontend-demo/src/components/molecules/product-grid-skeleton.tsx @@ -6,7 +6,7 @@ export function ProductGridSkeleton({ return (
{[...Array(numberOfItems)].map((_, i) => ( -
+
0 && (
{badges.map((badge, idx) => ( - + ))}
)} diff --git a/apps/frontend-demo/src/components/stats-section.tsx b/apps/frontend-demo/src/components/stats-section.tsx index 168723383d..25415be3cc 100644 --- a/apps/frontend-demo/src/components/stats-section.tsx +++ b/apps/frontend-demo/src/components/stats-section.tsx @@ -59,7 +59,7 @@ export function StatsSection() { colorClasses[stat.color as keyof typeof colorClasses] return ( -
+
{/* Main content */}
{/* Top section */} diff --git a/libs/ui/src/atoms/rating.tsx b/libs/ui/src/atoms/rating.tsx index 0cb5333713..40fb97083b 100644 --- a/libs/ui/src/atoms/rating.tsx +++ b/libs/ui/src/atoms/rating.tsx @@ -126,7 +126,7 @@ export function Rating({
{api.items.map((index) => ( -
+
))} diff --git a/libs/ui/src/atoms/skeleton.tsx b/libs/ui/src/atoms/skeleton.tsx index 901206c02c..8bee260173 100644 --- a/libs/ui/src/atoms/skeleton.tsx +++ b/libs/ui/src/atoms/skeleton.tsx @@ -233,7 +233,7 @@ Skeleton.Text = function SkeletonText({ return (
(
{api.value.map((_, index) => (
From cbfab73b239805fabfcd3f69906bdea89fc3ed3c Mon Sep 17 00:00:00 2001 From: Petr Glaser Date: Tue, 16 Dec 2025 21:07:20 +0100 Subject: [PATCH 2/2] fix: use slugify for items.label --- apps/frontend-demo/src/app/contact/page.tsx | 91 ++++++++++--------- .../frontend-demo/src/data/contact-content.ts | 78 ++++++++-------- 2 files changed, 85 insertions(+), 84 deletions(-) diff --git a/apps/frontend-demo/src/app/contact/page.tsx b/apps/frontend-demo/src/app/contact/page.tsx index 8621aaa7e6..c1bb7b4e8f 100644 --- a/apps/frontend-demo/src/app/contact/page.tsx +++ b/apps/frontend-demo/src/app/contact/page.tsx @@ -1,17 +1,18 @@ -'use client' -import { contactContent } from '@/data/contact-content' -import { useContactForm } from '@/hooks/use-contact-form' -import { Button } from '@techsio/ui-kit/atoms/button' -import { Icon, type IconType } from '@techsio/ui-kit/atoms/icon' -import { LinkButton } from '@techsio/ui-kit/atoms/link-button' -import { FormInput } from '@techsio/ui-kit/molecules/form-input' -import { FormTextarea } from '@techsio/ui-kit/molecules/form-textarea' -import { Select } from '@techsio/ui-kit/molecules/select' -import Image from 'next/image' -import contactImage from '/assets/hero/contact.webp' +"use client" +import { Button } from "@techsio/ui-kit/atoms/button" +import { Icon, type IconType } from "@techsio/ui-kit/atoms/icon" +import { LinkButton } from "@techsio/ui-kit/atoms/link-button" +import { FormInput } from "@techsio/ui-kit/molecules/form-input" +import { FormTextarea } from "@techsio/ui-kit/molecules/form-textarea" +import { Select } from "@techsio/ui-kit/molecules/select" +import { slugify } from "@techsio/ui-kit/utils" +import Image from "next/image" +import { contactContent } from "@/data/contact-content" +import { useContactForm } from "@/hooks/use-contact-form" +import contactImage from "/assets/hero/contact.webp" export default function ContactPage() { - const { hero, form, info, hours, help } = contactContent + const { hero, form, info, help } = contactContent const { formData, updateField, handleSubmit, isSubmitting } = useContactForm() return ( @@ -19,13 +20,13 @@ export default function ContactPage() { {/* Hero Section */}
Naše kancelář
@@ -40,14 +41,14 @@ export default function ContactPage() {
{/* Contact Content */} -
+
{/* Contact Form */}

{form.title} @@ -56,78 +57,78 @@ export default function ContactPage() { ) => - updateField('firstName', e.target.value) + updateField("firstName", e.target.value) } required + size="sm" + value={formData.firstName} /> ) => - updateField('lastName', e.target.value) + updateField("lastName", e.target.value) } required + size="sm" + value={formData.lastName} /> ) => - updateField('email', e.target.value) + updateField("email", e.target.value) } required + size="sm" + type="email" + value={formData.email} /> ) => - updateField('phone', e.target.value) + updateField("phone", e.target.value) } required + size="sm" + type="tel" + value={formData.phone} />