From 49011c09162317639bdbd249405c9df2ff8589a7 Mon Sep 17 00:00:00 2001
From: Linh Nguyen <78007881+linhnnk@users.noreply.github.com>
Date: Mon, 25 Mar 2024 21:14:04 -0700
Subject: [PATCH] feat(profile): Add other user's profile detail in appointment
(#722)
---
app/web/__tests__/ProfileDetail.test.tsx | 2 +-
.../ProfilePicture.test.tsx.snap | 4 +-
app/web/src/app/actions.ts | 15 ++
app/web/src/app/profile/[withUser]/page.tsx | 40 +++++
app/web/src/app/{user => }/profile/page.tsx | 8 +-
.../inbox/ConversationDropdownMenu.tsx | 2 +-
.../appointment/inbox/ConversationList.tsx | 5 +-
.../appointment/inbox/ConversationViewer.tsx | 6 +-
.../src/components/layout/ProfilePicture.tsx | 2 +-
.../profile/OtherUserProfileDetails.tsx | 163 ++++++++++++++++++
.../{user => profile}/ProfileDetails.tsx | 4 +-
11 files changed, 235 insertions(+), 16 deletions(-)
create mode 100644 app/web/src/app/profile/[withUser]/page.tsx
rename app/web/src/app/{user => }/profile/page.tsx (84%)
create mode 100644 app/web/src/components/profile/OtherUserProfileDetails.tsx
rename app/web/src/components/{user => profile}/ProfileDetails.tsx (95%)
diff --git a/app/web/__tests__/ProfileDetail.test.tsx b/app/web/__tests__/ProfileDetail.test.tsx
index 9d110744..bb88864c 100644
--- a/app/web/__tests__/ProfileDetail.test.tsx
+++ b/app/web/__tests__/ProfileDetail.test.tsx
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { ProfileDetails } from "@components/profile/ProfileDetails";
import "@testing-library/jest-dom";
-import { ProfileDetails } from "@components/user/ProfileDetails";
import { render, screen } from "@testing-library/react";
import { User } from "next-auth";
diff --git a/app/web/__tests__/__snapshots__/ProfilePicture.test.tsx.snap b/app/web/__tests__/__snapshots__/ProfilePicture.test.tsx.snap
index efe73e68..58ee3279 100644
--- a/app/web/__tests__/__snapshots__/ProfilePicture.test.tsx.snap
+++ b/app/web/__tests__/__snapshots__/ProfilePicture.test.tsx.snap
@@ -6,7 +6,7 @@ exports[`ProfilePicture matches snapshot 1`] = `
"baseElement":
,
"container":
{
+ try {
+ const users = await getUsrList("username", username);
+ if (users && users.length > 0) {
+ return users[0];
+ }
+ return null;
+ } catch (error) {
+ console.error("Error fetching user by username:", error);
+ return null;
+ }
+}
+
export async function getUserAppointments(user: User) {
const appointments = await db.appointment.findMany({
where: {
diff --git a/app/web/src/app/profile/[withUser]/page.tsx b/app/web/src/app/profile/[withUser]/page.tsx
new file mode 100644
index 00000000..270d4755
--- /dev/null
+++ b/app/web/src/app/profile/[withUser]/page.tsx
@@ -0,0 +1,40 @@
+/*
+ * Copyright [2023] [Privacypal Authors]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { OtherUserProfileDetails } from "@components/profile/OtherUserProfileDetails";
+import React from "react";
+import { auth } from "src/auth";
+import { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Other User Profile Detail",
+};
+
+export default async function OtherUserProfilePage({
+ params,
+}: {
+ params: { withUser: string };
+}) {
+ const session = await auth();
+ if (!session) {
+ return Not logged in;
+ }
+ return (
+
+
+
+ );
+}
diff --git a/app/web/src/app/user/profile/page.tsx b/app/web/src/app/profile/page.tsx
similarity index 84%
rename from app/web/src/app/user/profile/page.tsx
rename to app/web/src/app/profile/page.tsx
index cfc49024..1e9e9f8e 100644
--- a/app/web/src/app/user/profile/page.tsx
+++ b/app/web/src/app/profile/page.tsx
@@ -14,9 +14,13 @@
* limitations under the License.
*/
import Content from "@components/layout/Content";
-import { ProfileDetails } from "@components/user/ProfileDetails";
-import UserUpdateForm from "@components/user/UserUpdateForm";
+import { ProfileDetails } from "@components/profile/ProfileDetails";
import { auth } from "src/auth";
+import { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Profile Detail",
+};
export default async function UserDashboardPage() {
const session = await auth();
diff --git a/app/web/src/components/appointment/inbox/ConversationDropdownMenu.tsx b/app/web/src/components/appointment/inbox/ConversationDropdownMenu.tsx
index 71c865f7..1779c5e8 100644
--- a/app/web/src/components/appointment/inbox/ConversationDropdownMenu.tsx
+++ b/app/web/src/components/appointment/inbox/ConversationDropdownMenu.tsx
@@ -70,7 +70,7 @@ export const ConversationDropdownMenu = () => {
Homepage
-
+
Profile
diff --git a/app/web/src/components/appointment/inbox/ConversationList.tsx b/app/web/src/components/appointment/inbox/ConversationList.tsx
index 18e47bbe..19ceb173 100644
--- a/app/web/src/components/appointment/inbox/ConversationList.tsx
+++ b/app/web/src/components/appointment/inbox/ConversationList.tsx
@@ -99,7 +99,7 @@ const userMetaStyle: CSS = {
};
const profileLinkStyle: CSS = {
- fontSize: "0.75rem",
+ fontSize: "1rem",
};
interface ConversationListProps {
@@ -166,8 +166,7 @@ export const ConversationList = ({
{user.email}
- {/* TODO: possibly remove this link (do users have profiles?) */}
-
+
View Profile
diff --git a/app/web/src/components/appointment/inbox/ConversationViewer.tsx b/app/web/src/components/appointment/inbox/ConversationViewer.tsx
index bcb1638a..afa6a364 100644
--- a/app/web/src/components/appointment/inbox/ConversationViewer.tsx
+++ b/app/web/src/components/appointment/inbox/ConversationViewer.tsx
@@ -14,13 +14,13 @@
* limitations under the License.
*/
"use client";
-
import { Panel, PanelHeader, PanelMain, Title } from "@patternfly/react-core";
import { InboxAvatar } from "./InboxAvatar";
import pfAvatar from "@assets/pf_avatar.svg";
import { CSS } from "@lib/utils";
import { User } from "next-auth";
import { CognitoUser } from "@lib/cognito";
+import Link from "next/link";
const panelStyle: CSS = {
display: "flex",
@@ -86,7 +86,6 @@ interface ConversationViewerProps {
withUser: CognitoUser | undefined;
children?: React.ReactNode;
}
-
export const ConversationViewer = ({
withUser,
children,
@@ -94,7 +93,7 @@ export const ConversationViewer = ({
const headerText = withUser
? withUser.firstName + " " + withUser.lastName
: "No appointment selected.";
-
+ const profilepage = `/profile/${withUser?.username}`;
return (
@@ -107,6 +106,7 @@ export const ConversationViewer = ({
{withUser.email}
) : null}
+ {withUser && View profile}
{children}
diff --git a/app/web/src/components/layout/ProfilePicture.tsx b/app/web/src/components/layout/ProfilePicture.tsx
index 8def5eef..b3fac34a 100644
--- a/app/web/src/components/layout/ProfilePicture.tsx
+++ b/app/web/src/components/layout/ProfilePicture.tsx
@@ -66,7 +66,7 @@ export default function ProfilePicture({
// link to dashboard in place of user profile
const avatar = (
diff --git a/app/web/src/components/profile/OtherUserProfileDetails.tsx b/app/web/src/components/profile/OtherUserProfileDetails.tsx
new file mode 100644
index 00000000..16452764
--- /dev/null
+++ b/app/web/src/components/profile/OtherUserProfileDetails.tsx
@@ -0,0 +1,163 @@
+/*
+ * Copyright [2023] [Privacypal Authors]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"use client";
+import React, { useEffect, useState } from "react";
+import {
+ Card,
+ CardTitle,
+ CardBody,
+ CardHeader,
+ Flex,
+ Title,
+ FlexItem,
+ Divider,
+ CardFooter,
+ Alert,
+} from "@patternfly/react-core";
+import { User } from "next-auth";
+import { UserRole } from "@lib/userRole";
+import { CognitoUser } from "@lib/cognito";
+import { getUserByUsername } from "@app/actions";
+import { CSS } from "@lib/utils";
+
+const cardContainer: CSS = {
+ display: "flex",
+ justifyContent: "center",
+ filter: "drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25))",
+};
+
+const cardStyle: CSS = {
+ width: "25%",
+};
+
+interface ProfileDetailsProps {
+ user: User;
+ withUser: string;
+}
+
+export const OtherUserProfileDetails = ({
+ user,
+ withUser,
+}: ProfileDetailsProps) => {
+ const [userDetails, setUserDetails] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ const fetchUserDetails = async () => {
+ try {
+ const user = await getUserByUsername(withUser);
+ if (user) {
+ setUserDetails(user);
+ setLoading(false);
+ } else {
+ setLoading(false);
+ setError("User details not found");
+ }
+ } catch (error) {
+ console.error("Error fetching user details:", error);
+ setLoading(false);
+ setError("Error fetching user details");
+ }
+ };
+
+ fetchUserDetails();
+ }, [withUser]);
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ if (error) {
+ return (
+
+ );
+ }
+
+ if (!userDetails) {
+ return (
+
+ );
+ }
+
+ const withUserRole =
+ user.role === UserRole.PROFESSIONAL
+ ? UserRole.CLIENT
+ : UserRole.PROFESSIONAL;
+
+ return (
+
+
+
+
+ Professional's Information
+
+
+
+
+
+
+
+
+
+ Username:
+ {userDetails.username}
+
+
+
+ Email:
+ {userDetails.email}
+
+
+
+ Full Name:
+
+ {userDetails.firstName} {userDetails.lastName}
+
+
+
+ Role:
+ {withUserRole}
+
+
+
+
+
+ {/* */}
+
+
+
+
+
+ );
+};
diff --git a/app/web/src/components/user/ProfileDetails.tsx b/app/web/src/components/profile/ProfileDetails.tsx
similarity index 95%
rename from app/web/src/components/user/ProfileDetails.tsx
rename to app/web/src/components/profile/ProfileDetails.tsx
index 43fa3cf0..f4e7a876 100644
--- a/app/web/src/components/user/ProfileDetails.tsx
+++ b/app/web/src/components/profile/ProfileDetails.tsx
@@ -28,8 +28,6 @@ import {
import ProfilePicture from "@components/layout/ProfilePicture";
import { User } from "next-auth";
import Link from "next/link";
-import { UserRole } from "@lib/userRole";
-import { CognitoUser } from "@lib/cognito";
interface ProfileDetailsProps {
user: User;
}
@@ -48,7 +46,7 @@ export const ProfileDetails = ({ user }: ProfileDetailsProps) => {