Skip to content

Conversation

@alikashef
Copy link
Contributor

@alikashef alikashef commented May 9, 2025

Description

Related Issue

Closes #298

Changes

Checks

  • Storybook updated
  • Build succeeds
  • Standards followed

Summary by CodeRabbit

  • New Features

    • Introduced a user profile page with a cover image, avatar, user details, and a tabbed interface for Products, Favorites, and About sections.
    • Products are displayed in a responsive grid; About includes biography and skills.
  • Refactor

    • Removed the Typography test component and its related exports from the shared UI library.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 9, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

A new user profile page was implemented as a React component, featuring a tabbed interface for products, favorites, and about sections. The update also removes an old generic Typography component and its export from the UI library, reflecting a shift to a different Typography implementation.

Changes

File(s) Change Summary
apps/core/app/(landing)/genius/[username]/page.tsx Added new ProfilePage React component with cover, avatar, tabbed sections (Products, Favorite, About), and mock data.
packages/ui/src/components/atoms/typo-test.tsx Deleted the old generic Typography component and related TypeScript types.
packages/ui/src/components/index.ts Removed export for the deleted typo-test Typography component.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ProfilePage
    participant UIComponents

    User->>ProfilePage: Visit /genius/[username]
    ProfilePage->>UIComponents: Render Avatar, Typography, Tabs, ProductCard, Chip
    ProfilePage-->>User: Display profile with Products, Favorites, About tabs
    User->>ProfilePage: Switch tabs
    ProfilePage-->>User: Update displayed content accordingly
Loading

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Implement profile page (#298)

Possibly related PRs

Poem

A profile page, shiny and new,
With tabs and cards in every view.
Old Typography hops away,
As fresh designs come out to play.
Chips and avatars now delight—
The rabbit twitches with pure delight!
🐇✨

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9dc897 and 2f28a2f.

⛔ Files ignored due to path filters (3)
  • apps/core/public/images/_Becomeanauthorapply.png is excluded by !**/*.png
  • apps/core/public/images/ali.png is excluded by !**/*.png
  • apps/core/public/images/profile-image.jpg is excluded by !**/*.jpg
📒 Files selected for processing (3)
  • apps/core/app/(landing)/genius/[username]/page.tsx (1 hunks)
  • packages/ui/src/components/atoms/typo-test.tsx (0 hunks)
  • packages/ui/src/components/index.ts (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@mrbadri mrbadri self-requested a review May 9, 2025 11:15
@mrbadri
Copy link
Contributor

mrbadri commented May 9, 2025

This pull request is related to issue #298

Closes #298

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
apps/core/app/(landing)/genius/[username]/page.tsx (5)

36-37: Remove empty line

There's an unnecessary empty line within the JSX structure.

<Typography variant="label/md" weight="light" align="center" className="text-muted-foreground pt-2">
  Product Design, Web Design
</Typography>
-       
</div>

39-46: Use semantic HTML for tabs

The TabProvider component with TabList should have proper ARIA roles for improved accessibility.

-<TabProvider defaultValue="products">
+<TabProvider defaultValue="products" aria-label="Profile sections">
  
-  <TabList className="justify-start bg-card px-3 py-3 rounded-md">
+  <TabList className="justify-start bg-card px-3 py-3 rounded-md" role="tablist">
     <TabTrigger value="products">Products</TabTrigger>
     <TabTrigger value="favorite">Favorite</TabTrigger>
     <TabTrigger value="about">About</TabTrigger>
   </TabList>

This enhances the accessibility of the tab interface for screen reader users.


49-55: Add pagination for product listings

The products tab shows all products at once, which could lead to performance issues with large product lists.

Consider adding pagination when the number of products exceeds a certain threshold (e.g., 12 products):

{ProductList.length > 0 ? (
  <>
    <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 mt-6">
      {ProductList.slice(0, currentPage * 12).map((product, idx) => (
        <ProductCard key={product.id || idx} {...product} />
      ))}
    </div>
    {ProductList.length > 12 && (
      <div className="mt-8 flex justify-center">
        <Pagination />
      </div>
    )}
  </>
) : (
  <div className="flex flex-col items-center justify-center py-16">
    <Typography variant="heading/md" weight="bold" align="center">
      No products yet
    </Typography>
  </div>
)}

88-92: Use a consistent approach for skills list

The skills list is currently hardcoded within the component. Consider extracting this to a constant or props.

+ const SKILLS = ['UI/UX', 'Logo', 'Vector', 'Web Design', 'Animation'];

// Then in the component:
<div className="flex flex-wrap gap-2">
- {['UI/UX', 'Logo', 'Vector', 'web design', 'Animation'].map(skill => (
+ {SKILLS.map(skill => (
    <Chip 
      key={skill} 
      variant="secondary" 
      className="bg-black text-white font-medium px-4 py-2 rounded-md"
    >
      {skill}
    </Chip>
  ))}
</div>

This makes it easier to maintain and potentially receive from props or API data in the future.


102-103: Remove empty comment

There's an empty comment section that doesn't provide any value.

-  {/* Profile Info */}
-    
   </div>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bbe287d and c9dc897.

