Skip to content

Conversation

@jezweb
Copy link

@jezweb jezweb commented Nov 8, 2025

Summary

Adds visual loading feedback during todo form submission, with specific messaging when images are being uploaded.

Changes

  • Add animated spinner icon to submit button during submission
  • Context-aware loading text:
    • "Creating with image..." → New todo + image upload
    • "Updating with image..." → Edit todo + image upload
    • "Creating..." / "Updating..." → No image
  • Disable cancel button during submission
  • Uses Tailwind animate-spin utility

User Experience

Before: Click submit → button shows "Creating..." → no indication of image upload

After: Click submit with image → spinner appears → "Creating with image..." → clear feedback

Benefits

  • Progress indicator: Spinning icon shows active operation
  • Context awareness: Different messages for image vs. no-image submissions
  • User confidence: Clear feedback during potentially slow R2 uploads
  • Prevents double-submit: Disabled state + visual feedback

Code Quality

  • No external dependencies (uses inline SVG spinner)
  • Conditional rendering based on isPending and imageFile states
  • Consistent with existing form patterns

Testing

  1. Create todo without image → See "Creating..." with spinner
  2. Create todo with image → See "Creating with image..." with spinner
  3. Edit todo with image → See "Updating with image..." with spinner
  4. Verify cancel button disabled during submission

Part of UX improvements to provide better feedback during async operations.

Summary by CodeRabbit

  • Bug Fixes

    • Prevented unintended user actions by disabling the Cancel button while save operations are actively in progress.
  • New Features

    • Enhanced user experience during form submission with dynamic visual feedback including status indicators and contextual messaging that clearly indicates the operation type (create or update) and specifies whether images are being included or processed.

- Add spinning loader icon to submit button during submission
- Show specific text when image is being uploaded:
  - 'Creating with image...' for new todos with images
  - 'Updating with image...' for editing todos with images
  - Generic 'Creating...' / 'Updating...' when no image
- Disable cancel button during submission
- Visual feedback improves UX during potentially slow image uploads

Users now see clear indication that image upload is in progress.
@coderabbitai
Copy link

coderabbitai bot commented Nov 8, 2025

Walkthrough

The todo-form component was enhanced to provide better user feedback during form submission. The Cancel button is now disabled while a save operation is pending, and the submit button displays a spinner with context-aware text indicating the operation type and whether an image is being processed.

Changes

Cohort / File(s) Change Summary
Todo Form UI Enhancements
src/modules/todos/components/todo-form.tsx
Disabled Cancel button during pending state; replaced submit button label with spinner and contextual text that varies by imageFile presence and operation type (Create vs. Update)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Single file with focused UI state management changes
  • Button disable logic and conditional text rendering based on pending state
  • No structural or complex logic modifications

Poem

🐰 A spinner spins, a message true,
"Creating" or "Updating" through and through,
With images or without, the user sees,
Cancel button rests—put the form at ease!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a loading indicator for image uploads in the todo form, which aligns with the core functionality of showing visual feedback during form submission.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

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

Copy link

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

Caution

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

⚠️ Outside diff range comments (1)
src/modules/todos/components/todo-form.tsx (1)

498-505: Consider the implications of disabling the Cancel button.

While preventing accidental navigation during submission is good, users have no way to abort a slow or stuck operation (e.g., large R2 uploads on slow connections). Consider either:

  • Keeping the button enabled but showing a confirmation dialog if clicked during submission
  • Implementing proper cancellation using AbortController
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a44687a and 2f3811d.

📒 Files selected for processing (1)
  • src/modules/todos/components/todo-form.tsx (1 hunks)

Comment on lines 506 to 542
<Button type="submit" disabled={isPending}>
{isPending
? initialData
? "Updating..."
: "Creating..."
: initialData
? "Update Todo"
: "Create Todo"}
{isPending ? (
<span className="flex items-center gap-2">
<svg
className="animate-spin h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
{imageFile
? initialData
? "Updating with image..."
: "Creating with image..."
: initialData
? "Updating..."
: "Creating..."}
</span>
) : initialData ? (
"Update Todo"
) : (
"Create Todo"
)}
</Button>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add accessibility attributes for the loading state.

The spinner lacks ARIA attributes, and screen readers won't announce the state change to users relying on assistive technology.

Apply this diff to improve accessibility:

-                            <Button type="submit" disabled={isPending}>
+                            <Button type="submit" disabled={isPending} aria-live="polite">
                                 {isPending ? (
                                     <span className="flex items-center gap-2">
                                         <svg
                                             className="animate-spin h-4 w-4"
                                             xmlns="http://www.w3.org/2000/svg"
                                             fill="none"
                                             viewBox="0 0 24 24"
+                                            aria-hidden="true"
                                         >

Consider using Loader2 from lucide-react for consistency.

The component already imports icons from lucide-react (Upload, X), but implements a custom SVG spinner. For consistency and maintainability, consider using the Loader2 icon from lucide-react.

-import { Upload, X } from "lucide-react";
+import { Loader2, Upload, X } from "lucide-react";

Then replace the inline SVG:

                                 {isPending ? (
                                     <span className="flex items-center gap-2">
-                                        <svg
-                                            className="animate-spin h-4 w-4"
-                                            xmlns="http://www.w3.org/2000/svg"
-                                            fill="none"
-                                            viewBox="0 0 24 24"
-                                        >
-                                            <circle
-                                                className="opacity-25"
-                                                cx="12"
-                                                cy="12"
-                                                r="10"
-                                                stroke="currentColor"
-                                                strokeWidth="4"
-                                            />
-                                            <path
-                                                className="opacity-75"
-                                                fill="currentColor"
-                                                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
-                                            />
-                                        </svg>
+                                        <Loader2 className="h-4 w-4 animate-spin" aria-hidden="true" />
                                         {imageFile
                                             ? initialData
                                                 ? "Updating with image..."
📝 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
<Button type="submit" disabled={isPending}>
{isPending
? initialData
? "Updating..."
: "Creating..."
: initialData
? "Update Todo"
: "Create Todo"}
{isPending ? (
<span className="flex items-center gap-2">
<svg
className="animate-spin h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
{imageFile
? initialData
? "Updating with image..."
: "Creating with image..."
: initialData
? "Updating..."
: "Creating..."}
</span>
) : initialData ? (
"Update Todo"
) : (
"Create Todo"
)}
</Button>
<Button type="submit" disabled={isPending} aria-live="polite">
{isPending ? (
<span className="flex items-center gap-2">
<svg
className="animate-spin h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
aria-hidden="true"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
{imageFile
? initialData
? "Updating with image..."
: "Creating with image..."
: initialData
? "Updating..."
: "Creating..."}
</span>
) : initialData ? (
"Update Todo"
) : (
"Create Todo"
)}
</Button>
🤖 Prompt for AI Agents
In src/modules/todos/components/todo-form.tsx around lines 506-542, the loading
spinner lacks ARIA attributes and uses a custom inline SVG; update the markup to
improve accessibility and consistency by: 1) set the Button element to reflect
loading (add aria-busy={isPending} and disabled remains), 2) replace the inline
SVG with the imported Loader2 icon from lucide-react and give it
aria-hidden="true" and proper sizing classes, 3) wrap the spinner and label in a
span with role="status" and aria-live="polite" (or include a visually-hidden
text node such as "Loading…" inside) so screen readers are notified, and 4) keep
the visible text logic but ensure the button also has an accessible label when
only an icon is shown. Implement these changes without altering button visuals.

jezweb pushed a commit to jezweb/full-flare-stack that referenced this pull request Nov 8, 2025
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.

1 participant