diff --git a/frontend/components/profile/AchievementPreview.tsx b/frontend/components/profile/AchievementPreview.tsx new file mode 100644 index 0000000..bae93af --- /dev/null +++ b/frontend/components/profile/AchievementPreview.tsx @@ -0,0 +1,54 @@ +"use client"; + +import Image from "next/image"; +import { AchievementCard } from "./AchievementCard"; +import type { Achievement } from "./UserProfileView"; + +interface AchievementPreviewProps { + achievements: Achievement[]; + onViewAllAchievements: () => void; +} + +export function AchievementPreview({ + achievements, + onViewAllAchievements, +}: AchievementPreviewProps) { + const visibleAchievements = achievements.slice(0, 3); + + return ( +
+
+

Achievements

+ +
+ +
+ {visibleAchievements.map((achievement) => ( + + } + title={achievement.title} + date={achievement.date} + badge={achievement.value} + /> + ))} +
+
+ ); +} + diff --git a/frontend/components/profile/FollowButton.tsx b/frontend/components/profile/FollowButton.tsx new file mode 100644 index 0000000..e6e3ce5 --- /dev/null +++ b/frontend/components/profile/FollowButton.tsx @@ -0,0 +1,49 @@ +"use client"; + +import { UserCheck, UserPlus } from "lucide-react"; +import Button from "../Button"; + +interface FollowButtonProps { + isFollowing: boolean; + onFollow: () => void; + onUnfollow: () => void; +} + +export function FollowButton({ + isFollowing, + onFollow, + onUnfollow, +}: FollowButtonProps) { + const handleClick = () => { + if (isFollowing) { + onUnfollow(); + } else { + onFollow(); + } + }; + + const Icon = isFollowing ? UserCheck : UserPlus; + + if (isFollowing) { + return ( + + ); + } + + return ( + + ); +} + diff --git a/frontend/components/profile/OverviewCard.tsx b/frontend/components/profile/OverviewCard.tsx new file mode 100644 index 0000000..f0e75bd --- /dev/null +++ b/frontend/components/profile/OverviewCard.tsx @@ -0,0 +1,4 @@ +import { StatCard } from "./StatCard"; + +export { StatCard as OverviewCard }; + diff --git a/frontend/components/profile/OverviewGrid.tsx b/frontend/components/profile/OverviewGrid.tsx new file mode 100644 index 0000000..fb8ac5d --- /dev/null +++ b/frontend/components/profile/OverviewGrid.tsx @@ -0,0 +1,4 @@ +import { ProfileOverview } from "./ProfileOverview"; + +export { ProfileOverview as OverviewGrid }; + diff --git a/frontend/components/profile/ProfileStats.tsx b/frontend/components/profile/ProfileStats.tsx new file mode 100644 index 0000000..20e5e77 --- /dev/null +++ b/frontend/components/profile/ProfileStats.tsx @@ -0,0 +1,37 @@ +"use client"; + +interface ProfileStatsProps { + followingCount: number; + followersCount: number; + onFollowingClick: () => void; + onFollowersClick: () => void; +} + +export function ProfileStats({ + followingCount, + followersCount, + onFollowingClick, + onFollowersClick, +}: ProfileStatsProps) { + return ( +
+ + +
+ ); +} + diff --git a/frontend/components/profile/UserProfileView.tsx b/frontend/components/profile/UserProfileView.tsx new file mode 100644 index 0000000..3a00645 --- /dev/null +++ b/frontend/components/profile/UserProfileView.tsx @@ -0,0 +1,151 @@ +"use client"; + +import { X, Share2 } from "lucide-react"; +import { + Avatar, + AvatarFallback, + AvatarImage, +} from "@radix-ui/react-avatar"; +import { FollowButton } from "./FollowButton"; +import { ProfileStats } from "./ProfileStats"; +import { OverviewGrid } from "./OverviewGrid"; +import { AchievementPreview } from "./AchievementPreview"; + +export interface Achievement { + id: string; + icon: string; + title: string; + value: string; + date: string; +} + +export interface UserProfileViewProps { + id: string; + username: string; + handle: string; + avatar: string; + joinedDate: string; + followingCount: number; + followersCount: number; + isFollowing: boolean; + dayStreak: number; + totalPoints: number; + rank: number; + challengeLevel: string; + achievements: Achievement[]; + onFollow: () => void; + onUnfollow: () => void; + onShare: () => void; + onFollowingClick: () => void; + onFollowersClick: () => void; + onClose: () => void; + onViewAllAchievements: () => void; +} + +export function UserProfileView(props: UserProfileViewProps) { + const { + username, + handle, + avatar, + joinedDate, + followingCount, + followersCount, + isFollowing, + dayStreak, + totalPoints, + rank, + challengeLevel, + achievements, + onFollow, + onUnfollow, + onShare, + onFollowingClick, + onFollowersClick, + onClose, + onViewAllAchievements, + } = props; + + const initials = username + .split(" ") + .map((n) => n[0]) + .join(""); + + return ( +
+
+ {/* Close button */} + + +
+ {/* Avatar & basic info */} +
+ + + + {initials} + + + +
+

+ {username} +

+

@{handle}

+

+ Joined {joinedDate} +

+
+
+ + {/* Stats row */} + + + {/* Action bar */} +
+ + +
+ +
+ {/* Overview grid */} + + + + {/* Achievements preview */} + +
+
+
+
+ ); +} +