Skip to content

feat(customization): add settings panel for initial value and step configuration - #3

Open
vidyashreebv wants to merge 2 commits into
feature/counter-componentfrom
refactor/code-quality
Open

vidyashreebv wants to merge 2 commits into
feature/counter-componentfrom
refactor/code-quality

Conversation

@vidyashreebv

Copy link
Copy Markdown
Collaborator

What does this PR do?

  • Adds settings panel UI above the counter with input controls
  • Allows users to customize initial counter value dynamically
  • Allows users to customize step increment/decrement value
  • Implements "Apply" button to restart counter with new settings
  • Uses compact, responsive design that matches counter styling
  • Fixes input fields to allow typing negative values directly

What steps must a reviewer take to test the PR manually?

  1. Checkout refactor/code-quality branch
  2. Run npm install and npm run dev
  3. Test settings panel functionality:
    • Change "Initial Value" to 50
    • Change "Step Value" to 10
    • Click "Apply" button
    • Verify counter starts at 50
    • Click + and verify it increments by 10 (50 → 60 → 70)
    • Click - and verify it decrements by 10
    • Click Reset and verify it goes back to 50
  4. Test with negative values:
    • Set Initial Value to -20
    • Set Step Value to -5
    • Click Apply and verify behavior
  5. Test edge cases (0, large numbers, decimals)
  6. Verify responsive design on mobile/tablet
  7. Check that all tests still pass: npm run test

Screenshots

Screenshot 2026-01-07 at 8 23 36 PM Screenshot 2026-01-07 at 8 23 52 PM

Definition of done Checklist

Code Quality

  • I have written clean, readable code that has been refactored to the best of my ability
  • I have fixed all console warning arising due to my newly added code, ran linting and code formatting on every file
  • I have deleted all non-descriptive comments and dead code from the files I have touched

Testing

  • I have written unit tests for all foundational component files I have worked on, ensuring coverage of what the user sees and how the UI changes with interactions
  • I have tested these changes locally with all possible scenarios

Comment thread src/App.jsx
<input
type="number"
value={initialValue}
onChange={(e) => setInitialValue(Number(e.target.value))}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

use full naming everywhere

Suggested change
onChange={(e) => setInitialValue(Number(e.target.value))}
onChange={(event) => setInitialValue(Number(event.target.value))}

Comment thread src/App.jsx
</div>
<div className="flex items-end">
<button
onClick={handleApply}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
onClick={handleApply}
onClick={handleClickApply}

@Sarath-Kumar-G

Copy link
Copy Markdown
Collaborator

Good work!!

Thanks for the detailed PR description and review guidelines.

I've reviewed all PRs, and here are a few common feedback points:

  • Naming should be descriptive and full namings.
  • Named exports of functions are much recommended.
  • onChange and Click functions should have conventions ex: handleOnChangeCounterLimit, handleClickSubmit
  • Good that you started with testing, we'll have more discussion on unit testing in future.

@ashik-shaji

Copy link
Copy Markdown
Collaborator

@cw-pr-agent review

@mergemitra

mergemitra Bot commented Jan 14, 2026

Copy link
Copy Markdown

Change Summary

This PR adds a settings panel above the counter that lets users configure the counter's initial value and step increment/decrement. It implements state hooks for these settings and an "Apply" button that re-initializes the Counter by updating a key to force remount. It also introduces a centralized theme constants file for design tokens used across the UI.

File Changes

File Summary
src/App.jsx Adds settings panel UI, state hooks for initial/step, Apply button; passes props and key to Counter
src/constants/theme.js Adds theme constants file exporting colors, spacing, shadows, and border-radius tokens

@mergemitra

mergemitra Bot commented Jan 14, 2026

Copy link
Copy Markdown

PR Scorecard

Score

Communication Quality Code Correctness & Design Quality Test Quality & Coverage Code Readability & Maintainability
Scoring Methodology

Communication Scoring Framework

The overall communication score is a weighted average:

Dimension Weight Evaluates
PR Description Quality 60% Title format (conventional commits) + Description clarity (what changed & why)
PR Size & Scope 25% Appropriate sizing, scope cohesion, and justification for size
Commit Messages 15% Conventional commits format, atomic & descriptive changes

