From e70ffe36475fde1fa5ded7c7ed79dac51d2f8107 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sat, 29 Nov 2025 02:07:12 -0500 Subject: [PATCH 1/2] testing user view page --- .../UserProfile/UserProfile.tsx | 320 +++++++++++++----- 1 file changed, 244 insertions(+), 76 deletions(-) diff --git a/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx b/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx index abe4d5b..0057542 100644 --- a/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx +++ b/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx @@ -1,38 +1,210 @@ +// import React, { useEffect, useState } from "react"; +// import { useParams, Link } from "react-router-dom"; +// import axios from "axios"; +// import styles from "./UserProfile.module.css"; + +// const ServerPort = +// process.env.REACT_APP_SOCKET_IO_CLIENT_PORT || "http://localhost:3001"; + +// const UserProfile = () => { +// const { userId } = useParams<{ userId: string }>(); +// const [userData, setUserData] = useState(null); +// const [loading, setLoading] = useState(true); +// const [error, setError] = useState(""); + +// interface Load { +// id: number; +// loadId: string; // Add loadId property +// description: string; +// company: string; +// } + +// interface Driver { +// id: number; +// driverId: string; // Add driverId property +// name: string; +// experience: string; +// } + +// useEffect(() => { +// const fetchUserData = async () => { +// try { +// const [userRes, loadsRes, driversRes] = await Promise.all([ +// axios.get(`${ServerPort}/api/user/view/${userId}`), +// axios.get(`${ServerPort}/api/loads/user/${userId}`), +// axios.get(`${ServerPort}/api/drivers/user/${userId}`), +// ]); + +// setUserData({ +// ...userRes.data, +// loads: Array.isArray(loadsRes.data) ? loadsRes.data : [], +// drivers: Array.isArray(driversRes.data) ? driversRes.data : [], +// }); +// } catch (error) { +// console.error("Error fetching user profile data:", error); +// setError("Failed to load user profile data."); +// } finally { +// setLoading(false); +// } +// }; + +// fetchUserData(); +// }, [userId]); + +// if (loading) { +// return
Loading user profile...
; +// } + +// if (error) { +// return
{error}
; +// } + +// return ( +//
+//

User Profile

+//
+// {/* Loads Section on the Left */} +//
+//

Loads ({userData.loads.length}):

+// {Array.isArray(userData.loads) && userData.loads.length > 0 ? ( +// userData.loads.map((load: Load) => ( +//
+//

{load.description}

+//

Company: {load.company}

+//

Load ID: {load.id}

{/* Display loadId */} +// +// View Driver Profile +// +//
+// )) +// ) : ( +//

No loads available

+// )} +//
+ +// {/* Driver Details Section on the Right */} +//
+//

Available Status: {userData.loadStatus}

+// {userData.qrPNG && ( +// {`${userData.firstName} +// )} +//

+// Name: {userData.firstName} {userData.lastName} +//

+//

+// Customer Since: {new Date(userData.availableFrom).toLocaleDateString()} +//

+//

Type of Owner: {userData.userType}

+//

+// All Services Available: {userData.loadReferences ? userData.loadReferences.split(",") : "None"} +//

+//

+// Locations: {userData.location ? userData.location.split(",") : "None"} +//

+//

Phone Number: {userData.phoneNumber || "Not provided"}

+//

Address: {userData.address || "Not provided"}

+//
+ +// {/* Drivers Section in the Third Column */} +//
+//

Drivers ({userData.drivers.length}):

+// {Array.isArray(userData.drivers) && userData.drivers.length > 0 ? ( +// userData.drivers.map((driver: Driver) => ( +//
+//

{driver.name}

+//

Experience: {driver.experience}

+//

Driver ID: {driver.id}

{/* Display driverId */} +//
+// )) +// ) : ( +//

No drivers available

