Skip to content

Commit 1ab94fa

Browse files
authored
Merge pull request #152 from Riyad-Murad/frontend_structure_adjustment
frontend_structure_adjustment: Moved the API call logic from the comp…
2 parents b4f74a3 + 49aa977 commit 1ab94fa

File tree

28 files changed

+868
-496
lines changed

28 files changed

+868
-496
lines changed

amp-client/src/Axios/axios.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import axios from "axios";
22

3-
const axiosBaseUrl = axios.create({
3+
const axiosInstance = axios.create({
44
baseURL: import.meta.env.VITE_API_BASE_URL + '/api/v1',
55
headers: { "Content-Type": "application/json" },
66
});
77

8-
axiosBaseUrl.interceptors.request.use((config) => {
8+
axiosInstance.interceptors.request.use((config) => {
99
const token = localStorage.getItem("Token");
1010
if (token) {
1111
config.headers.Authorization = `Bearer ${token}`;
1212
}
1313
return config;
1414
});
1515

16-
export default axiosBaseUrl;
16+
export default axiosInstance;

amp-client/src/Components/ClientComponents/ClientNavbar/ClientNavbar.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import "./styles.css";
22
import { useState } from "react";
33
import { Link } from "react-router-dom";
44
import logo from "../../../assets/logo.png";
5-
import axiosBaseUrl from "../../../Axios/axios";
5+
import axiosInstance from "../../../Axios/axios";
66
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
77
import {
88
faUserCircle,
Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,91 @@
1-
import './styles.css'
1+
import "./styles.css";
22

3-
const InputField = ({ label, placeholder, value, onChange, width, textarea, type }) => {
3+
const InputField = ({
4+
label,
5+
placeholder,
6+
value,
7+
onChange,
8+
width,
9+
textarea,
10+
type,
11+
required = true,
12+
}) => {
413
return (
5-
<div className="input-field-container" style={{ width: width || '100%' }}>
6-
<label className="subtitle black-color">{label}*</label>
14+
<div className="input-field-container" style={{ width: width || "100%" }}>
15+
<label className="subtitle black-color">
16+
{label}
17+
{required ? <span>*</span> : null}
18+
</label>
719
{textarea ? (
820
<textarea
921
placeholder={placeholder}
1022
value={value}
1123
onChange={onChange}
24+
required={required}
1225
/>
1326
) : (
1427
<input
15-
type={type?type:"text"}
28+
type={type || "text"}
1629
placeholder={placeholder}
1730
value={value}
1831
onChange={onChange}
32+
required={required}
1933
/>
2034
)}
2135
</div>
2236
);
23-
}
37+
};
2438

25-
export default InputField
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+
91+
export default InputField;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import "./styles.css";
2-
import axiosBaseUrl from "../../../Axios/axios";
32
import { useLogout } from "../../../Hooks/useLogoutHook";
43
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
54
import { faSignOutAlt } from "@fortawesome/free-solid-svg-icons";

amp-client/src/Components/LandingPageComponents/ContactUs/ContactUsSection.jsx

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,68 @@
11
import "./styles.css";
2+
import { useState } from "react";
3+
import { toast } from "react-toastify";
24
import contactUs from "../../../assets/contact-us.png";
35
import InputField from "../../CommonComponents/InputField/InputField";
46
import ActionButton from "../../CommonComponents/ActionButton/ActionButton";
7+
import sendContactMessage from "../Services/ContactUsService/ContactUsService";
58

69
const ContactUsSection = ({ id }) => {
10+
const [formData, setFormData] = useState({
11+
name: "",
12+
email: "",
13+
phone_number: "",
14+
message: "",
15+
});
16+
17+
const [isSubmitting, setIsSubmitting] = useState(false);
18+
19+
const handleInputChange = (field) => (e) => {
20+
setFormData((prevData) => ({
21+
...prevData,
22+
[field]: e.target.value,
23+
}));
24+
};
25+
26+
const handleSubmit = async () => {
27+
if (!formData.name || !formData.email || !formData.phone_number) {
28+
toast.error("Please fill all required fields");
29+
return;
30+
}
31+
32+
// Email validation
33+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
34+
if (!emailRegex.test(formData.email)) {
35+
toast.error("Please enter a valid email address");
36+
return;
37+
}
38+
39+
setIsSubmitting(true);
40+
41+
try {
42+
const result = await sendContactMessage(formData);
43+
44+
if (result.success) {
45+
toast.success("Message sent successfully! We'll get back to you soon.");
46+
47+
// Reset form
48+
setFormData({
49+
name: "",
50+
email: "",
51+
phone_number: "",
52+
message: "",
53+
});
54+
} else {
55+
toast.error(
56+
result.error || "Failed to send message. Please try again."
57+
);
58+
}
59+
} catch (error) {
60+
toast.error("An unexpected error occurred. Please try again later.");
61+
} finally {
62+
setIsSubmitting(false);
63+
}
64+
};
65+
766
return (
867
<div id={id}>
968
<div className="section-center">
@@ -17,12 +76,48 @@ const ContactUsSection = ({ id }) => {
1776
<img src={contactUs} alt="Contact Us" className="contact-image" />
1877
</div>
1978
<div className="contact-form">
20-
<h2 className="section-titles primary-color section-center">Contact Us</h2>
21-
<InputField label="Full Name" placeholder="Full Name" width="80%" />
22-
<InputField label="Email" placeholder="Email" width="80%" />
23-
<InputField label="Phone Number" placeholder="Phone Number" width="80%" />
24-
<InputField label="Message" placeholder="Message" textarea width="80%" />
25-
<ActionButton backgroundColor="#233a7e" color="white" text="Submit" width="60%" />
79+
<h2 className="section-titles primary-color section-center less-margin">
80+
Contact Us
81+
</h2>
82+
83+
<InputField
84+
label="Full Name"
85+
placeholder="Full Name"
86+
width="80%"
87+
value={formData.name}
88+
onChange={handleInputChange("name")}
89+
/>
90+
<InputField
91+
label="Email"
92+
placeholder="Email"
93+
width="80%"
94+
type="email"
95+
value={formData.email}
96+
onChange={handleInputChange("email")}
97+
/>
98+
<InputField
99+
label="Phone Number"
100+
placeholder="Phone Number"
101+
width="80%"
102+
value={formData.phone_number}
103+
onChange={handleInputChange("phone_number")}
104+
/>
105+
<InputField
106+
label="Message"
107+
placeholder="Message (Optional)"
108+
textarea
109+
width="80%"
110+
value={formData.message}
111+
onChange={handleInputChange("message")}
112+
required={false}
113+
/>
114+
<ActionButton
115+
backgroundColor="#233a7e"
116+
color="white"
117+
text={isSubmitting ? "Submitting..." : "Submit"}
118+
width="60%"
119+
onClick={handleSubmit}
120+
/>
26121
</div>
27122
</section>
28123
</div>

amp-client/src/Components/LandingPageComponents/ContactUs/styles.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
/* ContactUsSection.css */
22
.section-center {
33
text-align: center;
4-
padding: 30px;
4+
padding-top: 30px;
5+
}
6+
7+
.less-margin {
8+
margin-bottom: 0px;
59
}
610

711
.contact-us-section {

amp-client/src/Components/LandingPageComponents/LoginForm/LoginForm.jsx

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,20 @@
11
import "./styles.css";
22
import { useState } from "react";
3-
import { toast } from "react-toastify";
4-
import { useNavigate } from "react-router-dom";
5-
import axiosBaseUrl from "../../../Axios/axios";
6-
import { useDispatch, useSelector } from "react-redux";
7-
import { storeData } from "../../../Redux/Slices/UserSlice";
3+
import { useSelector } from "react-redux";
84
import InputField from "../../CommonComponents/InputField/InputField";
95
import ActionButton from "../../CommonComponents/ActionButton/ActionButton";
10-
import { toggleLoad } from "../../../Redux/Slices/loadingSlice";
6+
import useLoginFormService from "../Services/LoginFormService/LoginFormService";
117

128
const LoginForm = ({ onClose }) => {
139
const [email, setEmail] = useState("");
1410
const [password, setPassword] = useState("");
1511

12+
const { handleLogin } = useLoginFormService();
1613
const loading = useSelector((state) => state.loading.loadingState);
1714

18-
const dispatch = useDispatch();
19-
20-
const navigate = useNavigate();
21-
22-
const handleLogin = async (e) => {
15+
const onSubmit = (e) => {
2316
e.preventDefault();
24-
25-
try {
26-
dispatch(toggleLoad(true));
27-
28-
const response = await axiosBaseUrl.post("/login", { email, password });
29-
30-
const userType = response.data.data.user_type;
31-
32-
localStorage.setItem("Token", response.data.data.token);
33-
dispatch(storeData(response.data.data));
34-
35-
if (userType === "Client") {
36-
toast.success("Hello Client");
37-
navigate("/client/dashboard");
38-
} else if (userType === "Provider") {
39-
toast.success("Hello Provider");
40-
navigate("/provider/dashboard");
41-
} else if (userType === "Admin") {
42-
toast.success("Hello Admin");
43-
navigate("/admin/navigation-page");
44-
}
45-
} catch (error) {
46-
toast.error("Login failed. Please try again.");
47-
} finally {
48-
dispatch(toggleLoad(false));
49-
}
17+
handleLogin(email, password);
5018
};
5119

5220
return (
@@ -79,13 +47,13 @@ const LoginForm = ({ onClose }) => {
7947
width="70%"
8048
value={password}
8149
onChange={(e) => setPassword(e.target.value)}
82-
/>
50+
/>
8351
<ActionButton
8452
backgroundColor="#F9A43A"
8553
color="#233A7E"
8654
text={<h3>Login</h3>}
8755
width="70%"
88-
onClick={handleLogin}
56+
onClick={onSubmit}
8957
margin="5px"
9058
/>
9159
</>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// ContactUsService.js
2+
import axiosInstance from "../../../../Axios/axios";
3+
4+
const sendContactMessage = async (contactData) => {
5+
try {
6+
const response = await axiosInstance.post("/insertMessage", contactData);
7+
return {
8+
success: true,
9+
data: response.data,
10+
};
11+
} catch (error) {
12+
console.error("Error sending contact message:", error);
13+
return {
14+
success: false,
15+
error: error.response?.data?.message || "Failed to send message",
16+
};
17+
}
18+
};
19+
20+
export default sendContactMessage;
21+

0 commit comments

Comments
 (0)