Skip to content

fix: harden admin magic runtime guards#172

Merged
adm01-debug merged 2 commits into
mainfrom
fix/batch-admin-magic-runtime-hardening
May 24, 2026
Merged

fix: harden admin magic runtime guards#172
adm01-debug merged 2 commits into
mainfrom
fix/batch-admin-magic-runtime-hardening

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 23, 2026

Summary

  • Replace targeted non-null assertions in admin product/import, supplier, kit-builder, Magic Up, novelty, simulator, and quote signature paths.
  • Add null-safe map access, safe collection fallbacks, guarded canvas/selection handling, and safer copy/render logic for optional data.
  • Remove unused imports/destructured values surfaced by focused lint in touched files.

Validation

  • Targeted rg search for the removed assertion patterns returned no matches.
  • npx.cmd eslint on the 15 touched files passed.
  • git diff --check HEAD~1..HEAD passed.
  • npx.cmd vitest run src/components/products/customization/__tests__/LocationPanelPrice.test.tsx src/components/products/ProductGrid.test.tsx passed: 2 files, 6 tests.
  • npm.cmd run build passed with existing Vite/Tailwind warnings.

Notes

  • npx.cmd tsc -p tsconfig.app.json --noEmit --pretty false was attempted and timed out after 4 minutes without emitting errors.
  • Push used HUSKY=0 because the repository pre-push lint:baseline hook is currently failing locally before remote validation.

Summary by cubic

Hardened runtime guards across admin, personalization manager, and Magic flows to prevent crashes when optional data is missing. Replaced non-null assertions with safe checks and fallbacks across selectors, imports, novelty grid, simulator, and signature pad.

  • Bug Fixes

    • Admin products/import and suppliers: null-safe map access, flatMap for import rows, safer PIX validation fallback with default message, and trimmed payload fields without !.
    • Category selectors: guarded handlers and null-safe tree/group building in cascade and simple selectors.
    • Personalization manager: guarded DnD and selection handlers to avoid null refs in accordion/drag operations.
    • Magic/novelties UI: resilient copy/render and gallery logic; guarded canvas/history/favorites; safer prompt and ad image flows; sturdier novelty grid reads.
    • Pricing and quotes: safer technique/variant selection and result calculations; guarded signature canvas and input handling.
  • Refactors

    • Removed unused imports and tightened destructuring in touched files.
    • Corrected effect dependencies and applied consistent null-safe patterns.
    • Kit builder VariantSelector: removed unused itemName prop.

Written for commit edfc49b. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Robustez em validações (PIX, prompts, seletores) e tratamento de erros na geração de prompts
    • Importação em massa mais confiável na seleção de linhas para import
  • Melhorias de UI/UX

    • Modal de novo componente com formulário e feedback de carregamento
    • Estados de carregamento, telas vazias e skeletons mais claros (listas, grid, previews)
    • Interações de teclado e ações de favoritar/excluir em galerias de imagens aprimoradas
    • Layouts e estilos de seleção de variantes, categorias e previews de logo refinados

Review Change Stack

Copilot AI review requested due to automatic review settings May 23, 2026 19:08
@vercel
Copy link
Copy Markdown

vercel Bot commented May 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 24, 2026 11:29am

@supabase
Copy link
Copy Markdown

supabase Bot commented May 23, 2026

This pull request has been ignored for the connected project doufsxqlfjyuvxuezpln because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Walkthrough

PR refatora 13 componentes para melhorar null-safety em operações Map/Array, adiciona validação com fallback seguro em validadores PIX, refatora data flows em ProductPersonalizationManager/NoveltyProductGrid/MultiEngravingResult, aprimora error handling em PromptGenerator com Promise.all para async pricing, e atualiza UI visual em AdImageResult/LogoPreviewCanvas/TechniqueSelector.

Changes

Null-Safety Hardening

