Add counter example; fix configuration
This commit is contained in:
42
examples/accident-counter/src/counter.tsx
Normal file
42
examples/accident-counter/src/counter.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import React, { useReducer, useEffect } from 'react';
|
||||
import { reducer } from './reducer';
|
||||
|
||||
export const Counter = () => {
|
||||
const [state, dispatch] = useReducer(reducer, { count: 0 });
|
||||
const unit = state.count === 1 ? 'day' : 'days';
|
||||
|
||||
useEffect(() => {
|
||||
window.document.title = `${state.count} ${unit}`;
|
||||
}, [state.count]);
|
||||
|
||||
return (
|
||||
<div className="p-8 space-y-8 text-center bg-white border rounded-md shadow-lg border-slate-400">
|
||||
<div className="space-y-4">
|
||||
<div data-test-id="counter-count" className="font-semibold text-8xl">
|
||||
{state.count}
|
||||
</div>
|
||||
<p>
|
||||
<span data-test-id="counter-unit">{unit}</span> since the last
|
||||
accident.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<button onClick={() => dispatch({ type: 'increment' })}>
|
||||
Increment
|
||||
</button>
|
||||
<button
|
||||
onClick={() => dispatch({ type: 'decrement' })}
|
||||
disabled={state.count === 0}
|
||||
>
|
||||
Decrement
|
||||
</button>
|
||||
<button
|
||||
onClick={() => dispatch({ type: 'reset' })}
|
||||
disabled={state.count === 0}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
29
examples/accident-counter/src/reducer.test.js
Normal file
29
examples/accident-counter/src/reducer.test.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { reducer } from './reducer';
|
||||
|
||||
describe('reducer', () => {
|
||||
it('should return the initial state', () => {
|
||||
const initialState = { count: 0 };
|
||||
expect(reducer()).toEqual(initialState);
|
||||
});
|
||||
|
||||
it('should handle decrement action', () => {
|
||||
const initialState = { count: 0 };
|
||||
const action = { type: 'increment' };
|
||||
const expectedState = { count: 1 };
|
||||
expect(reducer(initialState, action)).toEqual(expectedState);
|
||||
});
|
||||
|
||||
it('should handle increment action', () => {
|
||||
const initialState = { count: 1 };
|
||||
const action = { type: 'decrement' };
|
||||
const expectedState = { count: 0 };
|
||||
expect(reducer(initialState, action)).toEqual(expectedState);
|
||||
});
|
||||
|
||||
it('should handle unknown action', () => {
|
||||
const initialState = { count: 0 };
|
||||
const action = { type: 'UNKNOWN' };
|
||||
expect(reducer(initialState, action)).toEqual(initialState);
|
||||
});
|
||||
});
|
||||
29
examples/accident-counter/src/reducer.ts
Normal file
29
examples/accident-counter/src/reducer.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
type CounterState = {
|
||||
count: number;
|
||||
};
|
||||
|
||||
type CounterAction =
|
||||
| { type: 'increment' }
|
||||
| { type: 'decrement' }
|
||||
| { type: 'reset' };
|
||||
|
||||
export function reducer(
|
||||
state: CounterState = { count: 0 },
|
||||
action: CounterAction,
|
||||
): CounterState {
|
||||
if (!action) return state;
|
||||
|
||||
switch (action.type) {
|
||||
case 'increment':
|
||||
return { count: state.count + 1 };
|
||||
case 'decrement':
|
||||
if (state.count > 0) {
|
||||
return { count: state.count - 1 };
|
||||
}
|
||||
return { count: 0 };
|
||||
case 'reset':
|
||||
return { count: 0 };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user