Skip to content

Fix broken validation in delete-project-dialog#780

Open
delta6626 wants to merge 3 commits intoOpenCut-app:mainfrom
delta6626:main
Open

Fix broken validation in delete-project-dialog#780
delta6626 wants to merge 3 commits intoOpenCut-app:mainfrom
delta6626:main

Conversation

@delta6626
Copy link
Copy Markdown

@delta6626 delta6626 commented May 1, 2026

Fixes #724

Changes made

  1. Added a new state variable to track the value of the confirmation input
  2. Introduced a constant for the required confirmation text
  3. Disabled the delete button until the input matches that constant
  4. Updated the input placeholder and label to use the required text instead of hardcoded strings

Summary by CodeRabbit

  • New Features
    • Project deletion now requires users to type a confirmation phrase before proceeding.
    • The delete button remains disabled until the entered text exactly matches the required confirmation, reducing accidental deletions.
    • Confirmation prompt and input placeholder were clarified to guide users on the exact text to enter.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 1, 2026

@delta6626 is attempting to deploy a commit to the OpenCut OSS Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

The delete-project dialog now requires the user to type an exact confirmation string before enabling deletion. A REQUIRED_CONFIRMATION_TEXT constant was added, the input was converted to a controlled confirmationInput state, and the destructive delete button is disabled until the input matches the constant.

Changes

Delete Confirmation Validation

Layer / File(s) Summary
Data Shape / Constants
apps/web/src/project/components/delete-project-dialog.tsx
Adds REQUIRED_CONFIRMATION_TEXT constant used in the prompt and placeholder.
State
apps/web/src/project/components/delete-project-dialog.tsx
Introduces confirmationInput via useState<string>("") to capture typed confirmation.
UI / Wiring
apps/web/src/project/components/delete-project-dialog.tsx
Makes the confirmation Input controlled (value={confirmationInput}, onChange updates state) and sets placeholder to REQUIRED_CONFIRMATION_TEXT.
Behavior / Guard
apps/web/src/project/components/delete-project-dialog.tsx
Disables the destructive “Delete project” button unless confirmationInput === REQUIRED_CONFIRMATION_TEXT.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • simonorzel26

Poem

🐰 I nibble keys with gentle paws,
Now deletions need exacting laws.
Type the word, make no mistake,
Only then may projects break. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description includes 'Fixes #724' and lists specific changes made, but does not follow the template structure with required checkboxes for bug fixes. Add the required template checkbox indicating this is a bug fix and that it was approved by a maintainer.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix broken validation in delete-project-dialog' is specific and accurately summarizes the main change of adding proper confirmation validation to the delete dialog component.
Linked Issues check ✅ Passed All three requirements from issue #724 are met: confirmation input is now a controlled component, delete button is disabled until 'DELETE' is typed, and validation prevents deletion without confirmation.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the delete-project-dialog validation as specified in issue #724; no out-of-scope modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with 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.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

