Blox/
User Profile
A comprehensive user profile page with cover image, avatar, stats, tabs, skills, and social links. Perfect for social platforms and professional networks.
Cover ImageProfile StatsTabsSkillsSocial Links
Installation
Terminal
TSXReactTailwind
npx @uiblox/cli add user-profilePreview
SA
Sarah Anderson
Product Designer
12.5k
Followers
890
Following
48
Projects
About
Passionate about creating beautiful, user-centered digital experiences.
Skills
UI DesignUX ResearchFigmaPrototyping
San Francisco, CA
Joined Jan 2022
Source Code
user-profile.tsx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196"use client"; import { useState } from "react"; import { cn } from "@/lib/utils"; interface UserProfile { name: string; username: string; email: string; avatar: string; role: string; location: string; bio: string; joinedDate: string; stats: { followers: number; following: number; projects: number; }; skills: string[]; socialLinks: { platform: string; url: string; icon: string }[]; } const user: UserProfile = { name: "Sarah Anderson", username: "@sarahanderson", email: "sarah@example.com", avatar: "/avatar.jpg", role: "Senior Product Designer", location: "San Francisco, CA", bio: "Passionate about creating beautiful, user-centered digital experiences. Currently designing the future at TechCorp.", joinedDate: "January 2022", stats: { followers: 12500, following: 890, projects: 48 }, skills: ["UI Design", "UX Research", "Figma", "Prototyping", "Design Systems"], socialLinks: [ { platform: "Twitter", url: "#", icon: "twitter" }, { platform: "LinkedIn", url: "#", icon: "linkedin" }, { platform: "GitHub", url: "#", icon: "github" }, { platform: "Dribbble", url: "#", icon: "dribbble" }, ], }; const tabs = ["Overview", "Projects", "Activity", "Settings"]; export function UserProfile() { const [activeTab, setActiveTab] = useState("Overview"); const [isFollowing, setIsFollowing] = useState(false); return ( <div className="max-w-4xl mx-auto"> {/* Cover & Avatar */} <div className="relative"> <div className="h-48 bg-gradient-to-r from-purple-500 via-pink-500 to-cyan-500 rounded-t-xl" /> <div className="absolute -bottom-16 left-8 flex items-end gap-6"> <div className="w-32 h-32 rounded-full border-4 border-white dark:border-slate-900 bg-slate-200 dark:bg-slate-700 flex items-center justify-center text-4xl font-bold text-white overflow-hidden"> SA </div> <div className="pb-2"> <h1 className="text-2xl font-bold text-white drop-shadow-lg">{user.name}</h1> <p className="text-white/80 drop-shadow">{user.role}</p> </div> </div> </div> {/* Profile Content */} <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-b-xl pt-20 px-8 pb-8"> {/* Actions */} <div className="flex items-center justify-end gap-3 mb-6"> <button className="px-4 py-2 border border-slate-200 dark:border-slate-700 rounded-lg text-sm font-medium hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"> Message </button> <button onClick={() => setIsFollowing(!isFollowing)} className={cn( "px-4 py-2 rounded-lg text-sm font-medium transition-colors", isFollowing ? "bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300" : "bg-purple-600 hover:bg-purple-700 text-white" )} > {isFollowing ? "Following" : "Follow"} </button> </div> {/* Stats */} <div className="flex gap-8 mb-6 pb-6 border-b border-slate-200 dark:border-slate-800"> <div className="text-center"> <p className="text-2xl font-bold text-slate-900 dark:text-white">{user.stats.followers.toLocaleString()}</p> <p className="text-sm text-slate-500">Followers</p> </div> <div className="text-center"> <p className="text-2xl font-bold text-slate-900 dark:text-white">{user.stats.following.toLocaleString()}</p> <p className="text-sm text-slate-500">Following</p> </div> <div className="text-center"> <p className="text-2xl font-bold text-slate-900 dark:text-white">{user.stats.projects}</p> <p className="text-sm text-slate-500">Projects</p> </div> </div> {/* Tabs */} <div className="flex gap-1 mb-6 border-b border-slate-200 dark:border-slate-800"> {tabs.map((tab) => ( <button key={tab} onClick={() => setActiveTab(tab)} className={cn( "px-4 py-3 text-sm font-medium transition-colors relative", activeTab === tab ? "text-purple-600" : "text-slate-500 hover:text-slate-700 dark:hover:text-slate-300" )} > {tab} {activeTab === tab && ( <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-purple-600" /> )} </button> ))} </div> {/* Tab Content */} <div className="grid md:grid-cols-3 gap-6"> <div className="md:col-span-2 space-y-6"> {/* About */} <div> <h3 className="text-lg font-semibold text-slate-900 dark:text-white mb-3">About</h3> <p className="text-slate-600 dark:text-slate-400">{user.bio}</p> </div> {/* Skills */} <div> <h3 className="text-lg font-semibold text-slate-900 dark:text-white mb-3">Skills</h3> <div className="flex flex-wrap gap-2"> {user.skills.map((skill) => ( <span key={skill} className="px-3 py-1 bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 rounded-full text-sm"> {skill} </span> ))} </div> </div> </div> {/* Sidebar */} <div className="space-y-6"> {/* Info */} <div className="p-4 bg-slate-50 dark:bg-slate-800/50 rounded-xl space-y-3"> <div className="flex items-center gap-2 text-sm"> <LocationIcon /> <span className="text-slate-600 dark:text-slate-400">{user.location}</span> </div> <div className="flex items-center gap-2 text-sm"> <EmailIcon /> <span className="text-slate-600 dark:text-slate-400">{user.email}</span> </div> <div className="flex items-center gap-2 text-sm"> <CalendarIcon /> <span className="text-slate-600 dark:text-slate-400">Joined {user.joinedDate}</span> </div> </div> {/* Social Links */} <div> <h4 className="text-sm font-semibold text-slate-900 dark:text-white mb-3">Connect</h4> <div className="flex gap-2"> {user.socialLinks.map((link) => ( <a key={link.platform} href={link.url} className="p-2 bg-slate-100 dark:bg-slate-800 hover:bg-slate-200 dark:hover:bg-slate-700 rounded-lg transition-colors" title={link.platform} > <SocialIcon name={link.icon} /> </a> ))} </div> </div> </div> </div> </div> </div> ); } function LocationIcon() { return <svg className="w-4 h-4 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" /><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" /></svg>; } function EmailIcon() { return <svg className="w-4 h-4 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /></svg>; } function CalendarIcon() { return <svg className="w-4 h-4 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>; } function SocialIcon({ name }: { name: string }) { const icons: Record<string, JSX.Element> = { twitter: <svg className="w-4 h-4 text-slate-600 dark:text-slate-400" fill="currentColor" viewBox="0 0 24 24"><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg>, linkedin: <svg className="w-4 h-4 text-slate-600 dark:text-slate-400" fill="currentColor" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>, github: <svg className="w-4 h-4 text-slate-600 dark:text-slate-400" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>, dribbble: <svg className="w-4 h-4 text-slate-600 dark:text-slate-400" fill="currentColor" viewBox="0 0 24 24"><path d="M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12-5.385 12-12 12zm10.12-10.358c-.35-.11-3.17-.953-6.384-.438 1.34 3.684 1.887 6.684 1.992 7.308 2.3-1.555 3.936-4.02 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4 1.73 1.358 3.92 2.166 6.29 2.166 1.42 0 2.77-.29 4-.82zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765.135-.045.27-.084.405-.12-.26-.585-.54-1.167-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248-1.698-3.018-3.53-5.558-3.8-5.928-2.868 1.35-5.01 3.99-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6 3.645-1.365 5.19-3.44 5.373-3.702-1.81-1.61-4.19-2.586-6.795-2.586-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04.24.49.47.985.68 1.486.08.18.15.36.22.53 3.41-.43 6.8.26 7.14.33-.02-2.42-.88-4.64-2.31-6.38z"/></svg>, }; return icons[name] || null; }