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
ReactTailwind
TSX
npx @uiblox/cli add user-profile

Preview

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
"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; }