lolpee69 revised this gist . Go to revision
1 file changed, 131 insertions, 91 deletions
app.js
@@ -1,92 +1,132 @@ | |||
1 | - | import React, { Component } from 1 react1; | |
2 | - | import "./App.css" | |
3 | - | class Home extends Component { | |
4 | - | url = "http://localhost:8001/courses/" | |
5 | - | state = { | |
6 | - | show: false, | |
7 | - | data:[], | |
8 | - | rating: | |
1 | + | import axios from "axios"; | |
2 | + | import React, { useEffect, useState } from "react"; | |
3 | + | import "./App.css"; | |
4 | + | ||
5 | + | function Home() { | |
6 | + | const [data, setData] = useState([]); | |
7 | + | const [rating, setRating] = useState(1); | |
8 | + | const [refresh, setRefresh] = useState(false); // To trigger re-render on data changes | |
9 | + | ||
10 | + | // Fetch course data | |
11 | + | useEffect(() => { | |
12 | + | const fetchData = async () => { | |
13 | + | const response = await axios.get("http://localhost:8001/courses/get"); | |
14 | + | setData(response.data); | |
15 | + | }; | |
16 | + | fetchData(); | |
17 | + | }, [refresh]); | |
18 | + | ||
19 | + | // Apply for a course | |
20 | + | const handleApply = async (id) => { | |
21 | + | try { | |
22 | + | const response = await axios.post(`http://localhost:8001/courses/enroll/${id}`); | |
23 | + | alert("You have successfully enrolled for this course"); | |
24 | + | setRefresh(!refresh); // Refresh data after applying | |
25 | + | } catch (error) { | |
26 | + | alert("Error applying for the course"); | |
27 | + | } | |
28 | + | }; | |
29 | + | ||
30 | + | // Update rating state on change | |
31 | + | const handleRating = (event) => { | |
32 | + | setRating(event.target.value); | |
33 | + | }; | |
34 | + | ||
35 | + | // Add a rating to a course | |
36 | + | const handleAddRating = async (id) => { | |
37 | + | try { | |
38 | + | await axios.patch(`http://localhost:8001/courses/rating/${id}`, { rating: Number(rating)}); | |
39 | + | ||
40 | + | setRefresh(!refresh); // Refresh data after rating | |
41 | + | } catch (error) { | |
42 | + | alert("Error adding rating"); | |
43 | + | } | |
44 | + | }; | |
45 | + | ||
46 | + | // Drop a course | |
47 | + | const handleDrop = async (id) => { | |
48 | + | try { | |
49 | + | await axios.delete(`http://localhost:8001/courses/drop/${id}`); | |
50 | + | setRefresh(!refresh); // Refresh data after dropping | |
51 | + | } catch (error) { | |
52 | + | alert("Error dropping the course"); | |
53 | + | } | |
54 | + | }; | |
55 | + | ||
56 | + | return ( | |
57 | + | <div className="home"> | |
58 | + | <header> | |
59 | + | <h2>ABC Learning</h2> | |
60 | + | </header> | |
61 | + | <div className="cardContainer"> | |
62 | + | {data.map((course) => ( | |
63 | + | <div className="card" key={course._id}> | |
64 | + | <ul> | |
65 | + | <div className="header"> | |
66 | + | {/* Render course details */} | |
67 | + | <li data-testid="course-name">{course.courseName}</li> | |
68 | + | <li data-testid="course-dept">{course.courseDept}</li> | |
69 | + | <li data-testid="course-description">{course.description}</li> | |
70 | + | ||
71 | + | {/* Rating functionality */} | |
72 | + | <li> | |
73 | + | <> | |
74 | + | Rate: | |
75 | + | <select | |
76 | + | className="rating" | |
77 | + | name="rating" | |
78 | + | data-testid="select-box" | |
79 | + | value={rating} | |
80 | + | onChange={handleRating} | |
81 | + | > | |
82 | + | <option value="1">1</option> | |
83 | + | <option value="2">2</option> | |
84 | + | <option value="3">3</option> | |
85 | + | <option value="4">4</option> | |
86 | + | <option value="5">5</option> | |
87 | + | </select> | |
88 | + | <button | |
89 | + | className="rate" | |
90 | + | data-testid="add-rate" | |
91 | + | onClick={() => handleAddRating(course._id)} | |
92 | + | > | |
93 | + | Add | |
94 | + | </button> | |
95 | + | </> | |
96 | + | </li> | |
97 | + | ||
98 | + | {/* Drop course button */} | |
99 | + | <li> | |
100 | + | <button | |
101 | + | className="drop" | |
102 | + | data-testid="drop" | |
103 | + | onClick={() => handleDrop(course._id)} | |
104 | + | > | |
105 | + | Drop Course | |
106 | + | </button> | |
107 | + | </li> | |
108 | + | ||
109 | + | {/* Apply button */} | |
110 | + | <li> | |
111 | + | <button | |
112 | + | className="btn" | |
113 | + | data-testid="apply" | |
114 | + | onClick={() => handleApply(course._id)} | |
115 | + | > | |
116 | + | Apply | |
117 | + | </button> | |
118 | + | </li> | |
119 | + | </div> | |
120 | + | <div className="footer"> | |
121 | + | {/* Footer contents can go here */} | |
122 | + | <li data-testid="footer">Course Footer</li> | |
123 | + | </div> | |
124 | + | </ul> | |
125 | + | </div> | |
126 | + | ))} | |
127 | + | </div> | |
128 | + | </div> | |
129 | + | ); | |
9 | 130 | } | |
10 | - | componentDidMount = () => { | |
11 | - | this.handleGetData() | |
12 | - | } | |
13 | - | handleGetData = () => { | |
14 | - | fetch(this.url + "get") | |
15 | - | .then((res) => res.json()) | |
16 | - | .then((json) => { | |
17 | - | this.setState({ data: json }) | |
18 | - | }) | |
19 | - | } | |
20 | - | handleApply = async (id) => { | |
21 | - | const requestoption = { | |
22 | - | method: ’post1, | |
23 | - | headers: { ’Content-Type1: 1 application/json’ } | |
24 | - | }; | |
25 | - | fetch(this.url + 'enroll/' + id, requestoption) •then(() => { | |
26 | - | this.handleGetData() | |
27 | - | }) | |
28 | - | }; | |
29 | - | handleRating = (e) => { | |
30 | - | this.setState({ rating: e.target.value }) | |
31 | - | } | |
32 | - | handleAddRating = async (id) => { | |
33 | - | const requestoption = { | |
34 | - | method: 'PATCH', | |
35 | - | headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rating: this.state.rating }) } | |
36 | - | fetch(this.url + "rating/" + id, requestoption) | |
37 | - | •then(() => { | |
38 | - | this.handleGetData() | |
39 | - | }) | |
40 | - | } | |
41 | - | handleDrop = async (id) => { | |
42 | - | const requestoption = { | |
43 | - | method: 'DELETE', | |
44 | - | headers: { 'Content-Type': 'application/json' }, | |
45 | - | }; | |
46 | - | fetch(this.url + "drop/" + id, requestoption) | |
47 | - | •then(() => { | |
48 | - | this.handleGetData() | |
49 | - | }) | |
50 | - | } | |
51 | - | render() { | |
52 | - | return ( | |
53 | - | <div className="home"> | |
54 | - | <header> | |
55 | - | <h2>ABC Learning</h2> | |
56 | - | </header> | |
57 | - | <div className="cardContainer"> | |
58 | - | {this.state.data.map(courses => { return ( | |
59 | - | <div className="card"> | |
60 | - | <ul> | |
61 | - | <div className="header"> | |
62 | - | <li>{courses.courseName}</li> | |
63 | - | <li>{courses.courseDept}</li> | |
64 | - | <li>{courses.description}</li> | |
65 | - | {courses.isApplied && | |
66 | - | <li> | |
67 | - | {!courses.isRated && | |
68 | - | <li>Rate: | |
69 | - | <select | |
70 | - | className="rating" name="rating" onChange={this.handleRating}> | |
71 | - | <option>l</option> | |
72 | - | <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> | |
73 | - | <button className="rate" onClick={() => this.handleAddRating(courses._id)}>Add</button> | |
74 | - | </li> | |
75 | - | } | |
76 | - | {courses.isApplied && <button className="drop" onClick={() => this.handleDrop(courses._id)}>Drop Course</button> | |
77 | - | ~ } | |
78 | - | </li> | |
79 | - | } | |
80 | - | {1 courses.isApplied && <lixbutton className="btn" onClick={() => this.handleApply(courses._id)}>Apply</buttonx/li> | |
81 | - | } | |
82 | - | </div> <div className="footer"> | |
83 | - | <li>{courses.duration} hrs . | |
84 | - | {courses.noOfRatings} Ratings . {courses.rating}/5</li> | |
85 | - | </div> | |
86 | - | </ul> </div> | |
87 | - | </div> | |
88 | - | </div> | |
89 | - | ); | |
90 | - | } | |
91 | - | } | |
92 | - | export default Home | |
131 | + | ||
132 | + | export default Home; |
lolpee69 revised this gist . Go to revision
1 file changed, 92 insertions
app.js(file created)
@@ -0,0 +1,92 @@ | |||
1 | + | import React, { Component } from 1 react1; | |
2 | + | import "./App.css" | |
3 | + | class Home extends Component { | |
4 | + | url = "http://localhost:8001/courses/" | |
5 | + | state = { | |
6 | + | show: false, | |
7 | + | data:[], | |
8 | + | rating: | |
9 | + | } | |
10 | + | componentDidMount = () => { | |
11 | + | this.handleGetData() | |
12 | + | } | |
13 | + | handleGetData = () => { | |
14 | + | fetch(this.url + "get") | |
15 | + | .then((res) => res.json()) | |
16 | + | .then((json) => { | |
17 | + | this.setState({ data: json }) | |
18 | + | }) | |
19 | + | } | |
20 | + | handleApply = async (id) => { | |
21 | + | const requestoption = { | |
22 | + | method: ’post1, | |
23 | + | headers: { ’Content-Type1: 1 application/json’ } | |
24 | + | }; | |
25 | + | fetch(this.url + 'enroll/' + id, requestoption) •then(() => { | |
26 | + | this.handleGetData() | |
27 | + | }) | |
28 | + | }; | |
29 | + | handleRating = (e) => { | |
30 | + | this.setState({ rating: e.target.value }) | |
31 | + | } | |
32 | + | handleAddRating = async (id) => { | |
33 | + | const requestoption = { | |
34 | + | method: 'PATCH', | |
35 | + | headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rating: this.state.rating }) } | |
36 | + | fetch(this.url + "rating/" + id, requestoption) | |
37 | + | •then(() => { | |
38 | + | this.handleGetData() | |
39 | + | }) | |
40 | + | } | |
41 | + | handleDrop = async (id) => { | |
42 | + | const requestoption = { | |
43 | + | method: 'DELETE', | |
44 | + | headers: { 'Content-Type': 'application/json' }, | |
45 | + | }; | |
46 | + | fetch(this.url + "drop/" + id, requestoption) | |
47 | + | •then(() => { | |
48 | + | this.handleGetData() | |
49 | + | }) | |
50 | + | } | |
51 | + | render() { | |
52 | + | return ( | |
53 | + | <div className="home"> | |
54 | + | <header> | |
55 | + | <h2>ABC Learning</h2> | |
56 | + | </header> | |
57 | + | <div className="cardContainer"> | |
58 | + | {this.state.data.map(courses => { return ( | |
59 | + | <div className="card"> | |
60 | + | <ul> | |
61 | + | <div className="header"> | |
62 | + | <li>{courses.courseName}</li> | |
63 | + | <li>{courses.courseDept}</li> | |
64 | + | <li>{courses.description}</li> | |
65 | + | {courses.isApplied && | |
66 | + | <li> | |
67 | + | {!courses.isRated && | |
68 | + | <li>Rate: | |
69 | + | <select | |
70 | + | className="rating" name="rating" onChange={this.handleRating}> | |
71 | + | <option>l</option> | |
72 | + | <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> | |
73 | + | <button className="rate" onClick={() => this.handleAddRating(courses._id)}>Add</button> | |
74 | + | </li> | |
75 | + | } | |
76 | + | {courses.isApplied && <button className="drop" onClick={() => this.handleDrop(courses._id)}>Drop Course</button> | |
77 | + | ~ } | |
78 | + | </li> | |
79 | + | } | |
80 | + | {1 courses.isApplied && <lixbutton className="btn" onClick={() => this.handleApply(courses._id)}>Apply</buttonx/li> | |
81 | + | } | |
82 | + | </div> <div className="footer"> | |
83 | + | <li>{courses.duration} hrs . | |
84 | + | {courses.noOfRatings} Ratings . {courses.rating}/5</li> | |
85 | + | </div> | |
86 | + | </ul> </div> | |
87 | + | </div> | |
88 | + | </div> | |
89 | + | ); | |
90 | + | } | |
91 | + | } | |
92 | + | export default Home |