Formula: (Description x 0.6) + (PR Size x 0.25) + (Commits x 0.15)

Code Scoring Framework

The scorecard evaluates code using 3 key reviewer questions:

Reviewer Question Category
Is this the right solution, implemented the right way? Code Correctness
Would this catch bugs if the code broke tomorrow? Test Quality
Can someone new understand and safely modify this in 6 months? Maintainability
PR Communication Notes

Description Quality

  • ✅ Title follows conventional commits format with clear scope and descriptive summary
  • ✅ Description provides thorough manual testing steps, screenshots, and a completed checklist
  • ❌ Description omits added file src/constants/theme.js and doesn't explain its purpose
  • ❌ Definition-of-done claims unit tests were added, but no test files changed in this PR
  • ❌ Testing instructions reference branch 'refactor/code-quality' which may not match this PR branch
  • ❌ Inputs use Number(e.target.value) onChange, which can block intermediate values like '-' or empty strings

PR Size & Scope

  • ✅ Small, focused change (2 files, 93 added lines) making scope easy to review
  • ❌ src/constants/theme.js is added but not referenced in App.jsx; clarify or remove this unused file

Commit Messages

  • ✅ All commits follow conventional commits format (feat/settings, fix/settings) and are descriptive

Notes

Code Correctness & Design Quality

  • 🔴 Converting e.target.value with Number() at src/App.jsx:28, src/App.jsx:40 can produce NaN and prevents typing '-', '', or decimals reliably.
  • 🟠 Forcing Counter reset by changing key at src/App.jsx:712 is a remount hack that can unintentionally drop internal state and side effects.

Test Quality & Coverage

  • 🟠 No tests were added for the new settings/apply/reset behavior at src/App.jsx:1558, risking regressions in core user flows.

Code Readability & Maintainability

  • 🟠 Unassociated <label> elements at src/App.jsx:2231, src/App.jsx:3443 reduce accessibility and make inputs harder to use with assistive tech.
  • 💬 Minor [nitpick] Magic default numbers at src/App.jsx:56 reduce clarity; extract them into named constants for easier future changes.
  • 💬 Minor [nitpick] State named key at src/App.jsx:7 is easy to confuse with React element keys and harms readability.
  • 🟠 New theme token module at src/constants/theme.js:140 is unused in this diff, which can add dead code and confuse the styling source of truth.

Comment thread src/App.jsx
import Counter from './components/organisms/Counter/Counter'

