Skip to content

Commit 2346aed

Browse files
committed
provider_profile_and_user_dev: Added ProviderProfile Component Code and modified ReadMe file
1 parent d08c94c commit 2346aed

File tree

13 files changed

+346
-89
lines changed

13 files changed

+346
-89
lines changed

README.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,10 @@
2020
<img src="./readme/demo/Diagrams/ERD.png"/>
2121
</center>
2222

23-
### Component Diagram
23+
### System Architect Diagram
2424

2525
<center>
26-
<img src="./readme/demo/Diagrams/Component Diagram.png"/>
27-
</center>
28-
29-
### Flow Diagram
30-
31-
<center>
32-
<img src="./readme/demo/Diagrams/Flow Diagram.png"/>
26+
<img src="./readme/demo/Diagrams/System Architect Diagram.png"/>
3327
</center>
3428

3529
### Project Box Design
@@ -55,6 +49,12 @@ I used for this project ESP32 DevKit V1. It is based on the ESP32 microcontrolle
5549

5650
- <b>Personalized AI Optimization Plans:</b> Clients receive intelligent, data-driven strategies to optimize energy usage, reduce costs, and promote sustainability based on their consumption behaviors.
5751

52+
### Remarkable Features
53+
54+
<center>
55+
<img src="./readme/demo/Highlights/Highlight Section.png"/>
56+
</center>
57+
5858
<br><br>
5959

6060
<!-- Demo -->
@@ -88,6 +88,10 @@ I used for this project ESP32 DevKit V1. It is based on the ESP32 microcontrolle
8888
<!-- Development & Testing -->
8989
<img src="./readme/title6.svg"/>
9090

