Skip to content

Commit

Permalink
feat(profile): Add other user's profile detail in appointment (#722)
Browse files Browse the repository at this point in the history
  • Loading branch information
linhnnk authored Mar 26, 2024
1 parent 836127e commit 49011c0
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 16 deletions.
2 changes: 1 addition & 1 deletion app/web/__tests__/ProfileDetail.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
4 changes: 2 additions & 2 deletions app/web/__tests__/__snapshots__/ProfilePicture.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exports[`ProfilePicture matches snapshot 1`] = `
"baseElement": <body>
<div>
<a
href="/user/profile"
href="/profile"
style="display: flex; flex-direction: column; align-items: center; margin: 0.5rem 0px; text-decoration: none;"
>
<img
Expand All @@ -30,7 +30,7 @@ exports[`ProfilePicture matches snapshot 1`] = `
</body>,
"container": <div>
<a
href="/user/profile"
href="/profile"
style="display: flex; flex-direction: column; align-items: center; margin: 0.5rem 0px; text-decoration: none;"
>
<img
Expand Down
15 changes: 15 additions & 0 deletions app/web/src/app/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ export async function getAllUserData() {
return users;
}

export async function getUserByUsername(
username: string,
): Promise<CognitoUser | null> {
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: {
Expand Down
40 changes: 40 additions & 0 deletions app/web/src/app/profile/[withUser]/page.tsx
Original file line number Diff line number Diff line change
@@ -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 <main>Not logged in</main>;
}
return (
<main>
<OtherUserProfileDetails withUser={params.withUser} user={session.user} />
</main>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const ConversationDropdownMenu = () => {
<DropdownItem value={0} key="action" to="/user">
Homepage
</DropdownItem>
<DropdownItem value={2} key="profile" to="/user/profile">
<DropdownItem value={2} key="profile" to="/profile">
Profile
</DropdownItem>
<DropdownItem value={3} key="signout">
Expand Down
5 changes: 2 additions & 3 deletions app/web/src/components/appointment/inbox/ConversationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const userMetaStyle: CSS = {
};

const profileLinkStyle: CSS = {
fontSize: "0.75rem",
fontSize: "1rem",
};

interface ConversationListProps {
Expand Down Expand Up @@ -166,8 +166,7 @@ export const ConversationList = ({
</Title>
<span style={userMetaStyle}>{user.email}</span>
</div>
{/* TODO: possibly remove this link (do users have profiles?) */}
<Link href="/user/profile" style={profileLinkStyle}>
<Link href="/profile" style={profileLinkStyle}>
View Profile
</Link>
</PanelFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -86,15 +86,14 @@ interface ConversationViewerProps {
withUser: CognitoUser | undefined;
children?: React.ReactNode;
}

export const ConversationViewer = ({
withUser,
children,
}: ConversationViewerProps) => {
const headerText = withUser
? withUser.firstName + " " + withUser.lastName
: "No appointment selected.";

const profilepage = `/profile/${withUser?.username}`;
return (
<Panel style={panelStyle}>
<PanelHeader style={headerStyle}>
Expand All @@ -107,6 +106,7 @@ export const ConversationViewer = ({
<span style={userMetaStyle}>{withUser.email}</span>
) : null}
</div>
{withUser && <Link href={profilepage}>View profile</Link>}
</PanelHeader>
<PanelMain style={panelBodyStyle}>{children}</PanelMain>
</Panel>
Expand Down
2 changes: 1 addition & 1 deletion app/web/src/components/layout/ProfilePicture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function ProfilePicture({
// link to dashboard in place of user profile
const avatar = (
<Link
href={link ?? "/user/profile"}
href={link ?? "/profile"}
style={{ ...styles.link, ...style }}
title={tooltip}
>
Expand Down
163 changes: 163 additions & 0 deletions app/web/src/components/profile/OtherUserProfileDetails.tsx
Original file line number Diff line number Diff line change
@@ -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<CognitoUser | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(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 <div>Loading...</div>;
}

if (error) {
return (
<Alert variant="danger" title={error} style={{ marginTop: "1rem" }} />
);
}

if (!userDetails) {
return (
<Alert
variant="danger"
title="User details not found."
style={{ marginTop: "1rem" }}
/>
);
}

const withUserRole =
user.role === UserRole.PROFESSIONAL
? UserRole.CLIENT
: UserRole.PROFESSIONAL;

return (
<div style={cardContainer}>
<Card aria-label="Personal Information" style={cardStyle}>
<CardHeader style={{ textAlign: "center", marginBottom: "0.5rem" }}>
<CardTitle
component="h2"
style={{ fontSize: "2rem", fontWeight: "bold", margin: 0 }}
>
Professional's Information
</CardTitle>
</CardHeader>

<CardBody>
<Divider />
<Flex
direction={{ default: "row" }}
alignItems={{ default: "alignItemsFlexStart" }}
justifyContent={{ default: "justifyContentSpaceBetween" }}
grow={{ default: "grow" }}
>
<FlexItem>
<Flex direction={{ default: "column" }}>
<FlexItem>
<Title headingLevel="h2">Username:</Title>
<span>{userDetails.username}</span>
</FlexItem>

<FlexItem>
<Title headingLevel="h2">Email:</Title>
<span>{userDetails.email}</span>
</FlexItem>

<FlexItem>
<Title headingLevel="h2">Full Name:</Title>
<span>
{userDetails.firstName} {userDetails.lastName}
</span>
</FlexItem>
<FlexItem>
<Title headingLevel="h2">Role:</Title>
<span>{withUserRole}</span>
</FlexItem>
</Flex>
</FlexItem>

<FlexItem>
{/* <ProfilePicture
tooltip={`Logged in as ${user.username}`}
user={user}
style={{ marginLeft: "1rem" }}
width="100px"
/> */}
</FlexItem>
</Flex>
</CardBody>
</Card>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -48,7 +46,7 @@ export const ProfileDetails = ({ user }: ProfileDetailsProps) => {
<CardBody>
<Divider></Divider>
<Flex
direction={{ default: "row" }} // Set direction to "row"
direction={{ default: "row" }}
alignItems={{ default: "alignItemsFlexStart" }}
justifyContent={{ default: "justifyContentSpaceBetween" }}
grow={{ default: "grow" }}
Expand Down

0 comments on commit 49011c0

Please sign in to comment.