Created
September 28, 2025 15:03
-
-
Save HarshalRathore/762ae1fac8c91f4d445fbb982bb42ba7 to your computer and use it in GitHub Desktop.
React Agenda Manager App.js for ievolve 62636 Assessment - Full Code with Topics and Agenda Management
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* eslint-disable jsx-a11y/aria-role */ | |
| import React, { useState } from "react"; | |
| function App() { | |
| /** | |
| * keep this following data as default data in agenda details as it is required for testing | |
| * [ | |
| { | |
| title: "Angular", | |
| description: "Some description about the angular", | |
| topics: ["Introduction", "Typescript", "Why Angular?", "Understanding Versions", "Fundamentals"] | |
| }, | |
| { | |
| title: "Vue", | |
| description: "Some description about the vue", | |
| topics: ["Introduction", "Javascript", "Why Vue?", "Vue Bindings", "Component Interaction"] | |
| }, | |
| ], | |
| */ | |
| // your data goes here (state) | |
| const [newTitle, setnewTitle] = useState(''); | |
| const [newDescription, setnewDescription] = useState(''); | |
| const [newTopic, setnewTopic] = useState(''); | |
| const [addedTopic, setaddedTopic] = useState([]); | |
| const [showAgendaBlock, setshowAgendaBlock] = useState(false); | |
| const [addedAgenda, setaddedAgenda] = useState([ | |
| { | |
| title: "Angular", | |
| description: "Some description about the angular", | |
| topics: ["Introduction", "Typescript", "Why Angular?", "Understanding Versions", "Fundamentals"] | |
| }, | |
| { | |
| title: "Vue", | |
| description: "Some description about the vue", | |
| topics: ["Introduction", "Javascript", "Why Vue?", "Vue Bindings", "Component Interaction"] | |
| }, | |
| ]); | |
| // your methods goes here | |
| const handleChangeFn = (e) => { | |
| const value = e.target.value; | |
| const name = e.target.name; | |
| if (name === 'newTitle') { | |
| setnewTitle(value); | |
| } else if (name === 'newDescription') { | |
| setnewDescription(value); | |
| } else if (name === 'newTopic') { | |
| setnewTopic(value); | |
| } | |
| } | |
| const addTopicFn = (e) => { | |
| e.preventDefault(); | |
| setaddedTopic(addedTopic.concat(newTopic)); | |
| setnewTopic(""); | |
| } | |
| const addAgendaFn = (e) => { | |
| e.preventDefault(); | |
| var agenda = { | |
| title: newTitle, | |
| description: newDescription, | |
| topics: addedTopic | |
| } | |
| setnewTitle(""); | |
| setnewDescription(""); | |
| setnewTopic(""); | |
| setaddedTopic([]); | |
| setaddedAgenda(addedAgenda.concat(agenda)); | |
| } | |
| const preventSubmit = (e) => { | |
| e.preventDefault(); | |
| } | |
| const showAgendaBlockFn = (e) => { | |
| showAgendaBlock === false ? setshowAgendaBlock(true) : setshowAgendaBlock(false); | |
| } | |
| return ( | |
| <div> | |
| <h1 className="mx-5 mb-5">Agenda Manager</h1> | |
| {/* show/hide this following add agenda template */} | |
| {!showAgendaBlock && | |
| <div className="container" role="addAgenda"> | |
| <button className="btn btn-info" role="goToView" onClick={showAgendaBlockFn}> | |
| Click To View Agenda | |
| </button> | |
| <form onSubmit={preventSubmit}> | |
| <div className="my-3"> | |
| <label className="form-label">Title</label> | |
| {/* title */} | |
| <input | |
| type="text" | |
| name="newTitle" | |
| placeholder="Enter the title" | |
| className="form-control" | |
| role="inputTitle" | |
| value={newTitle} onChange={handleChangeFn} | |
| /> | |
| <small className="text-danger" data-testid="invalidTitle"> | |
| {newTitle.trim().length === 0 ? "Title is required" : ""} | |
| </small> | |
| </div> | |
| <div className="my-3"> | |
| <label className="form-label">Description</label> | |
| {/* description */} | |
| <input | |
| type="text" | |
| name="newDescription" | |
| placeholder="Enter the description" | |
| className="form-control" | |
| role="inputDescription" | |
| value={newDescription} onChange={handleChangeFn} | |
| /> | |
| <small className="text-danger" data-testid="invalidDescription"> | |
| {newDescription.trim().length === 0 ? "Description is required" : ""} | |
| </small> | |
| </div> | |
| <div className="my-3 w-50"> | |
| <label className="form-label">Enter topic</label> | |
| {/* topic */} | |
| <input | |
| type="text" | |
| name="newTopic" | |
| placeholder="Enter the topic" | |
| className="form-control" | |
| role="inputTopic" | |
| value={newTopic} onChange={handleChangeFn} | |
| /> | |
| <small className="text-danger" data-testid="invalidTopic"> | |
| {newTopic.trim().length === 0 && addedTopic.length === 0 ? "Topic is required" : ""} | |
| </small> | |
| </div> | |
| {/* on click should add topics and disable the button if invalid topic */} | |
| <button className="btn btn-success addAlign" role="addTopicBtn" onClick={addTopicFn} disabled={newTopic.trim().length === 0}> | |
| + Add Topic | |
| </button> | |
| {/* on click should add agenda details and disable the button if invalid inputs */} | |
| <button | |
| className="btn btn-success submitAlign" | |
| role="submitAgendaBtn" | |
| onClick={addAgendaFn} | |
| disabled={newTitle.trim().length === 0 || newDescription.trim().length === 0 || addedTopic.length === 0} | |
| > | |
| Submit Agenda | |
| </button> | |
| </form> | |
| {/* show if no topics added yet */} | |
| {addedTopic.length === 0 && | |
| <div className="text-danger ml-2 mt-5" data-testid="noTopicsMsg"> | |
| No Topics Added | |
| </div>} | |
| {/* display the list of topics added using li */} | |
| {addedTopic.length !== 0 && | |
| <div className="card my-3"> | |
| <div className="card-header">Added Topics</div> | |
| <div className="card-body"> | |
| <ul className="list-group"> | |
| {addedTopic.map((topic) => ( | |
| <li className="list-group-item" role="topicList" key={topic}> | |
| {topic} | |
| </li> | |
| ))} | |
| {/* topics list */} | |
| </ul> | |
| </div> | |
| <div className="card-footer">Refer the topics you added</div> | |
| </div>} | |
| </div>} | |
| {/* show/hide this following view agenda template */} | |
| {showAgendaBlock && | |
| <div className="container" role="viewAgenda"> | |
| <button className="btn btn-info" role="goToAdd" onClick={showAgendaBlockFn}> | |
| Click To Add Agenda | |
| </button> | |
| {/* iterate the agenda details to display */} | |
| {addedAgenda.map((agenda) => ( | |
| <div className="card my-3" role="cards" key={agenda.title}> | |
| <div className="card-header">{agenda.title}</div> | |
| <div className="card-body"> | |
| <ul className="list-group"> | |
| {/* iterate the topics to display */} | |
| {agenda.topics.map((topic) => ( | |
| <li className="list-group-item" key={topic}> | |
| {topic} | |
| {/* {topic} */} | |
| </li> | |
| ))} | |
| </ul> | |
| </div> | |
| <div className="card-footer">{agenda.description}</div> | |
| </div> | |
| ))} | |
| </div>} | |
| </div> | |
| ); | |
| } | |
| export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment