Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 6 additions & 7 deletions src/components/home/products-section.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client"

import { useState } from "react"
import Image from "next/image"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Container } from "@/components/ui/container"
Expand Down Expand Up @@ -85,7 +84,7 @@ Built with modern businesses in mind, StormERP integrates seamlessly with your e
"Business Intelligence & Reporting",
"Multi-Location & Multi-Currency Support"
],
productUrl: "https://erp.codestormhub.live",
productUrl: "https://codestormhub.live/erp/dashboard",
dashboardImage: "/products/stormerp-dashboard.png",
status: "active",
category: "ERP"
Expand All @@ -97,8 +96,6 @@ interface ProductsSectionProps {
}

export default function ProductsSection({ className }: ProductsSectionProps) {
const [selectedProduct, setSelectedProduct] = useState<Product | null>(null)

return (
<section className={className} aria-labelledby="products-heading">
<Container className="py-16 sm:py-24">
Expand Down Expand Up @@ -172,7 +169,6 @@ export default function ProductsSection({ className }: ProductsSectionProps) {
variant="outline"
size="sm"
className="flex-1"
onClick={() => setSelectedProduct(product)}
>
View Details
</Button>
Expand All @@ -193,7 +189,10 @@ export default function ProductsSection({ className }: ProductsSectionProps) {
</Card>

{/* Product Detail Modal */}
<DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto">
<DialogContent
className="max-w-5xl max-h-[90vh] overflow-y-auto"
aria-describedby="product-description"

Copilot AI Jan 13, 2026

Copy link

Choose a reason for hiding this comment

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

The aria-describedby attribute references a hardcoded ID "product-description", but this ID is duplicated for each product in the map loop (line 224). HTML IDs must be unique within the document. Consider using a dynamic ID such as product-description-${product.id} for both the aria-describedby attribute and the corresponding id on line 224.

Copilot uses AI. Check for mistakes.
>
<DialogHeader>
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-primary/20 flex items-center justify-center">
Expand Down Expand Up @@ -222,7 +221,7 @@ export default function ProductsSection({ className }: ProductsSectionProps) {
</div>

{/* Description */}
<div className="space-y-3">
<div className="space-y-3" id="product-description">

Copilot AI Jan 13, 2026

Copy link

Choose a reason for hiding this comment

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

This ID "product-description" is duplicated for each product in the map loop. It needs to be unique by incorporating the product identifier, such as product-description-${product.id}, to match the aria-describedby reference on line 194.

Suggested change
<div className="space-y-3" id="product-description">
<div className="space-y-3" id={`product-description-${product.id}`}>

Copilot uses AI. Check for mistakes.
<h4 className="text-lg font-semibold">About {product.name}</h4>
<div className="text-muted-foreground whitespace-pre-line leading-relaxed">
{product.fullDescription}
Expand Down
21 changes: 21 additions & 0 deletions src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const DialogOverlay = React.forwardRef<
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName

type DialogOverlayProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>

const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
Expand All @@ -53,6 +55,8 @@ const DialogContent = React.forwardRef<
))
DialogContent.displayName = DialogPrimitive.Content.displayName

type DialogContentProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>

const DialogHeader = ({
className,
...props
Expand All @@ -67,6 +71,8 @@ const DialogHeader = ({
)
DialogHeader.displayName = "DialogHeader"

type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>

const DialogFooter = ({
className,
...props
Expand All @@ -81,6 +87,8 @@ const DialogFooter = ({
)
DialogFooter.displayName = "DialogFooter"

type DialogFooterProps = React.HTMLAttributes<HTMLDivElement>

const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
Expand All @@ -96,6 +104,8 @@ const DialogTitle = React.forwardRef<
))
DialogTitle.displayName = DialogPrimitive.Title.displayName

type DialogTitleProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>

const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
Expand All @@ -108,6 +118,8 @@ const DialogDescription = React.forwardRef<
))
DialogDescription.displayName = DialogPrimitive.Description.displayName

type DialogDescriptionProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>

export {
Dialog,
DialogPortal,
Expand All @@ -120,3 +132,12 @@ export {
DialogTitle,
DialogDescription,
}

export type {
DialogOverlayProps,
DialogContentProps,
DialogHeaderProps,
DialogFooterProps,
DialogTitleProps,
DialogDescriptionProps,
}
Loading