⛔ Files ignored due to path filters (3)
  • apps/core/public/images/_Becomeanauthorapply.png is excluded by !**/*.png
  • apps/core/public/images/ali.png is excluded by !**/*.png
  • apps/core/public/images/profile-image.jpg is excluded by !**/*.jpg
📒 Files selected for processing (3)
  • apps/core/app/(landing)/genius/[username]/page.tsx (1 hunks)
  • packages/ui/src/components/atoms/typo-test.tsx (0 hunks)
  • packages/ui/src/components/index.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/ui/src/components/atoms/typo-test.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: merge-pr
🔇 Additional comments (2)
packages/ui/src/components/index.ts (1)

49-50: Removal of Typography export looks intentional

This change removes the export for "./atoms/typo-test", which aligns with the PR's purpose of replacing an older Typography component implementation. The file appears to be exporting a different Typography component from "./atoms/typography" on line 49 that is used by the new profile page.

apps/core/app/(landing)/genius/[username]/page.tsx (1)

1-8: Imports are properly organized

The component imports from the UI library (@repo/ui/components) and Next.js are well-structured. The Typography component being imported here is using the new implementation as intended by the changes in the index.ts file.

Comment on lines +9 to +106
const ProfilePage = () => {
return (
<div className="min-h-screen bg-background">
{/* Cover Image */}
<div className="relative z-0 w-full h-[400px] sm:h-[400px] md:h-[400px]">
<Image
src="/images/profile-image.jpg"
alt="Profile Cover"
fill
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-b from-transparent to-black/90" />
</div>
<div className='container relative -mt-20 sm:-mt-24 md:-mt-44 mx-auto z-10 '>
<div className=" flex flex-row gap-2 items-center">
<div className='flex flex-col items-center justify-center pb-6'>
<Avatar className="w-32 h-32 border-4 border-background shadow-lg">
<AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
</Avatar>
</div>
<div className='flex flex-col items-start justify-start'>
<Typography variant="heading/md" weight="medium" align="center" className="text-white">
Ali Ebrahimi Kashef
</Typography>
<Typography variant="label/md" weight="light" align="center" className="text-muted-foreground pt-2">
Product Design, Web Design
</Typography>

</div>
</div>

<TabProvider defaultValue="products">

<TabList className="justify-start bg-card px-3 py-3 rounded-md">
<TabTrigger value="products">Products</TabTrigger>
<TabTrigger value="favorite">Favorite</TabTrigger>
<TabTrigger value="about">About</TabTrigger>
</TabList>

{/* Products Tab */}
<TabContent value="products">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 mt-6">
{ProductList.map((product, idx) => (
<ProductCard key={idx} {...product} />
))}
</div>
</TabContent>