91+
#### Postman API Documentation
92+
93+
- You can check the full API documentation using this [link](https://documenter.getpostman.com/view/42830816/2sB2qXji4H).
94+
9195
### Code Test Cases
9296

9397
| Test Case | Test Case |
@@ -138,9 +142,13 @@ I used for this project ESP32 DevKit V1. It is based on the ESP32 microcontrolle
138142
<!-- Deployment -->
139143
<img src="./readme/title8.svg"/>
140144

141-
### EC2 Docker containers deployment
145+
### Deployment Diagram
142146

143-
- You can check the full API documentation using this [link](https://documenter.getpostman.com/view/42830816/2sB2qXji4H).
147+
<center>
148+
<img src="./readme/demo/Diagrams/Flow Diagram.png"/>
149+
</center>
150+
151+
### EC2 Docker containers deployment
144152

145153
| Deployment Pipeline Sample | GitHub Deployment Pipeline Success | EC2 Instance docker deployed |
146154
| --------------------------------------- | ------------------------------------- | ------------------------------------- |

amp-client/src/Components/CommonComponents/InputField/InputField.jsx

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -36,56 +36,4 @@ const InputField = ({
3636
);
3737
};
3838

39-
// V2
40-
// const InputField = ({
41-
// label,
42-
// placeholder,
43-
// value,
44-
// onChange,
45-
// width,
46-
// textarea,
47-
// type,
48-
// required = true,
49-
// }) => {
50-
// return (
51-
// <div className="input-field-container" style={{ width: width || "100%" }}>
52-
// <label className="subtitle black-color">
53-
// {label} {required && <span>*</span>}
54-
// </label>
55-
// {textarea ? (
56-
// <textarea placeholder={placeholder} value={value} onChange={onChange} />
57-
// ) : (
58-
// <input
59-
// type={type || "text"}
60-
// placeholder={placeholder}
61-
// value={value}
62-
// onChange={onChange}
63-
// />
64-
// )}
65-
// </div>
66-
// );
67-
// };
68-
69-
// const InputField = ({ label, placeholder, value, onChange, width, textarea, type }) => {
70-
// return (
71-
// <div className="input-field-container" style={{ width: width || '100%' }}>
72-
// <label className="subtitle black-color">{label}*</label>
73-
// {textarea ? (
74-
// <textarea
75-
// placeholder={placeholder}
76-
// value={value}
77-
// onChange={onChange}
78-
// />
79-
// ) : (
80-
// <input
81-
// type={type?type:"text"}
82-
// placeholder={placeholder}
83-
// value={value}
84-
// onChange={onChange}
85-
// />
86-
// )}
87-
// </div>
88-
// );
89-
// }
90-
9139
export default InputField;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import "./styles.css";
2+
import { useState } from "react";
3+
import { Link } from "react-router-dom";
4+
import { useLogout } from "../../../Hooks/useLogoutHook";
5+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
6+
import {
7+
faSignOutAlt,
8+
faUser,
9+
faChevronDown,
10+
} from "@fortawesome/free-solid-svg-icons";
11+
12+
const ProfileMenu = () => {
13+
const [isOpen, setIsOpen] = useState(false);
14+
const logout = useLogout();
15+
16+
const handleToggle = () => {
17+
setIsOpen((prev) => !prev);
18+
};
19+
20+
const handleLogout = async () => {
21+
try {
22+
await logout();
23+
} catch (error) {
24+
console.error("Logout failed:", error);
25+
}
26+
};
27+
28+
return (
29+
<div className="profile-menu-container">
30+
<div className="profile-summary" onClick={handleToggle}>
31+
<span className="username">Profile Menu</span>
32+
<FontAwesomeIcon
33+
icon={faChevronDown}
34+
className={`arrow-icon ${isOpen ? "open" : ""}`}
35+
/>
36+
</div>
37+
38+
{isOpen && (
39+
<div className="dropdown-menu">
40+
<Link to="/provider/profile" className="dropdown-item">
41+
<FontAwesomeIcon icon={faUser} className="item-icon" />
42+
Profile
43+
</Link>
44+
<button onClick={handleLogout} className="dropdown-item logout">
45+
<FontAwesomeIcon icon={faSignOutAlt} className="item-icon" />
46+
Logout
47+
</button>
48+
</div>
49+
)}
50+
</div>
51+
);
52+
};
53+
54+
export default ProfileMenu;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
.profile-menu-container {
2+
position: relative;
3+
display: flex;
4+
}
5+
6+
.profile-summary {
7+
border: 2px solid #fff;
8+
color: #fff;
9+
display: flex;
10+
align-items: center;
11+
justify-content: center;
12+
gap: 8px;
13+
width: 100%;
14+
padding: 10px 14px;
15+
font-size: 18px;
16+
background-color: transparent;
17+
border-radius: 8px;
18+
cursor: pointer;
19+
transition: background-color 0.3s ease;
20+
}
21+
22+
.profile-summary:hover {
23+
background-color: #fff;
24+
border: none;
25+
color: #f9a43a;
26+
}
27+
28+
.username {
29+
font-size: 18px;
30+
font-weight: 500;
31+
}
32+
33+
.arrow-icon {
34+
transition: transform 0.3s ease;
35+
}
36+
37+
.arrow-icon.open {
38+
transform: rotate(-180deg);
39+
}
40+
41+
.dropdown-menu {
42+
position: absolute;
43+
bottom: 100%;
44+
right: 0;
45+
background-color: #ffffff;
46+
border-radius: 12px;
47+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
48+
margin-bottom: 2px;
49+
min-width: 100%;
50+
/* min-width: 160px; */
51+
z-index: 100;
52+
overflow: hidden;
53+
}
54+
55+
.dropdown-item {
56+
display: flex;
57+
align-items: center;
58+
gap: 10px;
59+
padding: 12px 16px;
60+
font-size: 14px;
61+
color: #374151;
62+
text-decoration: none;
63+
background-color: #fff;
64+
border: none;
65+
width: 100%;
66+
text-align: left;
67+
cursor: pointer;
68+
}
69+
70+
.dropdown-item:hover {
71+
background-color: #f3f4f6;
72+
}
73+
74+
.logout {
75+
color: #b91c1c;
76+
}
77+
78+
.item-icon {
79+
width: 16px;
80+
height: 16px;
81+
}

amp-client/src/Components/ProviderComponents/ProviderSidebar/ProviderSidebar.jsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import "./styles.css";
22
import { Link } from "react-router-dom";
33
import logo from "../../../assets/logo.png";
4-
import LogoutButton from "../../CommonComponents/LogoutButton/LogoutButton";
4+
import ProfileMenu from "../../CommonComponents/ProfileMenu/ProfileMenu";
55
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
66
import {
77
faTachometerAlt,
@@ -34,13 +34,9 @@ const ProviderSidebar = () => {
3434
<FontAwesomeIcon icon={faBolt} className="sidebar-icon" />
3535
<span className="link-text">Power Prediction</span>
3636
</Link>
37-
<Link to="/provider/profile" className="sidebar-link">
38-
<FontAwesomeIcon icon={faUser} className="sidebar-icon" />
39-
<span className="link-text">Profile</span>
40-
</Link>
4137
</nav>
4238
<div className="sidebar-footer">
43-
<LogoutButton />
39+
<ProfileMenu />
4440
</div>
4541
</div>
4642
);

amp-client/src/Pages/ProviderPages/ProviderProfile/ProviderProfile.jsx

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,102 @@
11
import "./styles.css";
2+
import { useState } from "react";
3+
import { toast } from "react-toastify";
4+
import "react-toastify/dist/ReactToastify.css";
5+
import ProviderProfileService from "../Services/ProviderProfile/ProviderProfile";
6+
import InputField from "../../../Components/CommonComponents/InputField/InputField";
7+
import ActionButton from "../../../Components/CommonComponents/ActionButton/ActionButton";
28

39
const ProviderProfile = () => {
10+
const [formData, setFormData] = useState({
11+
name: "",
12+
email: "",
13+
password: "",
14+
phone_number: "",
15+
});
16+
17+
const { updateProfile } = ProviderProfileService();
18+
19+
const handleChange = (field, value) => {
20+
setFormData((prev) => ({
21+
...prev,
22+
[field]: value,
23+
}));
24+
};
25+
26+
const handleSubmit = async (e) => {
27+
e.preventDefault();
28+
await updateProfile(formData);
29+
};
30+
431
return (
5-
<>
6-
<div className="provider-profile-container">
7-
<div className="main-content">
8-
<h1 className="main-content-title section-titles">Provider Profile</h1>
32+
<div className="provider-profile-wrapper">
33+
<div className="provider-profile-main">
34+
<h2 className="provider-profile-heading">Provider Profile</h2>
35+
36+
<div className="provider-profile-card">
37+
<h2 className="provider-profile-subtitle">Edit Provider Profile</h2>
38+
<form className="provider-profile-form">
39+
<div className="provider-profile-form-group">
40+
<InputField
41+
label="Name"
42+
placeholder="Enter your name"
43+
value={formData.name}
44+
onChange={(e) => handleChange("name", e.target.value)}
45+
type="text"
46+
width="90%"
47+
required={false}
48+
/>
49+
</div>
50+
51+
<div className="provider-profile-form-group">
52+
<InputField
53+
label="Email"
54+
placeholder="Enter your email"
55+
value={formData.email}
56+
onChange={(e) => handleChange("email", e.target.value)}
57+
type="email"
58+
width="90%"
59+
required={false}
60+
/>
61+
</div>
62+
63+
<div className="provider-profile-form-group">
64+
<InputField
65+
label="Password"
66+
placeholder="Enter new password"
67+
value={formData.password}
68+
onChange={(e) => handleChange("password", e.target.value)}
69+
type="password"
70+
width="90%"
71+
required={false}
72+
/>
73+
</div>
74+
75+
<div className="provider-profile-form-group">
76+
<InputField
77+
label="Phone Number"
78+
placeholder="Enter phone number"
79+
value={formData.phone_number}
80+
onChange={(e) => handleChange("phone_number", e.target.value)}
81+
type="tel"
82+
width="90%"
83+
required={false}
84+
/>
85+
</div>
86+
87+
<ActionButton
88+
text="Save Changes"
89+
backgroundColor="#f9a43a"
90+
className="submit-action-button"
91+
color="#FFF"
92+
width="50%"
93+
margin="20px 0 0"
94+
onClick={handleSubmit}
95+
/>
96+
</form>
997
</div>
1098
</div>
11-
</>
99+
</div>
12100
);
13101
};
14102

0 commit comments

Comments
 (0)