+// )} +//
+//
+ +// {/* "Add Business" Button */} +// + +// {/* Navigation buttons */} +//
+// +// Home +// +// +// Message User +// +//
+//
+// ); +// }; + +// export default UserProfile; + import React, { useEffect, useState } from "react"; import { useParams, Link } from "react-router-dom"; import axios from "axios"; import styles from "./UserProfile.module.css"; -const ServerPort = - process.env.REACT_APP_SOCKET_IO_CLIENT_PORT || "http://localhost:3001"; +const SERVER_PORT = process.env.REACT_APP_SOCKET_IO_CLIENT_PORT || "http://localhost:3001"; + +interface Load { + id: number; + loadId: string; + description: string; + company: string; +} + +interface Driver { + id: number; + driverId: string; + name: string; + experience: string; +} -const UserProfile = () => { +interface UserData { + firstName: string; + lastName: string; + email: string; + phoneNumber?: string; + address?: string; + loadStatus?: string; + availableFrom?: string; + userType?: string; + loadReferences?: string; + location?: string; + qrPNG?: string; + loads: Load[]; + drivers: Driver[]; +} + +const UserProfile: React.FC = () => { const { userId } = useParams<{ userId: string }>(); - const [userData, setUserData] = useState(null); + const [userData, setUserData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); - interface Load { - id: number; - loadId: string; // Add loadId property - description: string; - company: string; - } - - interface Driver { - id: number; - driverId: string; // Add driverId property - name: string; - experience: string; - } - useEffect(() => { + if (!userId) { + setError("User ID not provided in URL."); + setLoading(false); + return; + } + const fetchUserData = async () => { try { const [userRes, loadsRes, driversRes] = await Promise.all([ - axios.get(`${ServerPort}/api/user/view/${userId}`), - axios.get(`${ServerPort}/api/loads/user/${userId}`), - axios.get(`${ServerPort}/api/drivers/user/${userId}`), + axios.get(`${SERVER_PORT}/api/user/view/${userId}`), + axios.get(`${SERVER_PORT}/api/loads/user/${userId}`), + axios.get(`${SERVER_PORT}/api/drivers/user/${userId}`), ]); setUserData({ @@ -40,8 +212,8 @@ const UserProfile = () => { loads: Array.isArray(loadsRes.data) ? loadsRes.data : [], drivers: Array.isArray(driversRes.data) ? driversRes.data : [], }); - } catch (error) { - console.error("Error fetching user profile data:", error); + } catch (err) { + console.error("Error fetching user profile data:", err); setError("Failed to load user profile data."); } finally { setLoading(false); @@ -51,29 +223,41 @@ const UserProfile = () => { fetchUserData(); }, [userId]); - if (loading) { - return
Loading user profile...
; - } + if (loading) return
Loading user profile...
; + if (error) return
{error}
; + if (!userData) return
No user data available.
; - if (error) { - return
{error}
; - } + const { + firstName, + lastName, + email, + phoneNumber, + address, + loadStatus, + availableFrom, + userType, + loadReferences, + location, + qrPNG, + loads, + drivers, + } = userData; return (

User Profile

- {/* Loads Section on the Left */} + {/* Loads Section */}
-

Loads ({userData.loads.length}):

- {Array.isArray(userData.loads) && userData.loads.length > 0 ? ( - userData.loads.map((load: Load) => ( +

Loads ({loads.length})

+ {loads.length > 0 ? ( + loads.map((load) => (

{load.description}

Company: {load.company}

-

Load ID: {load.id}

{/* Display loadId */} - - View Driver Profile +

Load ID: {load.loadId}

+ + View Load Details
)) @@ -82,42 +266,35 @@ const UserProfile = () => { )}
- {/* Driver Details Section on the Right */} + {/* User Profile Section */}
-

Available Status: {userData.loadStatus}

- {userData.qrPNG && ( + {qrPNG && ( {`${userData.firstName} )} -

- Name: {userData.firstName} {userData.lastName} -

-

- Customer Since: {new Date(userData.availableFrom).toLocaleDateString()} -

-

Type of Owner: {userData.userType}

-

- All Services Available: {userData.loadReferences ? userData.loadReferences.split(",") : "None"} -

-

- Locations: {userData.location ? userData.location.split(",") : "None"} -

-

Phone Number: {userData.phoneNumber || "Not provided"}

-

Address: {userData.address || "Not provided"}

+

{firstName} {lastName}

+

Email: {email}

+

Phone: {phoneNumber || "Not provided"}

+

Address: {address || "Not provided"}

+

Status: {loadStatus || "N/A"}

+

Customer Since: {availableFrom ? new Date(availableFrom).toLocaleDateString() : "N/A"}

+

Type of Owner: {userType || "N/A"}

+

Services: {loadReferences ? loadReferences.split(",").join(", ") : "None"}

+

Locations: {location ? location.split(",").join(", ") : "None"}

- {/* Drivers Section in the Third Column */} + {/* Drivers Section */}
-

Drivers ({userData.drivers.length}):

- {Array.isArray(userData.drivers) && userData.drivers.length > 0 ? ( - userData.drivers.map((driver: Driver) => ( +

Drivers ({drivers.length})

+ {drivers.length > 0 ? ( + drivers.map((driver) => (

{driver.name}

Experience: {driver.experience}

-

Driver ID: {driver.id}

{/* Display driverId */} +

Driver ID: {driver.driverId}

)) ) : ( @@ -126,22 +303,13 @@ const UserProfile = () => {
- {/* "Add Business" Button */} - - - {/* Navigation buttons */} + {/* Action Buttons */}
- - Home - - - Message User - + + Home + Message User
); From 7950bff392d098ce70519a49c043ffbea72778c2 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sat, 29 Nov 2025 02:21:52 -0500 Subject: [PATCH 2/2] testing the profile view page --- .../UserProfile/UserProfile.module.css | 120 ++++--- .../UserProfile/UserProfile.tsx | 294 ++++++++++++++---- 2 files changed, 310 insertions(+), 104 deletions(-) diff --git a/client/src/containers/User/AvailableTable/UserProfile/UserProfile.module.css b/client/src/containers/User/AvailableTable/UserProfile/UserProfile.module.css index daedeea..b7711f8 100644 --- a/client/src/containers/User/AvailableTable/UserProfile/UserProfile.module.css +++ b/client/src/containers/User/AvailableTable/UserProfile/UserProfile.module.css @@ -1,82 +1,109 @@ /* UserProfile.module.css */ - .userProfileContainer { - font-family: Arial, sans-serif; - max-width: 1200px; + max-width: 1300px; margin: auto; padding: 20px; + font-family: Arial, sans-serif; color: #333; } -.contentWrapper { +.profileHeader { display: flex; - flex-wrap: wrap; /* Allows wrapping for smaller screens */ + align-items: center; gap: 20px; + margin-bottom: 30px; } -.loadsSection, .profileSection, .driversSection { - background-color: #f9f9f9; - padding: 15px; +.profileImage { + width: 150px; + height: 150px; + object-fit: cover; + border-radius: 50%; + border: 3px solid #2980b9; +} + +.profileName h1 { + margin: 0; + font-size: 2rem; + color: #2980b9; +} + +.profileName p { + margin: 4px 0; + font-size: 1rem; +} + +.userInfoSection { + margin-bottom: 30px; +} + +.infoGrid { + display: flex; + flex-wrap: wrap; + gap: 15px; +} + +.infoCard { + background: #f5f5f5; + padding: 12px 15px; border-radius: 8px; - border: 1px solid #ddd; - flex: 1; - min-width: 280px; /* Minimum width to improve responsiveness */ + flex: 1 1 200px; + min-width: 180px; } -.loadsSection { - max-width: 400px; +.sectionsWrapper { + display: flex; + flex-wrap: wrap; + gap: 20px; +} + +.loadsSection, .driversSection { + flex: 1; + min-width: 280px; + background: #f9f9f9; + padding: 15px; + border-radius: 8px; + border: 1px solid #ddd; } .loadItem, .driverItem { - background-color: #fff; + background: #fff; padding: 12px; - margin-bottom: 10px; + margin-bottom: 12px; + border-radius: 6px; border: 1px solid #ddd; - border-radius: 4px; } -.loadLink, .buttonLink { +.loadLink { color: #2980b9; text-decoration: none; } -.loadLink:hover, .buttonLink:hover { +.loadLink:hover { text-decoration: underline; } -.profileSection { - flex: 2; -} - -.profileImage { - width: 150px; - height: auto; - border-radius: 8px; - margin-bottom: 10px; +.buttonContainer { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 20px; + justify-content: center; } .button { padding: 10px 20px; - background-color: #2980b9; + background: #2980b9; color: #fff; + border-radius: 5px; border: none; - border-radius: 4px; cursor: pointer; + text-decoration: none; text-align: center; - margin: 5px 0; - display: inline-block; } .button:hover { - background-color: #1a66a0; -} - -.buttonContainer { - display: flex; - flex-wrap: wrap; - gap: 10px; - margin-top: 20px; - justify-content: center; + background: #1a66a0; } .loading, @@ -87,10 +114,15 @@ } @media (max-width: 768px) { - .contentWrapper { - flex-direction: column; /* Stack sections vertically on smaller screens */ + .profileHeader { + flex-direction: column; + align-items: center; + text-align: center; + } + .sectionsWrapper { + flex-direction: column; } - .buttonContainer { - flex-direction: column; /* Stack buttons vertically */ + .infoGrid { + flex-direction: column; } } diff --git a/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx b/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx index 0057542..b7e0f24 100644 --- a/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx +++ b/client/src/containers/User/AvailableTable/UserProfile/UserProfile.tsx @@ -149,12 +149,182 @@ // export default UserProfile; +// import React, { useEffect, useState } from "react"; +// import { useParams, Link } from "react-router-dom"; +// import axios from "axios"; +// import styles from "./UserProfile.module.css"; + +// const SERVER_PORT = process.env.REACT_APP_SOCKET_IO_CLIENT_PORT || "http://localhost:3001"; + +// interface Load { +// id: number; +// loadId: string; +// description: string; +// company: string; +// } + +// interface Driver { +// id: number; +// driverId: string; +// name: string; +// experience: string; +// } + +// interface UserData { +// firstName: string; +// lastName: string; +// email: string; +// phoneNumber?: string; +// address?: string; +// loadStatus?: string; +// availableFrom?: string; +// userType?: string; +// loadReferences?: string; +// location?: string; +// qrPNG?: string; +// loads: Load[]; +// drivers: Driver[]; +// } + +// const UserProfile: React.FC = () => { +// const { userId } = useParams<{ userId: string }>(); +// const [userData, setUserData] = useState(null); +// const [loading, setLoading] = useState(true); +// const [error, setError] = useState(""); + +// useEffect(() => { +// if (!userId) { +// setError("User ID not provided in URL."); +// setLoading(false); +// return; +// } + +// const fetchUserData = async () => { +// try { +// const [userRes, loadsRes, driversRes] = await Promise.all([ +// axios.get(`${SERVER_PORT}/api/user/view/${userId}`), +// axios.get(`${SERVER_PORT}/api/loads/user/${userId}`), +// axios.get(`${SERVER_PORT}/api/drivers/user/${userId}`), +// ]); + +// setUserData({ +// ...userRes.data, +// loads: Array.isArray(loadsRes.data) ? loadsRes.data : [], +// drivers: Array.isArray(driversRes.data) ? driversRes.data : [], +// }); +// } catch (err) { +// console.error("Error fetching user profile data:", err); +// setError("Failed to load user profile data."); +// } finally { +// setLoading(false); +// } +// }; + +// fetchUserData(); +// }, [userId]); + +// if (loading) return
Loading user profile...
; +// if (error) return
{error}
; +// if (!userData) return
No user data available.
; + +// const { +// firstName, +// lastName, +// email, +// phoneNumber, +// address, +// loadStatus, +// availableFrom, +// userType, +// loadReferences, +// location, +// qrPNG, +// loads, +// drivers, +// } = userData; + +// return ( +//
+//

User Profile

+//
+// {/* Loads Section */} +//
+//

Loads ({loads.length})

+// {loads.length > 0 ? ( +// loads.map((load) => ( +//
+//

{load.description}

+//

Company: {load.company}

+//

Load ID: {load.loadId}

+// +// View Load Details +// +//
+// )) +// ) : ( +//

No loads available

+// )} +//
+ +// {/* User Profile Section */} +//
+// {qrPNG && ( +// {`${firstName} +// )} +//

{firstName} {lastName}

+//

Email: {email}

+//

Phone: {phoneNumber || "Not provided"}

+//

Address: {address || "Not provided"}

+//

Status: {loadStatus || "N/A"}

+//

Customer Since: {availableFrom ? new Date(availableFrom).toLocaleDateString() : "N/A"}

+//

Type of Owner: {userType || "N/A"}

+//

Services: {loadReferences ? loadReferences.split(",").join(", ") : "None"}

+//

Locations: {location ? location.split(",").join(", ") : "None"}

+//
+ +// {/* Drivers Section */} +//
+//

Drivers ({drivers.length})

+// {drivers.length > 0 ? ( +// drivers.map((driver) => ( +//
+//

{driver.name}

+//

Experience: {driver.experience}

+//

Driver ID: {driver.driverId}

+//
+// )) +// ) : ( +//

No drivers available

+// )} +//
+//
+ +// {/* Action Buttons */} +//
+// +// Home +// Message User +//
+//
+// ); +// }; + +// export default UserProfile; + +// UserProfile.tsx import React, { useEffect, useState } from "react"; import { useParams, Link } from "react-router-dom"; import axios from "axios"; import styles from "./UserProfile.module.css"; -const SERVER_PORT = process.env.REACT_APP_SOCKET_IO_CLIENT_PORT || "http://localhost:3001"; +const SERVER_PORT = + process.env.REACT_APP_SOCKET_IO_CLIENT_PORT || "http://localhost:3001"; interface Load { id: number; @@ -179,26 +349,25 @@ interface UserData { loadStatus?: string; availableFrom?: string; userType?: string; + experienceLevel?: string; + preferredLoadType?: string; + company?: string; + subscribed?: boolean; + rating?: number; + profileImage?: string; + loadDetails?: Load[]; + drivers?: Driver[]; loadReferences?: string; location?: string; - qrPNG?: string; - loads: Load[]; - drivers: Driver[]; } const UserProfile: React.FC = () => { const { userId } = useParams<{ userId: string }>(); const [userData, setUserData] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(""); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(""); useEffect(() => { - if (!userId) { - setError("User ID not provided in URL."); - setLoading(false); - return; - } - const fetchUserData = async () => { try { const [userRes, loadsRes, driversRes] = await Promise.all([ @@ -209,7 +378,7 @@ const UserProfile: React.FC = () => { setUserData({ ...userRes.data, - loads: Array.isArray(loadsRes.data) ? loadsRes.data : [], + loadDetails: Array.isArray(loadsRes.data) ? loadsRes.data : [], drivers: Array.isArray(driversRes.data) ? driversRes.data : [], }); } catch (err) { @@ -227,26 +396,47 @@ const UserProfile: React.FC = () => { if (error) return
{error}
; if (!userData) return
No user data available.
; - const { - firstName, - lastName, - email, - phoneNumber, - address, - loadStatus, - availableFrom, - userType, - loadReferences, - location, - qrPNG, - loads, - drivers, - } = userData; + const loads = userData.loadDetails || []; + const drivers = userData.drivers || []; return (
-

User Profile

-
+ {/* Profile Header */} +
+ {userData.profileImage && ( + {`${userData.firstName} + )} +
+

{userData.firstName} {userData.lastName}

+

Customer Since: {userData.availableFrom ? new Date(userData.availableFrom).toLocaleDateString() : "N/A"}

+

Type of Owner: {userData.userType || "N/A"}

+
+
+ + {/* User Info */} +
+

User Information

+
+
Email: {userData.email}
+
Phone: {userData.phoneNumber || "Not provided"}
+
Address: {userData.address || "Not provided"}
+
Status: {userData.loadStatus || "N/A"}
+
Experience Level: {userData.experienceLevel || "N/A"}
+
Preferred Load: {userData.preferredLoadType || "N/A"}
+
Company: {userData.company || "N/A"}
+
Subscribed: {userData.subscribed ? "Yes" : "No"}
+
Rating: {userData.rating || "N/A"}
+
Services: {userData.loadReferences ? userData.loadReferences.split(",").join(", ") : "None"}
+
Locations: {userData.location ? userData.location.split(",").join(", ") : "None"}
+
+
+ + {/* Loads and Drivers Sections */} +
{/* Loads Section */}

Loads ({loads.length})

@@ -254,10 +444,10 @@ const UserProfile: React.FC = () => { loads.map((load) => (

{load.description}

-

Company: {load.company}

-

Load ID: {load.loadId}

+

Company: {load.company}

+

Load ID: {load.loadId || load.id}

- View Load Details + View Driver Profile
)) @@ -266,26 +456,6 @@ const UserProfile: React.FC = () => { )}
- {/* User Profile Section */} -
- {qrPNG && ( - {`${firstName} - )} -

{firstName} {lastName}

-

Email: {email}

-

Phone: {phoneNumber || "Not provided"}

-

Address: {address || "Not provided"}

-

Status: {loadStatus || "N/A"}

-

Customer Since: {availableFrom ? new Date(availableFrom).toLocaleDateString() : "N/A"}

-

Type of Owner: {userType || "N/A"}

-

Services: {loadReferences ? loadReferences.split(",").join(", ") : "None"}

-

Locations: {location ? location.split(",").join(", ") : "None"}

-
- {/* Drivers Section */}

Drivers ({drivers.length})

@@ -293,8 +463,11 @@ const UserProfile: React.FC = () => { drivers.map((driver) => (

{driver.name}

-

Experience: {driver.experience}

-

Driver ID: {driver.driverId}

+

Experience: {driver.experience}

+

Driver ID: {driver.driverId || driver.id}

+ + View Driver Profile +
)) ) : ( @@ -305,11 +478,12 @@ const UserProfile: React.FC = () => { {/* Action Buttons */}
- - Home - Message User + + Home + + + Message User +
);