Layer / File(s) Summary
Category tree building & popover selection
src/components/admin/products/CategoryCascadeSelector.tsx, src/components/admin/products/CategorySelect.tsx
map.get(...)? em vez de map.get(...).! ao inserir nós filhos; CategorySelect reorganiza breadcrumb/busca/seleção com null-checks explícitos em classes e renderização.
Variant & size grouping with optional chaining
src/components/kit-builder/VariantSelector.tsx, src/components/pricing/simulator/ProductVariantSelector.tsx
Grouping por cor usa optional chaining em Map.get ao add variantes; renderização de chips/botões com classes seguras para estado selecionado/sem-estoque.
Canvas & context null checks
src/components/quotes/QuoteSignaturePad.tsx
getPos, draw, clear, submit retornam cedo quando canvas/context faltam; useState com defaults vazios para name/document; useEffect setup strokeStyle/lineWidth.

Validation & Error Handling

Layer / File(s) Summary
PIX key validation with fallback
src/components/admin/products/new-supplier/useNewSupplierForm.ts, src/components/admin/suppliers-manager/useSuppliersManager.ts
validatePixKey retorna nullish → ?? 'Chave PIX inválida' garante sempre string para toast.error; payload de save agora evita non-null assertion em nome→code fallback.
PromptGenerator error handling & context extension
src/components/magic-up/PromptGenerator.tsx
Payload agora inclui dimensionUnit/isCurved/season; lança Error explícito quando data.prompts não é array; filter(Boolean) + join(" — ") para locationName/techniqueName; safePrintAreas evita undefined ao renderizar Painel de customização.
TechniqueSelector handler safety
src/components/pricing/simulator/TechniqueSelector.tsx
handleLocationSelect/handleTechniqueSelect validam existence de comp/loc/tech antes de prosseguir; useEffect agora depende de onSelect para reset correto.

Component Data Flow Refactoring

Layer / File(s) Summary
ProductPersonalizationManager conditional rendering
src/components/admin/personalization-manager/ProductPersonalizationManager.tsx
Mapeia m.components apenas quando m.selectedProduct definido; modal "Novo Componente" com campos código/nome explícitos; três estados (loading/empty/list com DnD/Accordion).
NoveltyProductGrid loading & product derivation
src/components/novelties/NoveltyProductGrid.tsx
products via useMemo; loadingProgress com setInterval/setTimeout explícito; esqueleto com barra animada; filtros/ordenação preservados; seleção em massa com BulkActionBar/BulkVariantWizard.
MultiEngravingResult async pricing refactor
src/components/pricing/simulator/MultiEngravingResult.tsx
Promise.all com try/catch por engraving; calculatePrice(engraving.technique.id, quantity, colors); per-item priceData/loading/error; JSX customizações reestruturado com badges de código (Copy/CheckCircle2).
BulkImportDialog row filtering
src/components/admin/products/BulkImportDialog.tsx
flatMap em rowsToImport filtrando valid/data e !existsInDb no modo insert; preserva fluxo de validação/etapas.

UI Visual Refinement

Layer / File(s) Summary
AdImageResult history & interactions
src/components/magic-up/AdImageResult.tsx
Galeria de histórico reescrita com suporte teclado (Enter/Space); stopPropagation em botões favoritar/excluir; imagem principal com overlay ajustado; ações mobile/copy comercial com navigator.clipboard?.writeText.
LogoPreviewCanvas rendering
src/components/mockup/logo-editor/LogoPreviewCanvas.tsx
Aspas simples em imports; indicador "Simulando" com Badge reorganizado; produto preview com h-full/object-contain; logo alternando src conforme isCanvasProcessed; fallback com dataset.fallback.
TechniqueSelector UI & summary
src/components/pricing/simulator/TechniqueSelector.tsx
Step indicators com className condicional; cards componente/local/técnica com ícones Package/Ruler/Paintbrush; resumo em grid com rótulos; maxWidth/maxHeight/maxColors com Ruler/Palette.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • adm01-debug/promo-gifts-v4#168: PR relacionado que também endurece normalização de dados e remoção de non-null assertions em componentes de produtos.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed O título descreve com precisão o objetivo principal: enrijecer guards de runtime em código admin/magic, removendo non-null assertions e adicionando null-safety em múltiplos arquivos.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/batch-admin-magic-runtime-hardening

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens several admin, pricing simulator, Magic Up, and novelty UI flows by removing targeted non-null assertions and adding null-safe guards/fallbacks to reduce runtime crashes when optional data is missing.

Changes:

  • Replaced ! assertions with guarded access (null-safe map access, safe refs, and safer collection fallbacks).
  • Improved handler safety in selectors (component/location/technique selection) and canvas/signature flows.
  • Cleaned up imports/formatting and minor UI/layout adjustments while maintaining behavior.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/components/quotes/QuoteSignaturePad.tsx Removes unsafe canvasRef.current! usage and guards canvas interactions.
src/components/pricing/simulator/TechniqueSelector.tsx Guards selection handlers and fixes effect deps for safer technique picking.
src/components/pricing/simulator/ProductVariantSelector.tsx Makes variant grouping logic null-safe and adjusts UI classes.
src/components/pricing/simulator/MultiEngravingResult.tsx Removes non-null assertions around calculation results / codes and cleans imports.
src/components/novelties/NoveltyProductGrid.tsx Adds safer defaults and refactors loading/progress/filter rendering for resilience.
src/components/mockup/logo-editor/LogoPreviewCanvas.tsx Avoids non-null assertions in logo rendering and improves conditional rendering safety.
src/components/magic-up/PromptGenerator.tsx Uses safe print area fallbacks and removes non-null assertions in customization panel wiring.
src/components/magic-up/AdImageResult.tsx Removes unsafe imageUrl! and improves guarded rendering around optional props.
src/components/kit-builder/VariantSelector.tsx Makes variant grouping null-safe and cleans up imports/props usage.
src/components/admin/suppliers-manager/useSuppliersManager.ts Replaces assertions and improves PIX validation error fallback.
src/components/admin/products/new-supplier/useNewSupplierForm.ts Improves PIX validation error fallback (no !).
src/components/admin/products/CategorySelect.tsx Makes tree building null-safe and refactors breadcrumb/search logic formatting.
src/components/admin/products/CategoryCascadeSelector.tsx Makes tree building null-safe and cleans import formatting.
src/components/admin/products/BulkImportDialog.tsx Uses flatMap to avoid data! assertions when building import rows.
src/components/admin/personalization-manager/ProductPersonalizationManager.tsx Adds guard to avoid rendering with selectedProduct! and refactors props formatting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/magic-up/AdImageResult.tsx Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/admin/products/BulkImportDialog.tsx (1)

263-288: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Trate falha de executeBatchImport para evitar UI travada em “importing”.

Se a Promise falhar em Line 278, hoje não há try/catch local: o usuário pode ficar sem feedback e sem rollback de estado.

