I want to create a counter app. The features are
Click on Add counter button and a new Counter will be added.
Each counter will have separate state management.
Each counter will have increment and decrement buttons.
Increase the value variable of the increment and decrement buttons. (like sometimes 1 or sometimes 5 this way)
Clicking the Reset button will reset all the counters.
At the very first time there will be a counter as the initial state and its initial value will be 0
This app will use only vanilla javascript and redux(import from CDN). I am giving the HTML and I have done some code on it. But can not implement all the features. Can anyone help me out?
# HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Simple Counter Application</title>
<script src="https://cdn.tailwindcss.com"></script>
<!-- import redux from cdn -->
<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>
</head>
<body>
<div class="w-screen h-screen p-10 bg-gray-100 text-slate-700">
<!-- header -->
<h1 class="max-w-md mx-auto text-center text-2xl font-bold">
Simple Counter Application
</h1>
<!-- counters -->
<div class="mx-auto max-w-md mt-10 space-y-5">
<div
class="p-4 my-4 h-auto flex flex-col items-center justify-center space-y-5 bg-white rounded shadow"
id="counterSection"
>
<div id="counter" class="text-2xl font-semibold"></div>
<div class="flex space-x-3">
<button
id="increment"
class="bg-indigo-400 text-white px-3 py-2 rounded shadow"
>
Increment
</button>
<button
id="decrement"
class="bg-red-400 text-white px-3 py-2 rounded shadow"
>
Decrement
</button>
</div>
</div>
<button
id="addCounter"
class="bg-indigo-400 text-white px-3 py-2 rounded shadow"
>
Add Counter
</button>
<button
id="resetCounter"
class="bg-red-400 text-white px-3 py-2 rounded shadow ml-2"
>
Reset
</button>
</div>
<div class="mx-auto max-w-md mt-5 space-y-5" id="newSection"></div>
</div>
<script src="./script.js"></script>
</body>
</html>
Here is the redux code
# script.js
const counterEL = document.getElementById("counter");
const incrementEL = document.getElementById("increment");
const decrementEL = document.getElementById("decrement");
const addCounterEL = document.getElementById("addCounter");
const resetCounterEL = document.getElementById("resetCounter");
function counterSection() {
const oldCounter = document.getElementById("counterSection");
const newCounter = oldCounter.cloneNode(true);
document.getElementById("newSection").append(newCounter);
}
// Action Identifiers
const INCREMENT = "increment";
const DECREMENT = "decrement";
const ADD_COUNTER = "addCounter";
// Action Creators
const increment = (value) => {
return {
type: INCREMENT,
payload: value,
};
};
const decrement = (value) => {
return {
type: DECREMENT,
payload: value,
};
};
const addCounter = (value) => {
return {
type: ADD_COUNTER,
payload: value,
};
};
// Initial State
const initialValue = {
value: 0,
counterValue: 1,
};
// Reducer
function counterReducer(state = initialValue, action) {
if (action.type === INCREMENT) {
return {
...state,
value: state.value + action.payload,
};
} else if (action.type === DECREMENT) {
return {
...state,
value: state.value - action.payload,
};
} else {
return state;
}
}
function addCounterReducer(state = initialValue, action) {
if (action.type === ADD_COUNTER) {
console.log(state.counterValue);
return {
...state,
newCountervalue: state.counterValue + action.payload,
};
}
}
// Store
const store1 = Redux.createStore(counterReducer);
const store2 = Redux.createStore(addCounterReducer);
// Update UI
const render1 = () => {
const stateCounter = store1.getState();
counterEL.innerText = stateCounter.value.toString();
incrementEL.innerText = `Increment +${stateCounter.counterValue.toString()}`;
decrementEL.innerText = `Decrement -${stateCounter.counterValue.toString()}`;
};
const render2 = () => {
const stateCounter = store1.getState();
counterEL.innerText = stateCounter.counterValue.toString();
incrementEL.innerText = `Increment +${stateCounter.counterValue.toString()}`;
decrementEL.innerText = `Decrement -${stateCounter.counterValue.toString()}`;
};
render1();
store1.subscribe(render1);
store2.subscribe(render2);
// Functionality
incrementEL.addEventListener("click", () => {
store1.dispatch(increment(1));
});
decrementEL.addEventListener("click", () => {
store1.dispatch(decrement(1));
});
addCounterEL.addEventListener("click", () => {
store2.dispatch(addCounter(1));
counterSection();
});