Improve empty feed state with icon and discover CTA
Redesign FeedEmptyState with a centered icon, cleaner layout, and two actionable buttons for the follows tab: 'Discover people to follow' linking to /packs, and 'Browse the Global feed' to switch tabs. Other call sites are unaffected (new props are optional).
This commit is contained in:
@@ -327,10 +327,11 @@ export function Feed({ kinds, tagFilters, header, hideCompose, emptyMessage, fee
|
||||
message={
|
||||
emptyMessage ?? (
|
||||
activeTab === 'follows'
|
||||
? 'No posts yet. Follow some people to see their content here.'
|
||||
? 'Your feed is empty. Follow some people to see their posts here.'
|
||||
: 'No posts found. Check your relay connections or come back soon.'
|
||||
)
|
||||
}
|
||||
showDiscover={!emptyMessage && activeTab === 'follows'}
|
||||
onSwitchToGlobal={
|
||||
activeTab === 'follows' && showGlobalFeed
|
||||
? () => handleSetActiveTab('global')
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Users } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface FeedEmptyStateProps {
|
||||
@@ -5,31 +8,45 @@ interface FeedEmptyStateProps {
|
||||
message: string;
|
||||
/** Called when the user clicks "Switch to Global". Omit to hide the button. */
|
||||
onSwitchToGlobal?: () => void;
|
||||
/** Show a "Discover people" link to /packs. */
|
||||
showDiscover?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consistent empty state for Follows/Global feed tabs across all feed pages.
|
||||
*
|
||||
* - Follows tab: pass `onSwitchToGlobal` to render a "Switch to Global" CTA.
|
||||
* - Global tab: omit `onSwitchToGlobal`; the message should guide the user
|
||||
* - Follows tab: pass `onSwitchToGlobal` and `showDiscover` to render CTAs.
|
||||
* - Global tab: omit both; the message should guide the user
|
||||
* to check their relay connections.
|
||||
*/
|
||||
export function FeedEmptyState({
|
||||
message,
|
||||
onSwitchToGlobal,
|
||||
showDiscover,
|
||||
className,
|
||||
}: FeedEmptyStateProps) {
|
||||
return (
|
||||
<div className={cn('py-16 px-8 text-center space-y-3', className)}>
|
||||
<p className="text-muted-foreground break-all">{message}</p>
|
||||
{onSwitchToGlobal && (
|
||||
<button
|
||||
className="text-sm text-primary hover:underline"
|
||||
onClick={onSwitchToGlobal}
|
||||
>
|
||||
Switch to Global
|
||||
</button>
|
||||
<div className={cn('py-20 px-8 flex flex-col items-center text-center', className)}>
|
||||
<div className="size-12 rounded-full bg-muted flex items-center justify-center mb-4">
|
||||
<Users className="size-6 text-muted-foreground" />
|
||||
</div>
|
||||
|
||||
<p className="text-muted-foreground max-w-xs">{message}</p>
|
||||
|
||||
{(showDiscover || onSwitchToGlobal) && (
|
||||
<div className="flex flex-col gap-2 mt-5 w-full max-w-xs">
|
||||
{showDiscover && (
|
||||
<Button asChild className="rounded-full">
|
||||
<Link to="/packs">Discover people to follow</Link>
|
||||
</Button>
|
||||
)}
|
||||
{onSwitchToGlobal && (
|
||||
<Button variant="ghost" className="rounded-full" onClick={onSwitchToGlobal}>
|
||||
Browse the Global feed
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user