Skip to content

Commit 2c4a149

Browse files
committed
feat(connections): Enhance user search and empty state UI with improved interactions
- Add clear search button to search input for better UX - Redesign empty state views for followers, following, and search tabs - Improve search input placeholder and styling - Add subtle animations and visual indicators for empty states - Enhance search functionality with minimum character requirement feedback - Improve overall visual hierarchy and user guidance in connections page
1 parent 4f06954 commit 2c4a149

File tree

5 files changed

+124
-36
lines changed

5 files changed

+124
-36
lines changed

app/protected/connections/page.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,35 @@ export default function ConnectionsPage() {
5555

5656
<TabsContent value="search" className="flex-1 overflow-y-auto space-y-3">
5757
<div className="relative mb-4">
58-
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
58+
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
5959
<Input
60-
placeholder="Search for users to connect..."
60+
placeholder="Search by name or username..."
6161
value={searchQuery}
6262
onChange={(e) => setSearchQuery(e.target.value)}
63-
className="pl-9"
63+
className="pl-9 pr-9"
6464
/>
65+
{searchQuery && (
66+
<button
67+
onClick={() => setSearchQuery('')}
68+
className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
69+
aria-label="Clear search"
70+
>
71+
<svg
72+
xmlns="http://www.w3.org/2000/svg"
73+
width="16"
74+
height="16"
75+
viewBox="0 0 24 24"
76+
fill="none"
77+
stroke="currentColor"
78+
strokeWidth="2"
79+
strokeLinecap="round"
80+
strokeLinejoin="round"
81+
>
82+
<line x1="18" y1="6" x2="6" y2="18" />
83+
<line x1="6" y1="6" x2="18" y2="18" />
84+
</svg>
85+
</button>
86+
)}
6587
</div>
6688
<SearchUsers searchQuery={searchQuery} />
6789
</TabsContent>

components/connections/FollowersList.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,23 @@ export function FollowersList() {
8787

8888
if (followers.length === 0) {
8989
return (
90-
<div className="flex flex-col items-center justify-center p-12 text-center">
91-
<Users className="h-12 w-12 text-muted-foreground mb-4" />
92-
<h3 className="text-lg font-semibold mb-2">No followers yet</h3>
93-
<p className="text-muted-foreground">
94-
When people follow you, they&apos;ll appear here
95-
</p>
90+
<div className="flex flex-col items-center justify-center p-16 text-center space-y-6">
91+
<div className="relative">
92+
<div className="absolute inset-0 bg-purple-500/20 blur-3xl rounded-full" />
93+
<div className="relative bg-purple-500/10 p-6 rounded-full border border-purple-500/20">
94+
<Users className="h-16 w-16 text-purple-400" />
95+
</div>
96+
</div>
97+
<div className="space-y-2">
98+
<h3 className="text-xl font-bold">No followers yet</h3>
99+
<p className="text-muted-foreground max-w-md">
100+
When people follow you, they&apos;ll appear here. Keep engaging with the community!
101+
</p>
102+
</div>
103+
<div className="flex items-center gap-2 text-sm text-muted-foreground">
104+
<div className="w-2 h-2 rounded-full bg-purple-500 animate-pulse" />
105+
<span>Share your profile to gain followers</span>
106+
</div>
96107
</div>
97108
)
98109
}

components/connections/FollowingList.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,23 @@ export function FollowingList() {
7575

7676
if (following.length === 0) {
7777
return (
78-
<div className="flex flex-col items-center justify-center p-12 text-center">
79-
<Users className="h-12 w-12 text-muted-foreground mb-4" />
80-
<h3 className="text-lg font-semibold mb-2">No connections yet</h3>
81-
<p className="text-muted-foreground">
82-
Start following users to build your network
83-
</p>
78+
<div className="flex flex-col items-center justify-center p-16 text-center space-y-6">
79+
<div className="relative">
80+
<div className="absolute inset-0 bg-blue-500/20 blur-3xl rounded-full" />
81+
<div className="relative bg-blue-500/10 p-6 rounded-full border border-blue-500/20">
82+
<Users className="h-16 w-16 text-blue-400" />
83+
</div>
84+
</div>
85+
<div className="space-y-2">
86+
<h3 className="text-xl font-bold">No connections yet</h3>
87+
<p className="text-muted-foreground max-w-md">
88+
Start following users to build your professional network and stay connected
89+
</p>
90+
</div>
91+
<div className="flex items-center gap-2 text-sm text-muted-foreground">
92+
<div className="w-2 h-2 rounded-full bg-blue-500 animate-pulse" />
93+
<span>Try the Search tab to find people</span>
94+
</div>
8495
</div>
8596
)
8697
}

components/connections/SearchUsers.tsx

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,38 +78,68 @@ export function SearchUsers({ searchQuery }: SearchUsersProps) {
7878

7979
if (searchQuery.trim().length < 2) {
8080
return (
81-
<div className="flex flex-col items-center justify-center p-12 text-center">
82-
<Search className="h-12 w-12 text-muted-foreground mb-4" />
83-
<h3 className="text-lg font-semibold mb-2">Search for users</h3>
84-
<p className="text-muted-foreground">
85-
Type at least 2 characters to search
86-
</p>
81+
<div className="flex flex-col items-center justify-center p-16 text-center space-y-6">
82+
<div className="relative">
83+
<div className="absolute inset-0 bg-primary/20 blur-3xl rounded-full" />
84+
<div className="relative bg-primary/10 p-6 rounded-full border border-primary/20">
85+
<Search className="h-16 w-16 text-primary" />
86+
</div>
87+
</div>
88+
<div className="space-y-2">
89+
<h3 className="text-xl font-bold">Discover New Connections</h3>
90+
<p className="text-muted-foreground max-w-md">
91+
Search for users by name or username to expand your network
92+
</p>
93+
</div>
94+
<div className="flex items-center gap-2 text-sm text-muted-foreground">
95+
<div className="w-2 h-2 rounded-full bg-primary animate-pulse" />
96+
<span>Type at least 2 characters to start searching</span>
97+
</div>
8798
</div>
8899
)
89100
}
90101

91102
if (users.length === 0) {
92103
return (
93-
<div className="flex flex-col items-center justify-center p-12 text-center">
94-
<Search className="h-12 w-12 text-muted-foreground mb-4" />
95-
<h3 className="text-lg font-semibold mb-2">No users found</h3>
96-
<p className="text-muted-foreground">
97-
Try a different search term
104+
<div className="flex flex-col items-center justify-center p-16 text-center space-y-6">
105+
<div className="relative">
106+
<div className="bg-muted/50 p-6 rounded-full border border-border">
107+
<Search className="h-16 w-16 text-muted-foreground" />
108+
</div>
109+
</div>
110+
<div className="space-y-2">
111+
<h3 className="text-xl font-bold">No users found</h3>
112+
<p className="text-muted-foreground max-w-md">
113+
We couldn&apos;t find anyone matching &quot;{searchQuery}&quot;
114+
</p>
115+
</div>
116+
<p className="text-sm text-muted-foreground">
117+
Try searching with a different name or username
98118
</p>
99119
</div>
100120
)
101121
}
102122

103123
return (
104-
<div className="space-y-3">
105-
{users.map((user) => (
106-
<UserCard
107-
key={user.id}
108-
user={user}
109-
connectionStatus={connectionStatuses[user.id]}
110-
onConnectionChange={handleConnectionChange}
111-
/>
112-
))}
124+
<div className="space-y-4">
125+
{/* Result count header */}
126+
<div className="flex items-center justify-between px-1">
127+
<p className="text-sm text-muted-foreground">
128+
Found <span className="font-semibold text-foreground">{users.length}</span> {users.length === 1 ? 'user' : 'users'}
129+
</p>
130+
</div>
131+
132+
{/* User list */}
133+
<div className="space-y-3">
134+
{users.map((user) => (
135+
<UserCard
136+
key={user.id}
137+
user={user}
138+
connectionStatus={connectionStatuses[user.id]}
139+
onConnectionChange={handleConnectionChange}
140+
/>
141+
))}
142+
</div>
113143
</div>
114144
)
115145
}

components/connections/UserProfileModal.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,20 @@ export function UserProfileModal({
105105
}
106106
}, [open, userId, loadProfile, loadConnectionStatus])
107107

108+
// Keyboard navigation
109+
useEffect(() => {
110+
const handleKeyDown = (e: KeyboardEvent) => {
111+
if (e.key === 'Escape' && open) {
112+
onOpenChange(false)
113+
}
114+
}
115+
116+
if (open) {
117+
document.addEventListener('keydown', handleKeyDown)
118+
return () => document.removeEventListener('keydown', handleKeyDown)
119+
}
120+
}, [open, onOpenChange])
121+
108122
const handleFollow = async () => {
109123
try {
110124
setActionLoading(true)
@@ -171,7 +185,7 @@ export function UserProfileModal({
171185

172186
return (
173187
<Dialog open={open} onOpenChange={onOpenChange}>
174-
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
188+
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto backdrop-blur-md">
175189
<DialogHeader>
176190
<DialogTitle className="sr-only">User Profile</DialogTitle>
177191
</DialogHeader>

0 commit comments

Comments
 (0)