{/* Favorite Tab */}
<TabContent value="favorite">
<div className="flex flex-col items-center justify-center py-16">
<Typography variant="heading/md" weight="bold" align="center">
No favorites yet
</Typography>
<Typography variant="paragraph/md" align="center" className="text-muted-foreground mt-2">
Products you favorite will appear here.
</Typography>
</div>
</TabContent>

{/* About Tab */}
<TabContent value="about">
<div className="flex flex-col items-center justify-center w-full mt-8">
<div className="w-full bg-card rounded-xl flex flex-col md:flex-row justify-between items-start md:items-stretch p-6 gap-8">
{/* Biography */}
<div className="flex-1 min-w-0">
<Typography variant="heading/sm" weight="bold" className="mb-2 text-white">
Biography
</Typography>
<Typography variant="paragraph/md" className="text-muted-foreground">
A freelance graphic and UI/UX designer. I specialise in Web Design, logo and brand development, motion graphics, and offer design services to business of all sizes.
</Typography>
</div>
{/* Skills */}
<div className="flex flex-col min-w-[220px]">
<Typography variant="heading/sm" weight="bold" className="mb-2 text-white">
Skills
</Typography>
<div className="flex flex-wrap gap-2">
{['UI/UX', 'Logo', 'Vector', 'web design', 'Animation'].map(skill => (
<Chip key={skill} variant="secondary" className="bg-black text-white font-medium px-4 py-2 rounded-md">
{skill}
</Chip>
))}
</div>
</div>
</div>
</div>
</TabContent>
</TabProvider>

</div>

{/* Profile Info */}

</div>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Extract data to props or mock data file

The component contains hardcoded user data that should be extracted to either props or a separate mock data file.

Consider restructuring the component to receive user data as props:

const ProfilePage = ({ 
  userData = {
    name: "Ali Ebrahimi Kashef",
    profession: "Product Design, Web Design",
    coverImage: "/images/profile-image.jpg",
    avatar: "/images/ali.png",
    biography: "A freelance graphic and UI/UX designer. I specialise in Web Design, logo and brand development, motion graphics, and offer design services to business of all sizes.",
    skills: ['UI/UX', 'Logo', 'Vector', 'Web Design', 'Animation']
  },
  products = ProductList 
}) => {
  // Component implementation using userData and products instead of hardcoded values
}

This would make the component more reusable and easier to test, as well as prepare it for fetching real data from an API.

