diff --git a/.gitignore b/.gitignore
index e43b0f9..d7010f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,6 @@
.DS_Store
+
+node_modules
+
+/coverage/
+
diff --git a/src/App.css b/src/App.css
index 74b5e05..00d9bec 100644
--- a/src/App.css
+++ b/src/App.css
@@ -2,37 +2,13 @@
text-align: center;
}
-.App-logo {
- height: 40vmin;
- pointer-events: none;
+table {
+ margin: 4rem auto;
}
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
+table,
+th,
+td {
+ border: 1px solid black;
}
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
-}
-
-@keyframes App-logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
diff --git a/src/App.js b/src/App.js
index 3784575..e3838a0 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,23 +1,17 @@
-import logo from './logo.svg';
-import './App.css';
+import "./App.css";
+import { useReducer } from "react";
+import tableReducer, { initialState } from "./reducer/table.reducer";
+import Header from "./components/Header";
+import Form from "./components/Form";
+import Table from "./components/Table";
function App() {
+ const [state, dispatch] = useReducer(tableReducer, initialState);
return (
);
}
diff --git a/src/App.test.js b/src/App.test.js
index 1f03afe..1923bf3 100644
--- a/src/App.test.js
+++ b/src/App.test.js
@@ -3,6 +3,6 @@ import App from './App';
test('renders learn react link', () => {
render();
- const linkElement = screen.getByText(/learn react/i);
- expect(linkElement).toBeInTheDocument();
+ const titleElement = screen.getByText(/React Sample Application/i);
+ expect(titleElement).toBeInTheDocument();
});
diff --git a/src/components/Form.js b/src/components/Form.js
new file mode 100644
index 0000000..a3bb3f5
--- /dev/null
+++ b/src/components/Form.js
@@ -0,0 +1,44 @@
+import { useState } from "react";
+import { v4 as uuidv4 } from "uuid";
+
+const Form = ({dispatch}) => {
+ const initialObj = {
+ id: uuidv4(),
+ name: "",
+ role: "",
+ }
+ const [contributorObj, setContributorObj] = useState(initialObj);
+ return(
+
+
Form
+
+ setContributorObj({ ...contributorObj, name: e.target.value })
+ }
+ />
+
+ setContributorObj({ ...contributorObj, role: e.target.value })
+ }
+ />
+
+
+ )
+}
+
+
+export default Form
diff --git a/src/components/Header.js b/src/components/Header.js
new file mode 100644
index 0000000..20ec67a
--- /dev/null
+++ b/src/components/Header.js
@@ -0,0 +1,6 @@
+const Header = () => {
+ return
+ React Sample Application
+ ;
+}
+export default Header
\ No newline at end of file
diff --git a/src/components/Table.js b/src/components/Table.js
new file mode 100644
index 0000000..afb5c10
--- /dev/null
+++ b/src/components/Table.js
@@ -0,0 +1,37 @@
+const Table = ({ state, dispatch }) => {
+ return (
+
+
+
+ | Name |
+ Role |
+
+
+
+ {state.members?.map((contributor) => {
+ return (
+
+ | {contributor.name} |
+ {contributor.role} |
+
+
+ |
+
+ );
+ })}
+
+
+ );
+};
+
+export default Table;
+
diff --git a/src/reducer/table.reducer.js b/src/reducer/table.reducer.js
new file mode 100644
index 0000000..69f3b52
--- /dev/null
+++ b/src/reducer/table.reducer.js
@@ -0,0 +1,31 @@
+export const initialState = {
+ members: [
+ { id: 1234, name: "Jessica Adams", role: "Community Engineer" },
+ ],
+ totalMembers: 1,
+ };
+
+const tableReducer = (state = initialState, action) => {
+ switch(action.type){
+ case "ADD_MEMBER" :
+ return {
+ ...state,
+ members: [...state.members, action.payload.member],
+ totalMembers: state.totalMembers+1
+ };
+
+ case "REMOVE_MEMBER" :
+ const updatedMembersList = state.members.filter((memberObj) => memberObj.id !== action.payload.member.id )
+ return {
+ ...state,
+ members: [...updatedMembersList],
+ totalMembers: state.totalMembers - 1
+ };
+
+ default :
+ break;
+ }
+}
+
+
+export default tableReducer
\ No newline at end of file
diff --git a/src/reducer/table.reducer.test.js b/src/reducer/table.reducer.test.js
new file mode 100644
index 0000000..23355fe
--- /dev/null
+++ b/src/reducer/table.reducer.test.js
@@ -0,0 +1,75 @@
+import tableReducer from "./table.reducer";
+
+describe("testing reducer", () => {
+ test("ADD_MEMBER", () => {
+ const initialState = {
+ members: [
+ { id: 1234, name: "Jessica Adams", role: "Community Engineer" },
+ ],
+ totalMembers: 1,
+ };
+
+ const action = {
+ type: "ADD_MEMBER",
+ payload: {
+ member: {
+ id: 1235,
+ name: "Ompragash Vishwanathan",
+ role: "Senior Software Engineer",
+ },
+ },
+ };
+
+ const expectedState = {
+ members: [
+ { id: 1234, name: "Jessica Adams", role: "Community Engineer" },{
+ id: 1235,
+ name: "Ompragash Vishwanathan",
+ role: "Senior Software Engineer",
+ }
+ ],
+ totalMembers: 2,
+ };
+
+ const state = tableReducer(initialState, action)
+ expect(state).toEqual(expectedState)
+ });
+
+
+ test("REMOVE_MEMBER", () => {
+ const initialState = {
+ members: [
+ { id: 1234, name: "Jessica Adams", role: "Community Engineer" },
+ { id: 1235, name: "Ompragash Vishwanathan", role: "Senior Software Engineer" },
+ { id: 1236, name: "Pravin Mali", role: "Community Engineer Manager" },
+ { id: 1237, name: "Alex Garg", role: "Community Engineer" },
+ ],
+ totalMembers: 4,
+ };
+
+ const action = {
+ type: "REMOVE_MEMBER",
+ payload: {
+ member: {
+ id: 1237,
+ name: "Alex Garg",
+ role: "Community Engineer",
+ },
+ },
+ };
+
+ const expectedState = {
+ members: [
+ { id: 1234, name: "Jessica Adams", role: "Community Engineer" },
+ { id: 1235, name: "Ompragash Vishwanathan", role: "Senior Software Engineer" },
+ { id: 1236, name: "Pravin Mali", role: "Community Engineer Manager" }
+ ],
+ totalMembers: 3,
+ };
+
+ const state = tableReducer(initialState, action)
+ expect(state).toEqual(expectedState)
+
+ })
+});
+