Copy link
Copy Markdown
Contributor

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/project/components/delete-project-dialog.tsx`:
- Line 84: Replace the loose inequality with a strict one: in the JSX where the
Button's disabled prop compares confirmationInput to REQUIRED_CONFIRMATION_TEXT
(the expression inside the Button with onClick={onConfirm}), change the operator
from != to !== so the check uses strict inequality and avoids type-coercion.
- Around line 67-77: The Label and Input are not programmatically associated;
add a unique id (e.g., "confirmation-input") to the Input component and set the
Label's htmlFor to that id so screen readers and click-to-focus work properly;
update the JSX around Label and Input (the components rendering the confirmation
field using REQUIRED_CONFIRMATION_TEXT, confirmationInput, and
setConfirmationInput) to include the matching id/htmlFor attributes.
- Around line 32-35: The dialog's confirmationInput state (confirmationInput,
setConfirmationInput) is not reset when the Dialog (Dialog component using
isOpen and onOpenChange) closes, so reopening bypasses the "DELETE" guard; fix
by wrapping the passed onOpenChange with a local handler (e.g.,
handleOpenChange) that calls setConfirmationInput("") whenever open becomes
false and then forwards the event to the original onOpenChange prop, and pass
that handler into Dialog's onOpenChange.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 981b72af-980c-484c-9f38-007b79c130b7

📥 Commits

Reviewing files that changed from the base of the PR and between 6ec818f and 89677d9.

📒 Files selected for processing (1)
  • apps/web/src/project/components/delete-project-dialog.tsx

Comment on lines +32 to 35
const [confirmationInput, setConfirmationInput] = useState<string>("");

return (
<Dialog open={isOpen} onOpenChange={onOpenChange}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

confirmationInput is never reset when the dialog closes — the confirmation guard is bypassed on re-use.

When the dialog is closed (via Cancel, backdrop click, or Escape) and then reopened, confirmationInput retains its previous value. If the user previously typed "DELETE" and confirmed a deletion, the state still holds "DELETE" when the dialog opens for the next project, causing the delete button to be immediately enabled and completely bypassing the guard.

The fix is to intercept onOpenChange locally and reset the state whenever the dialog transitions to closed:

🛡️ Proposed fix
  const [confirmationInput, setConfirmationInput] = useState<string>("");
+
+  const handleOpenChange = (open: boolean) => {
+    if (!open) setConfirmationInput("");
+    onOpenChange(open);
+  };

  return (
-   <Dialog open={isOpen} onOpenChange={onOpenChange}>
+   <Dialog open={isOpen} onOpenChange={handleOpenChange}>
      ...
-         <Button variant="outline" onClick={() => onOpenChange(false)}>
+         <Button variant="outline" onClick={() => handleOpenChange(false)}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/project/components/delete-project-dialog.tsx` around lines 32 -
35, The dialog's confirmationInput state (confirmationInput,
setConfirmationInput) is not reset when the Dialog (Dialog component using
isOpen and onOpenChange) closes, so reopening bypasses the "DELETE" guard; fix
by wrapping the passed onOpenChange with a local handler (e.g.,
handleOpenChange) that calls setConfirmationInput("") whenever open becomes
false and then forwards the event to the original onOpenChange prop, and pass
that handler into Dialog's onOpenChange.

Comment thread apps/web/src/project/components/delete-project-dialog.tsx Outdated
Comment thread apps/web/src/project/components/delete-project-dialog.tsx Outdated
Copy link
Copy Markdown
Contributor

@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.

♻️ Duplicate comments (1)
apps/web/src/project/components/delete-project-dialog.tsx (1)

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

confirmationInput is still not reset when the dialog closes — delete guard is bypassed on re-use.

The previously flagged fix has not been applied. onOpenChange is forwarded directly to <Dialog> (line 35) and the Cancel button (line 82), so confirmationInput retains "DELETE" after a successful deletion. The next time the dialog opens the button is immediately enabled, completely defeating the guard.

🛡️ Proposed fix
  const [confirmationInput, setConfirmationInput] = useState<string>("");

+ const handleOpenChange = (open: boolean) => {
+   if (!open) setConfirmationInput("");
+   onOpenChange(open);
+ };

  return (
-   <Dialog open={isOpen} onOpenChange={onOpenChange}>
+   <Dialog open={isOpen} onOpenChange={handleOpenChange}>
      ...
-         <Button variant="outline" onClick={() => onOpenChange(false)}>
+         <Button variant="outline" onClick={() => handleOpenChange(false)}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/project/components/delete-project-dialog.tsx` around lines 32 -
35, confirmationInput is not cleared when the dialog closes so the delete guard
is bypassed on reopen; fix it by resetting confirmationInput whenever the dialog
is closed — either add a useEffect that watches isOpen and calls
setConfirmationInput("") when isOpen becomes false, or wrap the onOpenChange
prop passed to <Dialog> with a handler that calls setConfirmationInput("")
before delegating to the original onOpenChange; also ensure the Cancel button’s
handler similarly clears confirmationInput (reference confirmationInput,
setConfirmationInput, onOpenChange, <Dialog>, and the Cancel button handler).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@apps/web/src/project/components/delete-project-dialog.tsx`:
- Around line 32-35: confirmationInput is not cleared when the dialog closes so
the delete guard is bypassed on reopen; fix it by resetting confirmationInput
whenever the dialog is closed — either add a useEffect that watches isOpen and
calls setConfirmationInput("") when isOpen becomes false, or wrap the
onOpenChange prop passed to <Dialog> with a handler that calls
setConfirmationInput("") before delegating to the original onOpenChange; also
ensure the Cancel button’s handler similarly clears confirmationInput (reference
confirmationInput, setConfirmationInput, onOpenChange, <Dialog>, and the Cancel
button handler).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8336beab-a863-492f-89c0-e61f7d905c38

📥 Commits

Reviewing files that changed from the base of the PR and between 89677d9 and ac9216d.

📒 Files selected for processing (1)
  • apps/web/src/project/components/delete-project-dialog.tsx

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.

[BUG] Delete project dialog validation is broken - can delete without typing DELETE

1 participant