function App() {
const [initialValue, setInitialValue] = useState(10)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🔴 Critical
Parsing type="number" input with Number(e.target.value) on every keystroke breaks intermediate states (e.g. -, empty, 1.) and can set NaN; keep draft values as strings and parse/validate on Apply.

Suggested Change:

const DEFAULT_INITIAL_VALUE = 10
const DEFAULT_STEP = 5

const [draftInitialValue, setDraftInitialValue] = useState(String(DEFAULT_INITIAL_VALUE))
const [draftStep, setDraftStep] = useState(String(DEFAULT_STEP))
const [{ initialValue, step }, setCounterSettings] = useState({
  initialValue: DEFAULT_INITIAL_VALUE,
  step: DEFAULT_STEP,
})
const [counterVersion, setCounterVersion] = useState(0)

const handleApply = () => {
  const nextInitialValue = Number(draftInitialValue)
  const nextStep = Number(draftStep)

  if (!Number.isFinite(nextInitialValue) || !Number.isFinite(nextStep)) return

  setCounterSettings({ initialValue: nextInitialValue, step: nextStep })
  setCounterVersion(v => v + 1)
}

// ...
<input
  type="number"
  value={draftInitialValue}
  onChange={(e) => setDraftInitialValue(e.target.value)}
  step="any"
/>
<input
  type="number"
  value={draftStep}
  onChange={(e) => setDraftStep(e.target.value)}
  step="any"
/>

<Counter key={counterVersion} initialValue={initialValue} step={step} />

Comment thread src/App.jsx
<h3 className="text-lg font-bold text-gray-800 mb-3">Counter Settings</h3>
<div className="flex gap-3 flex-wrap">
<div className="flex-1 min-w-[140px]">
<label className="block text-xs font-medium text-gray-700 mb-1">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟠 Major
Associate labels with inputs via htmlFor/id to improve accessibility and click/AT behavior.

Suggested Change:

<label
  htmlFor="initialValue"
  className="block text-xs font-medium text-gray-700 mb-1"
>
  Initial Value
</label>
<input id="initialValue" /* ... */ />

<label
  htmlFor="stepValue"
  className="block text-xs font-medium text-gray-700 mb-1"
>
  Step Value
</label>
<input id="stepValue" /* ... */ />

Comment thread src/App.jsx
function App() {
const [initialValue, setInitialValue] = useState(10)
const [step, setStep] = useState(5)
const [key, setKey] = useState(0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 💬 Minor [nitpick]
Rename the key state to something explicit (e.g. counterVersion) to avoid confusion with React element keys and clarify intent.

Suggested Change:

const [counterVersion, setCounterVersion] = useState(0)

const handleApply = () => {
  setCounterVersion(v => v + 1)
}

<Counter key={counterVersion} initialValue={initialValue} step={step} />

Comment thread src/App.jsx
/>
</div>
<div className="flex items-end">
<button

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 💬 Minor [nitpick]
Add type="button" to prevent accidental form submission if this UI is ever placed inside a <form>.

Suggested Change:

<button type="button" onClick={handleApply}>
  Apply
</button>

Comment thread src/App.jsx
}

return (
<div className="min-h-screen bg-gradient-to-br from-green-50 via-emerald-50 to-teal-50 flex items-center justify-center p-4">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟠 Major
Add RTL tests covering settings changes + Apply + counter +/- + Reset to prevent regressions in the new core user flow.

Suggested Change:

// App.test.jsx (example)
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import App from './App'

test('applies initial value and step, and reset returns to applied initial value', async () => {
  const user = userEvent.setup()
  render(<App />)

  await user.clear(screen.getByLabelText(/initial value/i))
  await user.type(screen.getByLabelText(/initial value/i), '50')
  await user.clear(screen.getByLabelText(/step value/i))
  await user.type(screen.getByLabelText(/step value/i), '10')
  await user.click(screen.getByRole('button', { name: /apply/i }))

  // Assert the displayed count / behavior based on your Counter UI
})

Comment thread src/constants/theme.js
@@ -0,0 +1,40 @@
/**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟠 Major
If theme tokens aren’t being used yet, consider removing this file from the PR; otherwise wire it into App.jsx/Counter to avoid dead code.

Suggested Change:

// Option A: remove this file until used
// Option B: import and use tokens where className strings are duplicated
// import { colors } from './constants/theme'

@mergemitra

mergemitra Bot commented Jan 14, 2026

Copy link
Copy Markdown

PR Overview

PR Type: Feature

Focus Areas for Architect Review

The counter reset is implemented via a remount (key bump); confirm this is acceptable versus adding an explicit reset mechanism in Counter to avoid losing internal state.

The current number input handling should support intermediate typing states (-, empty, decimals); validate UX expectations and consider string draft + parse-on-apply.

No tests were added in the diff for the new settings/apply flow; confirm existing test coverage or request RTL tests that assert visible count changes and reset behavior.

PR Insights

Potential PR Improvements

  • Robustness: Input parsing can produce NaN for empty fields.
  • Best Practices: Remounting components via key can hide state issues.
  • Code Maintainability: Theme constants are added but not yet used.
  • Testing: No new tests are shown for the settings panel.

Strengths

  • Description Quality: Description includes clear manual test steps and edge cases.
  • Code Maintainability: Settings UI is grouped in a clear layout.
  • Correctness: State is wired to inputs and passed as props.
  • Documentation: Theme constants file has a clear header comment.

@vidya-cw vidya-cw added the Closed and Can't merge Changes are made in another branch/PR or directly merging the latest PR label Jan 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Closed and Can't merge Changes are made in another branch/PR or directly merging the latest PR resolved PR comments

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants