Last active 1749835442

lolpee69 revised this gist 1749835442. Go to revision

1 file changed, 203 insertions

reactapp.js(file created)

@@ -0,0 +1,203 @@
1 + /* eslint-disable jsx-a11y/aria-role */
2 + import React, { useState } from "react";
3 +
4 + function App() {
5 + // Default agenda data for testing
6 + const [agenda, setAgenda] = useState([
7 + {
8 + title: "Angular",
9 + description: "Some description about the angular",
10 + topics: ["Introduction", "Typescript", "Why Angular?", "Understanding Versions", "Fundamentals"],
11 + },
12 + {
13 + title: "Vue",
14 + description: "Some description about the vue",
15 + topics: ["Introduction", "Javascript", "Why Vue?", "Vue Bindings", "Component Interaction"],
16 + },
17 + ]);
18 +
19 + const [newTitle, setNewTitle] = useState("");
20 + const [newDescription, setNewDescription] = useState("");
21 + const [newTopic, setNewTopic] = useState("");
22 + const [topics, setTopics] = useState([]);
23 + const [showAddAgenda, setShowAddAgenda] = useState(true);
24 + const [errors, setErrors] = useState({
25 + title: "",
26 + description: "",
27 + topic: "",
28 + });
29 +
30 + // Form validation
31 + const validateTitle = (title) => (title.trim() === "" ? "Title is required" : "");
32 + const validateDescription = (description) => (description.trim() === "" ? "Description is required" : "");
33 + const validateTopic = (topic) => (topic.trim() === "" ? "Topic is required" : "");
34 +
35 + const handleTitleChange = (e) => {
36 + setNewTitle(e.target.value);
37 + setErrors({ ...errors, title: validateTitle(e.target.value) });
38 + };
39 +
40 + const handleDescriptionChange = (e) => {
41 + setNewDescription(e.target.value);
42 + setErrors({ ...errors, description: validateDescription(e.target.value) });
43 + };
44 +
45 + const handleTopicChange = (e) => {
46 + setNewTopic(e.target.value);
47 + setErrors({ ...errors, topic: validateTopic(e.target.value) });
48 + };
49 +
50 + const addTopic = () => {
51 + if (validateTopic(newTopic) === "") {
52 + setTopics([...topics, newTopic.trim()]);
53 + setNewTopic("");
54 + }
55 + };
56 +
57 + const submitAgenda = () => {
58 + if (
59 + validateTitle(newTitle) === "" &&
60 + validateDescription(newDescription) === "" &&
61 + topics.length > 0
62 + ) {
63 + setAgenda([...agenda, { title: newTitle.trim(), description: newDescription.trim(), topics }]);
64 + setNewTitle("");
65 + setNewDescription("");
66 + setTopics([]);
67 + }
68 + };
69 +
70 + return (
71 + <div>
72 + <h1 className="mx-5 mb-5">Agenda Manager</h1>
73 +
74 + {/* Add Agenda Template */}
75 + {showAddAgenda && (
76 + <div className="container" role="addAgenda">
77 + <button className="btn btn-info" role="goToView" onClick={() => setShowAddAgenda(false)}>
78 + Click To View Agenda
79 + </button>
80 + <form>
81 + <div className="my-3">
82 + <label className="form-label">Title</label>
83 + <input
84 + type="text"
85 + placeholder="Enter the title"
86 + className="form-control"
87 + role="inputTitle"
88 + value={newTitle}
89 + onChange={handleTitleChange}
90 + />
91 + <small className="text-danger" data-testid="invalidTitle">
92 + {errors.title}
93 + </small>
94 + </div>
95 +
96 + <div className="my-3">
97 + <label className="form-label">Description</label>
98 + <input
99 + type="text"
100 + placeholder="Enter the description"
101 + className="form-control"
102 + role="inputDescription"
103 + value={newDescription}
104 + onChange={handleDescriptionChange}
105 + />
106 + <small className="text-danger" data-testid="invalidDescription">
107 + {errors.description}
108 + </small>
109 + </div>
110 +
111 + <div className="my-3 w-50">
112 + <label className="form-label">Enter topic</label>
113 + <input
114 + type="text"
115 + placeholder="Enter the topic"
116 + className="form-control"
117 + role="inputTopic"
118 + value={newTopic}
119 + onChange={handleTopicChange}
120 + />
121 + <small className="text-danger" data-testid="invalidTopic">
122 + {errors.topic}
123 + </small>
124 + </div>
125 +
126 + <button
127 + type="button"
128 + className="btn btn-success addAlign"
129 + role="addTopicBtn"
130 + onClick={addTopic}
131 + disabled={validateTopic(newTopic) !== ""}
132 + >
133 + + Add Topic
134 + </button>
135 +
136 + <button
137 + type="button"
138 + className="btn btn-success submitAlign"
139 + role="submitAgendaBtn"
140 + onClick={submitAgenda}
141 + disabled={
142 + validateTitle(newTitle) !== "" || validateDescription(newDescription) !== "" || topics.length === 0
143 + }
144 + >
145 + Submit Agenda
146 + </button>
147 + </form>
148 +
149 + {topics.length === 0 && (
150 + <div className="text-danger ml-2 mt-5" data-testid="noTopicsMsg">
151 + No Topics Added
152 + </div>
153 + )}
154 +
155 + {topics.length > 0 && (
156 + <div className="card my-3">
157 + <div className="card-header">Added Topics</div>
158 + <div className="card-body">
159 + <ul className="list-group">
160 + {topics.map((topic, index) => (
161 + <li className="list-group-item" role="topicList" key={index}>
162 + {topic}
163 + </li>
164 + ))}
165 + </ul>
166 + </div>
167 + <div className="card-footer">Refer the topics you added</div>
168 + </div>
169 + )}
170 + </div>
171 + )}
172 +
173 + {/* View Agenda Template */}
174 + {!showAddAgenda && (
175 + <div className="container" role="viewAgenda">
176 + <button className="btn btn-info" role="goToAdd" onClick={() => setShowAddAgenda(true)}>
177 + Click To Add Agenda
178 + </button>
179 +
180 + {agenda.map((item, index) => (
181 + <div className="card my-3" role="cards" key={index}>
182 + <div className="card-header">{item.title}</div>
183 + <div className="card-body">
184 + <ul className="list-group">
185 + {item.topics.map((topic, idx) => (
186 + <li className="list-group-item" key={idx}>
187 + {topic}
188 + </li>
189 + ))}
190 + </ul>
191 + </div>
192 + <div className="card-footer">{item.description}</div>
193 + </div>
194 + ))}
195 + </div>
196 + )}
197 + </div>
198 + );
199 + }
200 +
201 + export default App;
202 +
203 +
Newer Older