diff --git a/src/app/admin/import/ImportCenterClient.tsx b/src/app/admin/import/ImportCenterClient.tsx
index 998c715..d0241da 100644
--- a/src/app/admin/import/ImportCenterClient.tsx
+++ b/src/app/admin/import/ImportCenterClient.tsx
@@ -179,21 +179,12 @@ export default function ImportCenterClient({ brandId: initialBrandId, brandName:
{/* ── Upload ── */}
{step === "upload" && (
-
{ e.preventDefault(); }}
onDrop={handleDrop}
- onClick={() => inputRef.current?.click()}
- onKeyDown={(e) => {
- if (e.key === "Enter" || e.key === " ") {
- e.preventDefault();
- inputRef.current?.click();
- }
- }}
className="flex flex-col items-center justify-center gap-3 rounded-2xl border-2 border-dashed border-[var(--admin-border)] bg-white p-12 cursor-pointer hover:border-[var(--admin-accent)] hover:bg-[var(--admin-bg)] transition-colors"
>
-
+
{ const f = e.target.files?.[0]; if (f) handleFile(f); }} />
+
{fileName && (
diff --git a/src/app/cart/CartClient.tsx b/src/app/cart/CartClient.tsx
index c90c78e..69e7f77 100644
--- a/src/app/cart/CartClient.tsx
+++ b/src/app/cart/CartClient.tsx
@@ -291,7 +291,7 @@ export default function CartClient() {
)}
-
+
+
diff --git a/src/app/pricing/PricingClientPage.tsx b/src/app/pricing/PricingClientPage.tsx
index c612ecc..461bed4 100644
--- a/src/app/pricing/PricingClientPage.tsx
+++ b/src/app/pricing/PricingClientPage.tsx
@@ -385,7 +385,7 @@ export default function PricingClientPage() {
function BillingToggle({ cycle, onChange }: { cycle: BillingCycle; onChange: (c: BillingCycle) => void }) {
return (
-
+
+
);
}
\ No newline at end of file
diff --git a/src/components/admin/BrandSelector.tsx b/src/components/admin/BrandSelector.tsx
index ff28481..660f472 100644
--- a/src/components/admin/BrandSelector.tsx
+++ b/src/components/admin/BrandSelector.tsx
@@ -140,57 +140,24 @@ export default function BrandSelector({
{open && (
-
{showAllBrandsOption && (
-
- )}
-
- {brands.map((b) => {
- const isActive = b.id === activeBrandId;
- return (
+
+
+ )}
+
+ {brands.map((b) => {
+ const isActive = b.id === activeBrandId;
+ return (
+
+
+
);
})}
-
+
)}
);
diff --git a/src/components/admin/BrandSettingsForm.tsx b/src/components/admin/BrandSettingsForm.tsx
index 77ba8eb..e960318 100644
--- a/src/components/admin/BrandSettingsForm.tsx
+++ b/src/components/admin/BrandSettingsForm.tsx
@@ -887,18 +887,10 @@ export function LogoUploadField({
dangerouslySetInnerHTML={{ __html: hint }}
/>
- {
- if (e.key === "Enter" || e.key === " ") {
- (e.currentTarget.querySelector('input[type="file"]') as HTMLInputElement | null)?.click();
- }
- }}
+
+
{error && {error}
}
diff --git a/src/components/admin/CommandPalette.tsx b/src/components/admin/CommandPalette.tsx
index b95e9a7..4c4e721 100644
--- a/src/components/admin/CommandPalette.tsx
+++ b/src/components/admin/CommandPalette.tsx
@@ -342,9 +342,9 @@ function CommandPaletteDialog({ onClose }: { onClose: () => void }) {
{/* Results */}
- void }) {
const Icon = ICON_MAP[entry.iconName] ?? Search;
const isSelected = i === safeSelected;
return (
-
+
);
})
)}
-
+
{/* Footer hint */}
setSearch(e.target.value)}
/>
-
+
{filtered.length === 0 && (
{search ? "No segments match." : "No saved segments yet."}
@@ -88,40 +88,36 @@ export default function SegmentListSidebar({ segments, activeSegmentId, onSelect
) : (
- onSelect(segment)}
- onKeyDown={(e) => {
- if (e.key === "Enter" || e.key === " ") {
- e.preventDefault();
- onSelect(segment);
- }
- }}
- className={`px-3 py-2.5 rounded-xl cursor-pointer flex items-center justify-between gap-2 transition-all ${
+
-
-
{segment.name}
- {segment.description && (
-
{segment.description}
- )}
-
{ e.stopPropagation(); setConfirmDelete(segment.id); }}
+ onClick={() => onSelect(segment)}
+ className="flex-1 min-w-0 text-left bg-transparent border-0 p-0 cursor-pointer"
+ aria-pressed={activeSegmentId === segment.id}
+ aria-label={`Select segment ${segment.name}`}
+ >
+ {segment.name}
+ {segment.description && (
+ {segment.description}
+ )}
+
+ setConfirmDelete(segment.id)}
className="opacity-0 group-hover:opacity-100 p-1.5 rounded-lg hover:bg-red-50 text-red-500 hover:text-red-600 transition-all"
aria-label="Delete segment"
>
{Icons.trash("w-4 h-4")}
-
+
)}
))}
-
+
);
}
\ No newline at end of file
diff --git a/src/components/admin/NewProductForm.tsx b/src/components/admin/NewProductForm.tsx
index 1eaa7ec..21b8342 100644
--- a/src/components/admin/NewProductForm.tsx
+++ b/src/components/admin/NewProductForm.tsx
@@ -240,21 +240,13 @@ export default function NewProductForm({ defaultBrandId = "", brands = [], lockB
Product Image
JPG, PNG, WebP · 1200px max width · max 5MB (ideally under 2MB)
- {
- if (e.key === "Enter" || e.key === " ") {
- fileInputRef.current?.click();
- }
- }}
+
+
{uploadError && {uploadError}
}
diff --git a/src/components/admin/ProductEditForm.tsx b/src/components/admin/ProductEditForm.tsx
index 3fe615d..2583de0 100644
--- a/src/components/admin/ProductEditForm.tsx
+++ b/src/components/admin/ProductEditForm.tsx
@@ -320,21 +320,13 @@ export default function ProductEditForm({ product, brands }: ProductEditFormProp
JPG, PNG, WebP · 1200px max width · max 5MB (ideally under 2MB)
- {
- if (e.key === "Enter" || e.key === " ") {
- fileInputRef.current?.click();
- }
- }}
+
+
{uploadError && {uploadError}
}
diff --git a/src/components/admin/ProductFormModal.tsx b/src/components/admin/ProductFormModal.tsx
index 63d0da5..47ace92 100644
--- a/src/components/admin/ProductFormModal.tsx
+++ b/src/components/admin/ProductFormModal.tsx
@@ -310,14 +310,7 @@ export default function ProductFormModal({
01 · Media
-
{
- if (e.key === "Enter" || e.key === " ") {
- if (!uploading) fileInputRef.current?.click();
- }
- }}
+
+
{uploadError && (
diff --git a/src/components/admin/ScheduleImportModal.tsx b/src/components/admin/ScheduleImportModal.tsx
index a56c13e..c111fd1 100644
--- a/src/components/admin/ScheduleImportModal.tsx
+++ b/src/components/admin/ScheduleImportModal.tsx
@@ -162,18 +162,10 @@ export default function ScheduleImportModal({ brandId, onClose, onComplete }: Pr
{/* Drop zone */}
- {
- if (e.key === "Enter" || e.key === " ") {
- fileInputRef.current?.click();
- }
- }}
+
+
>
diff --git a/src/components/admin/UpgradePlanModal.tsx b/src/components/admin/UpgradePlanModal.tsx
index 9e6fcca..5f6f1b1 100644
--- a/src/components/admin/UpgradePlanModal.tsx
+++ b/src/components/admin/UpgradePlanModal.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useState, useEffect, useEffectEvent, useCallback } from "react";
+import { useState, useEffect, useCallback, useRef } from "react";
import { createPlanUpgradeCheckout } from "@/actions/billing/stripe-checkout";
type PlanTier = "starter" | "farm" | "enterprise";
@@ -83,48 +83,25 @@ export default function UpgradePlanModal({
}: UpgradePlanModalProps) {
const [annual, setAnnual] = useState(() => defaultAnnual);
const [loading, setLoading] = useState(null);
- const [isVisible, setIsVisible] = useState(() => false);
+ const dialogRef = useRef(null);
- // Handle animation state — derived during render per React docs:
- // "Adjusting some state when a prop changes". Uses a lazy initializer so
- // the lint's static "useState(prop)" check does not fire.
- const [prevIsOpen, setPrevIsOpen] = useState(() => isOpen);
- if (isOpen !== prevIsOpen) {
- setPrevIsOpen(isOpen);
- if (isOpen) {
- requestAnimationFrame(() => setIsVisible(true));
- } else {
- setIsVisible(false);
- }
- }
+ // Open the dialog once on mount; rely on parent to unmount when closing
+ const setDialogRef = (el: HTMLDialogElement | null) => {
+ dialogRef.current = el;
+ if (el && !el.open) el.showModal();
+ };
- // Lock body scroll when modal is open
+ // Native