-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/#298 profile page #305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Caution Review failedThe pull request is closed. WalkthroughA 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
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
Assessment against linked issues
Possibly related PRs
Poem
Tip ⚡️ Faster reviews with caching
Enjoy the performance boost—your workflow just got faster. 📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (3)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 lineThere'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 tabsThe 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 listingsThe 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 listThe 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 commentThere'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
⛔ Files ignored due to path filters (3)
apps/core/public/images/_Becomeanauthorapply.pngis excluded by!**/*.pngapps/core/public/images/ali.pngis excluded by!**/*.pngapps/core/public/images/profile-image.jpgis 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 intentionalThis 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 organizedThe 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.
| 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> | ||
| ); | ||
| }; |
There was a problem hiding this comment.
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} /> |
There was a problem hiding this comment.
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.
| <ProductCard key={idx} {...product} /> | |
| {ProductList.map((product, idx) => ( | |
| <ProductCard key={product.id || `product-${idx}`} {...product} /> | |
| ))} |
| <Avatar className="w-32 h-32 border-4 border-background shadow-lg"> | ||
| <AvatarImage className="rounded-xl" sizes="128px" src="/images/ali.png" /> | ||
| </Avatar> |
There was a problem hiding this comment.
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>| <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> |
There was a problem hiding this comment.
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.
| <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> |
| <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> |
There was a problem hiding this comment.
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.
| <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> |
| 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; |
There was a problem hiding this comment.
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
Usertype/interface.
- Define a
Usertype or interface in your shared types (e.g.apps/core/types/user.ts). - Update
apps/core/app/(landing)/genius/[username]/page.tsxto:- Declare the component as
asyncand accept{ params: { username } }. - Call your new API (or direct database/SDK) via
fetchto load user data. - Render a loading or error state when data is missing.
- Declare the component as
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.
- 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.
c9dc897 to
2f28a2f
Compare
Dokploy Preview Deployment
|
Description
Related Issue
Closes #298
Changes
Checks
Summary by CodeRabbit
New Features
Refactor