Skip to content

Commit

Permalink
feat: Update ProfileCard component with thumbnail, name, job title, c…
Browse files Browse the repository at this point in the history
…ompany, and description props and button
  • Loading branch information
chadgrover committed Jul 18, 2024
1 parent f79acc7 commit a23cd38
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 7 deletions.
10 changes: 9 additions & 1 deletion components/ProfileCard/ProfileCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,13 @@ export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {
args: {},
args: {
thumbnail: "images/profile-thumbnail.png",
firstName: "sarah",
lastName: "dole",
jobTitle: "front end engineer",
company: "microsoft",
description:
"I turn coffee into bugs which are fixed by someone else. Certified Stack Overflow and ChatGPT developer.",
},
};
71 changes: 67 additions & 4 deletions components/ProfileCard/ProfileCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,70 @@
"use server";

const ProfileCard = () => {
return <h1>Hello World!</h1>
}
import { memo } from "react";
import Image from "next/image";
import {
formatFullName,
formatButtonVariantClassName,
formatJobTitleAndCompany,
} from "@/lib/utils/formatting";
import { IProfileCardProps, IButtonProps } from "./ProfileCard.types";

export default ProfileCard;
const Button: React.FC<IButtonProps> = ({
type,
addClassName,
children,
variant = "primary",
...rest
}) => {
const BASE_BUTTON_CLASSES =
"w-fit flex flex-row items-center text-base gap-2 p-px";

return (
<button
{...rest}
type={type}
disabled={variant === "disabled"}
className={formatButtonVariantClassName(
variant,
BASE_BUTTON_CLASSES,
addClassName
)}
>
<span>{children}</span>
</button>
);
};

const ProfileCard: React.FC<IProfileCardProps> = memo(
({ thumbnail, firstName, lastName, jobTitle, company, description }) => (
<article className="flex flex-col items-center w-[340px] h-auto bg-white rounded-md drop-shadow-md font-noto-sans px-4 py-6 gap-10">
<header className="flex flex-col items-center gap-6 justify-between">
<Image
src={thumbnail}
alt="The profile picture of the user"
width={64}
height={64}
priority
/>
<div className="flex flex-col items-center gap-px">
<h1 className="text-xl text-neutral-900 font-medium">
{formatFullName(firstName, lastName)}
</h1>
<h2 className="text-sm text-neutral-600 font-light">
{formatJobTitleAndCompany(jobTitle, company)}
</h2>
</div>
<p className="text-base text-neutral-600 font-normal text-center">
{description}
</p>
</header>
<Button type="button" variant="primary">
Contact me
</Button>
</article>
)
);

ProfileCard.displayName = "ProfileCard";

export default ProfileCard;
12 changes: 12 additions & 0 deletions components/ProfileCard/ProfileCard.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IButtonProps } from "@/components/BlogCard/BlogCard.types";

interface IProfileCardProps {
thumbnail: string;
firstName: string;
lastName: string;
jobTitle: string;
company: string;
description: string;
}

export type { IProfileCardProps, IButtonProps };
26 changes: 24 additions & 2 deletions lib/utils/formatting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const formatFullName = (firstName: string, lastName: string): string => {
};

/**
*
*
* @param variant The variant of the button
* @param baseClasses The base classes for the button
* @param addClassName Additional classes to add to the button (optional)
Expand All @@ -36,5 +36,27 @@ const formatButtonVariantClassName = (
}
};

export { formatFullName, formatButtonVariantClassName };
/**
*
* @param jobTitle The job title of the user
* @param company The company the user works for
* @returns A formatted string with the job title and company
*/
const formatJobTitleAndCompany = (
jobTitle: string,
company: string
): string => {
const jobTitleAsArray = jobTitle.split(" ");
jobTitleAsArray.forEach((word, index) => {
jobTitleAsArray[index] = word.charAt(0).toUpperCase() + word.slice(1);
});

const companyAsArray = company.split(" ");
companyAsArray.forEach((word, index) => {
companyAsArray[index] = word.charAt(0).toUpperCase() + word.slice(1);
});

return `${jobTitleAsArray.join(" ")} @ ${companyAsArray.join(" ")}`;
};

export { formatFullName, formatButtonVariantClassName, formatJobTitleAndCompany };

0 comments on commit a23cd38

Please sign in to comment.