<TabContent value="products">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 mt-6">
{ProductList.map((product, idx) => (
<ProductCard key={idx} {...product} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use unique identifiers for keys instead of array indices

Using array indices as keys can lead to rendering issues if the list order changes.

{ProductList.map((product, idx) => (
-  <ProductCard key={idx} {...product} />
+  <ProductCard key={product.id || `product-${idx}`} {...product} />
))}

This assumes product objects have an id property. If not, generate a more meaningful key using a prefix with the index.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<ProductCard key={idx} {...product} />
{ProductList.map((product, idx) => (
<ProductCard key={product.id || `product-${idx}`} {...product} />
))}

Comment on lines +25 to +27
<Avatar className="w-32 h-32 border-4 border-background shadow-lg">
<AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
</Avatar>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add alt text for avatar image

The AvatarImage component is missing alternative text for accessibility.

<Avatar className="w-32 h-32 border-4 border-background shadow-lg">
-  <AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
+  <AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" alt="Ali Ebrahimi Kashef" />
</Avatar>

Comment on lines +13 to +21
<div className="relative z-0 w-full h-[400px] sm:h-[400px] md:h-[400px]">
<Image
src="/images/profile-image.jpg"
alt="Profile Cover"
fill
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-b from-transparent to-black/90" />
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve accessibility for cover image

The cover image should have better accessibility support, especially since it's a significant part of the profile UI.

 <div className="relative z-0  w-full h-[400px] sm:h-[400px] md:h-[400px]">
   <Image
     src="/images/profile-image.jpg"
     alt="Profile Cover"
     fill
-    className="object-cover"
+    className="object-cover"
+    priority
   />
   <div className="absolute inset-0 bg-gradient-to-b from-transparent to-black/90" />
 </div>

Add the priority prop to the Image component to improve the Largest Contentful Paint (LCP) metric, as this is likely a key visual element.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="relative z-0 w-full h-[400px] sm:h-[400px] md:h-[400px]">
<Image
src="/images/profile-image.jpg"
alt="Profile Cover"
fill
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-b from-transparent to-black/90" />
</div>
<div className="relative z-0 w-full h-[400px] sm:h-[400px] md:h-[400px]">
<Image
src="/images/profile-image.jpg"
alt="Profile Cover"
fill
className="object-cover"
priority
/>
<div className="absolute inset-0 bg-gradient-to-b from-transparent to-black/90" />
</div>

Comment on lines +22 to +38
<div className='container relative -mt-20 sm:-mt-24 md:-mt-44 mx-auto z-10 '>
<div className=" flex flex-row gap-2 items-center">
<div className='flex flex-col items-center justify-center pb-6'>
<Avatar className="w-32 h-32 border-4 border-background shadow-lg">
<AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
</Avatar>
</div>
<div className='flex flex-col items-start justify-start'>
<Typography variant="heading/md" weight="medium" align="center" className="text-white">
Ali Ebrahimi Kashef
</Typography>
<Typography variant="label/md" weight="light" align="center" className="text-muted-foreground pt-2">
Product Design, Web Design
</Typography>

</div>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix inconsistent spacing and improve avatar accessibility

There's inconsistent spacing in the JSX structure and the Avatar component needs better accessibility.

<div className='container relative -mt-20 sm:-mt-24 md:-mt-44 mx-auto z-10 '>
- <div className=" flex flex-row gap-2 items-center">
+ <div className="flex flex-row gap-4 items-center">
    <div className='flex flex-col items-center justify-center pb-6'>
-   <Avatar className="w-32 h-32 border-4 border-background shadow-lg">
+   <Avatar className="w-32 h-32 border-4 border-background shadow-lg" aria-label="User profile picture">
      <AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
    </Avatar>
    </div>
    <div className='flex flex-col items-start justify-start'>

This improves spacing between elements and adds an aria-label to the Avatar component for better screen reader support.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className='container relative -mt-20 sm:-mt-24 md:-mt-44 mx-auto z-10 '>
<div className=" flex flex-row gap-2 items-center">
<div className='flex flex-col items-center justify-center pb-6'>
<Avatar className="w-32 h-32 border-4 border-background shadow-lg">
<AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
</Avatar>
</div>
<div className='flex flex-col items-start justify-start'>
<Typography variant="heading/md" weight="medium" align="center" className="text-white">
Ali Ebrahimi Kashef
</Typography>
<Typography variant="label/md" weight="light" align="center" className="text-muted-foreground pt-2">
Product Design, Web Design
</Typography>
</div>
</div>
<div className='container relative -mt-20 sm:-mt-24 md:-mt-44 mx-auto z-10 '>
<div className="flex flex-row gap-4 items-center">
<div className='flex flex-col items-center justify-center pb-6'>
<Avatar className="w-32 h-32 border-4 border-background shadow-lg" aria-label="User profile picture">
<AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
</Avatar>
</div>
<div className='flex flex-col items-start justify-start'>
<Typography variant="heading/md" weight="medium" align="center" className="text-white">
Ali Ebrahimi Kashef
</Typography>
<Typography variant="label/md" weight="light" align="center" className="text-muted-foreground pt-2">
Product Design, Web Design
</Typography>
</div>
</div>

Comment on lines +1 to +108
import { Avatar, AvatarImage } from '@repo/ui/components';
import Image from 'next/image';
import {Typography} from '@repo/ui/components';
import { TabProvider, TabList, TabTrigger, TabContent } from '@repo/ui/components';
import { ProductCard } from '@repo/ui/components';
import { ProductList } from '../../_constant/mock-product-list';
import { Chip } from '@repo/ui/components';

const ProfilePage = () => {
return (
<div className="min-h-screen bg-background">
{/* Cover Image */}
<div className="relative z-0 w-full h-[400px] sm:h-[400px] md:h-[400px]">
<Image
src="/images/profile-image.jpg"
alt="Profile Cover"
fill
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-b from-transparent to-black/90" />
</div>
<div className='container relative -mt-20 sm:-mt-24 md:-mt-44 mx-auto z-10 '>
<div className=" flex flex-row gap-2 items-center">
<div className='flex flex-col items-center justify-center pb-6'>
<Avatar className="w-32 h-32 border-4 border-background shadow-lg">
<AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" />
</Avatar>
</div>
<div className='flex flex-col items-start justify-start'>
<Typography variant="heading/md" weight="medium" align="center" className="text-white">
Ali Ebrahimi Kashef
</Typography>
<Typography variant="label/md" weight="light" align="center" className="text-muted-foreground pt-2">
Product Design, Web Design
</Typography>

</div>
</div>

<TabProvider defaultValue="products">

<TabList className="justify-start bg-card px-3 py-3 rounded-md">
<TabTrigger value="products">Products</TabTrigger>
<TabTrigger value="favorite">Favorite</TabTrigger>
<TabTrigger value="about">About</TabTrigger>
</TabList>

{/* Products Tab */}
<TabContent value="products">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 mt-6">
{ProductList.map((product, idx) => (
<ProductCard key={idx} {...product} />
))}
</div>
</TabContent>

{/* Favorite Tab */}
<TabContent value="favorite">
<div className="flex flex-col items-center justify-center py-16">
<Typography variant="heading/md" weight="bold" align="center">
No favorites yet
</Typography>
<Typography variant="paragraph/md" align="center" className="text-muted-foreground mt-2">
Products you favorite will appear here.
</Typography>
</div>
</TabContent>

{/* About Tab */}
<TabContent value="about">
<div className="flex flex-col items-center justify-center w-full mt-8">
<div className="w-full bg-card rounded-xl flex flex-col md:flex-row justify-between items-start md:items-stretch p-6 gap-8">
{/* Biography */}
<div className="flex-1 min-w-0">
<Typography variant="heading/sm" weight="bold" className="mb-2 text-white">
Biography
</Typography>
<Typography variant="paragraph/md" className="text-muted-foreground">
A freelance graphic and UI/UX designer. I specialise in Web Design, logo and brand development, motion graphics, and offer design services to business of all sizes.
</Typography>
</div>
{/* Skills */}
<div className="flex flex-col min-w-[220px]">
<Typography variant="heading/sm" weight="bold" className="mb-2 text-white">
Skills
</Typography>
<div className="flex flex-wrap gap-2">
{['UI/UX', 'Logo', 'Vector', 'web design', 'Animation'].map(skill => (
<Chip key={skill} variant="secondary" className="bg-black text-white font-medium px-4 py-2 rounded-md">
{skill}
</Chip>
))}
</div>
</div>
</div>
</div>
</TabContent>
</TabProvider>

</div>

{/* Profile Info */}

</div>
);
};

export default ProfilePage;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Add data fetching for dynamic profiles

The component is intended to display user profiles based on the username route parameter but currently uses hardcoded data.

Since this is a Next.js page component with a dynamic route parameter [username], it should fetch user data based on this parameter. Consider implementing:

// This could be at the top of the file
async function getProfileData(username) {
  // In a real implementation, this would fetch from an API
  try {
    const response = await fetch(`/api/users/${username}`);
    if (!response.ok) throw new Error('Failed to fetch user data');
    return await response.json();
  } catch (error) {
    console.error('Error fetching profile data:', error);
    return null;
  }
}

// Then make the page component async
const ProfilePage = async ({ params }) => {
  const { username } = params;
  const userData = await getProfileData(username);
  
  if (!userData) {
    return <div>User not found</div>;
  }
  
  // Rest of component using userData instead of hardcoded values
}

🏁 Script executed:

#!/bin/bash
# Check if there's an API route defined for fetching user profiles

echo "Checking for API routes for user profiles..."
fd -t f "route.ts" apps/core/app/api -x cat {} \; | grep -A 10 -B 10 "users"

echo "Checking for any user data models or types..."
rg -t typescript "type User" --glob "!node_modules"
rg -t typescript "interface User" --glob "!node_modules"

Length of output: 565


Implement Dynamic Profile Data Fetching

The [username] page is currently using hardcoded data. To support real user profiles you should:

  • Create an API route to fetch user data, for example:
    • apps/core/app/api/users/[username]/route.ts
    • Return a JSON payload conforming to a User type/interface.
  • Define a User type or interface in your shared types (e.g. apps/core/types/user.ts).
  • Update apps/core/app/(landing)/genius/[username]/page.tsx to:
    • Declare the component as async and accept { params: { username } }.
    • Call your new API (or direct database/SDK) via fetch to load user data.
    • Render a loading or error state when data is missing.

Example diff in page.tsx:

+ // apps/core/app/types/user.ts
+ export interface User {
+   name: string;
+   avatarUrl: string;
+   bio: string;
+   skills: string[];
+   // …other fields
+ }
+
+ // apps/core/app/api/users/[username]/route.ts
+ import { NextResponse } from 'next/server';
+ import { fetchUserByUsername } from '@/lib/user';
+
+ export async function GET(
+   _req: Request,
+   { params: { username } }
+ ) {
+   const user = await fetchUserByUsername(username);
+   if (!user) return NextResponse.json({ message: 'Not found' }, { status: 404 });
+   return NextResponse.json(user);
+ }
+
  // apps/core/app/(landing)/genius/[username]/page.tsx
- const ProfilePage = () => {
+ import { User } from '@/types/user';
+
+ async function getProfileData(username: string): Promise<User | null> {
+   const res = await fetch(`/api/users/${username}`);
+   if (!res.ok) return null;
+   return res.json();
+ }
+
+ const ProfilePage = async ({
+   params: { username },
+ }: {
+   params: { username: string };
+ }) => {
+   const userData = await getProfileData(username);
+   if (!userData) return <div>User not found</div>;
+
+   // replace hardcoded values with userData.{…}

This ensures your page loads real profiles, not static placeholders.

Committable suggestion skipped: line range outside the PR's diff.

alikashef added 2 commits May 12, 2025 09:51
- Created a new ProfilePage component featuring a cover image, user avatar, and user details.
- Implemented a tabbed interface with sections for Products, Favorites, and About.
- Added mock product data and integrated ProductCard component for product display.
- Included new images for user profile and cover.
- Introduced a new ProfilePage component featuring a cover image, user avatar, and user information.
- Implemented a tabbed layout with sections for Products, Favorites, and About, utilizing the TabProvider component.
- Integrated ProductCard for displaying products and included mock product data.
- Removed unused Typography component from the UI library.
@mrbadri mrbadri force-pushed the feat/#298-profile-page branch from c9dc897 to 2f28a2f Compare May 12, 2025 16:52
@pixel-dockploy
Copy link

Dokploy Preview Deployment

Name Status Preview Updated (UTC)
client 🔄 Building Preview URL 2025-05-12T16:52:43.825Z

@mrbadri mrbadri merged commit 484c149 into main May 12, 2025
@mrbadri mrbadri deleted the feat/#298-profile-page branch May 12, 2025 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

profile page

3 participants