✅ Sugestão objetiva de correção
   const executeImport = useCallback(async () => {
     let rowsToImport: ImportRow[];
     if (importMode === 'insert') {
       rowsToImport = validationResults.flatMap((r) =>
         r.valid && r.data && !r.existsInDb ? [r.data] : [],
       );
     } else {
       rowsToImport = validationResults.flatMap((r) => (r.valid && r.data ? [r.data] : []));
     }
     if (rowsToImport.length === 0) {
       toast.error('Nenhuma linha para importar');
       return;
     }

-    setStep('importing');
-    const result = await executeBatchImport(rowsToImport, importMode, (p) => setProgress({ ...p }));
-    setImportResult(result);
-    setStep('complete');
-    if (result.succeeded > 0) {
-      toast.success(`${result.succeeded} produto(s) importado(s)!`);
-      onComplete();
-    }
-    if (result.failed > 0) {
-      toast.error(`${result.failed} produto(s) falharam`);
-    }
+    setStep('importing');
+    try {
+      const result = await executeBatchImport(rowsToImport, importMode, (p) => setProgress({ ...p }));
+      setImportResult(result);
+      setStep('complete');
+      if (result.succeeded > 0) {
+        toast.success(`${result.succeeded} produto(s) importado(s)!`);
+        onComplete();
+      }
+      if (result.failed > 0) {
+        toast.error(`${result.failed} produto(s) falharam`);
+      }
+    } catch (err) {
+      logger.error('Falha na importação em lote:', err);
+      toast.error('Falha ao importar produtos. Tente novamente.');
+      setStep('preview');
+    }
   }, [validationResults, importMode, onComplete]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/admin/products/BulkImportDialog.tsx` around lines 263 - 288, A
Promise rejection from executeBatchImport can leave the UI stuck in the
"importing" step; inside the executeImport function wrap the await
executeBatchImport(rowsToImport, importMode, ...) call in a try/catch (and
optionally a finally) so that on error you setStep('complete') (or a dedicated
error state), setImportResult to an error/empty result, reset/setProgress
appropriately, and call toast.error with the caught error message; reference the
executeImport function, the executeBatchImport call, setStep, setImportResult,
setProgress and toast so you ensure the UI state is always updated and
onComplete is not called on failures.
src/components/pricing/simulator/MultiEngravingResult.tsx (1)

61-102: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Evitar sobrescrita de estado por resposta assíncrona obsoleta.

O fluxo atual pode aplicar no estado o resultado de um cálculo antigo (corrida entre chamadas), exibindo total/prazo incorretos quando quantity ou engravings mudam rápido.

Diff sugerido
   useEffect(() => {
+    let cancelled = false;
+
     const calculateAll = async () => {
       if (engravings.length === 0) {
         setCalculations([]);
+        setIsCalculating(false);
         return;
       }
 
       setIsCalculating(true);
@@
       const results = await Promise.all(
         engravings.map(async (engraving) => {
@@
         }),
       );
 
+      if (cancelled) return;
       setCalculations(results);
       setIsCalculating(false);
     };
 
     const debounce = setTimeout(calculateAll, 300);
-    return () => clearTimeout(debounce);
+    return () => {
+      cancelled = true;
+      clearTimeout(debounce);
+    };
   }, [engravings, quantity, calculatePrice]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/pricing/simulator/MultiEngravingResult.tsx` around lines 61 -
102, The effect can apply stale async results to state when multiple
calculateAll runs overlap; modify the useEffect/calculateAll flow to ignore
outdated responses by introducing a request token/ID (e.g., a useRef like
currentRequestId) or an AbortController so each run captures a unique
id/controller, checks it before calling setCalculations/setIsCalculating, and/or
aborts in-flight calculatePrice calls on cleanup; update the calculateAll
mapping (the async engraving loop) to bail out if the token has changed and only
setCalculations/setIsCalculating for the latest token, referencing the existing
useEffect, calculateAll function, setCalculations and setIsCalculating
identifiers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/novelties/NoveltyProductGrid.tsx`:
- Line 399: No componente NoveltyProductGrid atualize o valor do placeholder
usado no campo de busca: substitua a string placeholder="Buscar novidades…  /"
por uma versão sem a barra e sem o espaço extra (ex: "Buscar novidades…") no
elemento que define o atributo placeholder (procure pelo atributo placeholder
dentro de NoveltyProductGrid.tsx).

In `@src/components/pricing/simulator/TechniqueSelector.tsx`:
- Around line 171-175: Add explicit type="button" to the clickable card buttons
in the TechniqueSelector component to prevent accidental form submissions;
locate the button elements rendered in TechniqueSelector.tsx (the ones using
onClick={() => handleComponentSelect(comp)}) and any other similar card buttons
around the other occurrences referenced, and update their JSX to include
type="button" on each <button> element so clicks do not act as submits when
inside a form.

---

Outside diff comments:
In `@src/components/admin/products/BulkImportDialog.tsx`:
- Around line 263-288: A Promise rejection from executeBatchImport can leave the
UI stuck in the "importing" step; inside the executeImport function wrap the
await executeBatchImport(rowsToImport, importMode, ...) call in a try/catch (and
optionally a finally) so that on error you setStep('complete') (or a dedicated
error state), setImportResult to an error/empty result, reset/setProgress
appropriately, and call toast.error with the caught error message; reference the
executeImport function, the executeBatchImport call, setStep, setImportResult,
setProgress and toast so you ensure the UI state is always updated and
onComplete is not called on failures.

In `@src/components/pricing/simulator/MultiEngravingResult.tsx`:
- Around line 61-102: The effect can apply stale async results to state when
multiple calculateAll runs overlap; modify the useEffect/calculateAll flow to
ignore outdated responses by introducing a request token/ID (e.g., a useRef like
currentRequestId) or an AbortController so each run captures a unique
id/controller, checks it before calling setCalculations/setIsCalculating, and/or
aborts in-flight calculatePrice calls on cleanup; update the calculateAll
mapping (the async engraving loop) to bail out if the token has changed and only
setCalculations/setIsCalculating for the latest token, referencing the existing
useEffect, calculateAll function, setCalculations and setIsCalculating
identifiers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c626bee7-55e4-433f-9716-4539ff98e3ea

📥 Commits

Reviewing files that changed from the base of the PR and between 7fb9cee and cf0c86d.

📒 Files selected for processing (15)
  • src/components/admin/personalization-manager/ProductPersonalizationManager.tsx
  • src/components/admin/products/BulkImportDialog.tsx
  • src/components/admin/products/CategoryCascadeSelector.tsx
  • src/components/admin/products/CategorySelect.tsx
  • src/components/admin/products/new-supplier/useNewSupplierForm.ts
  • src/components/admin/suppliers-manager/useSuppliersManager.ts
  • src/components/kit-builder/VariantSelector.tsx
  • src/components/magic-up/AdImageResult.tsx
  • src/components/magic-up/PromptGenerator.tsx
  • src/components/mockup/logo-editor/LogoPreviewCanvas.tsx
  • src/components/novelties/NoveltyProductGrid.tsx
  • src/components/pricing/simulator/MultiEngravingResult.tsx
  • src/components/pricing/simulator/ProductVariantSelector.tsx
  • src/components/pricing/simulator/TechniqueSelector.tsx
  • src/components/quotes/QuoteSignaturePad.tsx

{searchQuery && <button onClick={() => setSearchQuery("")} className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"><X className="h-3 w-3" /></button>}
<Search className="absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
<Input
placeholder="Buscar novidades… /"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remover caractere extra no placeholder de busca.

Na Line 399, o placeholder tem uma barra (/) sobrando ("Buscar novidades… /"), o que aparece como ruído na UI.

Diff sugerido
-                  placeholder="Buscar novidades…  /"
+                  placeholder="Buscar novidades…"
📝 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.

Suggested change
placeholder="Buscar novidades… /"
placeholder="Buscar novidades…"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/novelties/NoveltyProductGrid.tsx` at line 399, No componente
NoveltyProductGrid atualize o valor do placeholder usado no campo de busca:
substitua a string placeholder="Buscar novidades…  /" por uma versão sem a barra
e sem o espaço extra (ex: "Buscar novidades…") no elemento que define o atributo
placeholder (procure pelo atributo placeholder dentro de
NoveltyProductGrid.tsx).

Comment on lines 171 to 175
<button
key={`${comp.code}-${idx}`}
onClick={() => handleComponentSelect(comp)}
className="p-4 rounded-lg border bg-card hover:bg-accent hover:border-primary/50 transition-all text-left group"
className="group rounded-lg border bg-card p-4 text-left transition-all hover:border-primary/50 hover:bg-accent"
>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Defina type="button" nos botões de seleção

Sem type explícito, o default é submit; se este componente estiver dentro de <form>, clique em card pode disparar submit acidental.

✅ Correção rápida
-              <button
+              <button
+                type="button"
                 key={`${comp.code}-${idx}`}
                 onClick={() => handleComponentSelect(comp)}
                 className="group rounded-lg border bg-card p-4 text-left transition-all hover:border-primary/50 hover:bg-accent"
               >
...
-                <button
+                <button
+                  type="button"
                   key={`${loc.code}-${idx}`}
                   onClick={() => handleLocationSelect(loc)}
                   className="group rounded-lg border bg-card p-4 text-left transition-all hover:border-primary/50 hover:bg-accent"
                 >
...
-              <button
+              <button
+                type="button"
                 key={tech.id}
                 onClick={() => handleTechniqueSelect(tech)}
                 className="group rounded-lg border bg-card p-4 text-left transition-all hover:border-primary/50 hover:bg-accent"
               >

Also applies to: 213-216, 249-253

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/pricing/simulator/TechniqueSelector.tsx` around lines 171 -
175, Add explicit type="button" to the clickable card buttons in the
TechniqueSelector component to prevent accidental form submissions; locate the
button elements rendered in TechniqueSelector.tsx (the ones using onClick={() =>
handleComponentSelect(comp)}) and any other similar card buttons around the
other occurrences referenced, and update their JSX to include type="button" on
each <button> element so clicks do not act as submits when inside a form.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 15 files

Re-trigger cubic

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/magic-up/AdImageResult.tsx (1)

405-405: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Promise do clipboard sem tratamento de erro.

A chamada navigator.clipboard?.writeText() retorna uma Promise que pode falhar (ex: permissões negadas, contexto não-HTTPS), mas não há .catch() nem await para tratar rejeições. Isso pode gerar unhandled rejection e o usuário não recebe feedback caso a cópia falhe.

Como per coding guidelines, Promises devem ter .catch() ou await com try/catch.

🛡️ Fix proposto com tratamento de erro
                  <Button
                    size="sm"
                    variant="ghost"
                    className="h-7 gap-1 text-xs"
-                    onClick={() => navigator.clipboard?.writeText(copyPack.whatsapp)}
+                    onClick={async () => {
+                      try {
+                        await navigator.clipboard?.writeText(copyPack.whatsapp);
+                      } catch {
+                        // Silent fail ou adicionar toast de erro
+                      }
+                    }}
                  >
                    <Copy className="h-3.5 w-3.5" /> Copiar WhatsApp
                  </Button>

Alternativa com feedback ao usuário (requer import do toast):

onClick={async () => {
  try {
    await navigator.clipboard?.writeText(copyPack.whatsapp);
    toast.success('Copiado para área de transferência');
  } catch {
    toast.error('Erro ao copiar texto');
  }
}}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/magic-up/AdImageResult.tsx` at line 405, The inline onClick
currently calls navigator.clipboard?.writeText(copyPack.whatsapp) without
handling the returned Promise; change the handler to an async function that
awaits navigator.clipboard?.writeText(copyPack.whatsapp) inside a try/catch, and
in the try call toast.success('Copiado para área de transferência') and in the
catch call toast.error('Erro ao copiar texto') so rejections are handled and the
user gets feedback; update the onClick referencing
navigator.clipboard?.writeText(copyPack.whatsapp) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/magic-up/AdImageResult.tsx`:
- Line 405: The inline onClick currently calls
navigator.clipboard?.writeText(copyPack.whatsapp) without handling the returned
Promise; change the handler to an async function that awaits
navigator.clipboard?.writeText(copyPack.whatsapp) inside a try/catch, and in the
try call toast.success('Copiado para área de transferência') and in the catch
call toast.error('Erro ao copiar texto') so rejections are handled and the user
gets feedback; update the onClick referencing
navigator.clipboard?.writeText(copyPack.whatsapp) accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9bb24bd4-69e2-445c-acb8-990cd2d998a1

📥 Commits

Reviewing files that changed from the base of the PR and between cf0c86d and edfc49b.

📒 Files selected for processing (1)
  • src/components/magic-up/AdImageResult.tsx

@adm01-debug adm01-debug merged commit 4e46adc into main May 24, 2026
27 of 30 checks passed
@adm01-debug adm01-debug deleted the fix/batch-admin-magic-runtime-hardening branch May 24, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants