'use client';
import { useState, useEffect } from 'react';
import { Sparkles, MessageSquare, ArrowUp } from 'lucide-react';
import { getRecommendedPosts } from '@/actions/recommendations';
import type { ForumPost } from '@/types/forum';
import Link from 'next/link';
import { useAuth } from '@/contexts/AuthContext';
interface RecommendedWidgetProps {
limit?: number;
showViewAll?: boolean;
}
/**
* RecommendedWidget - Displays personalized post recommendations
*
* Uses recommendation algorithm to suggest posts based on:
* - User's category preferences
* - Bookmarked bills
* - Voting patterns
* - Recent activity
*
* Falls back to trending posts for unauthenticated users
*/
export function RecommendedWidget({ limit = 5, showViewAll = false }: RecommendedWidgetProps) {
const { user } = useAuth();
const [posts, setPosts] = useState<ForumPost[]>([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const loadRecommendations = async () => {
setIsLoading(true);
const result = await getRecommendedPosts(limit);
if (result.success && result.data) {
setPosts(result.data);
}
setIsLoading(false);
};
loadRecommendations();
}, [limit, user?.id]); // Reload when user changes
if (isLoading) {
return (
<div className="bg-background-secondary border-2 border-border-primary rounded-lg p-6">
<div className="animate-pulse space-y-4">
<div className="h-6 bg-background-primary rounded w-2/3" />
<div className="space-y-3">
{[...Array(3)].map((_, i) => (
<div key={i} className="h-4 bg-background-primary rounded" />
))}
</div>
</div>
</div>
);
}
if (posts.length === 0) {
return null;
}
return (
<div className="bg-background-secondary border-2 border-border-primary rounded-lg p-6 mb-6">
{/* Header */}
<div className="flex items-center justify-between mb-4">
<h3 className="text-xl font-bold text-text-primary flex items-center gap-2">
<Sparkles className="text-accent-red" size={24} />
{user ? 'Recommended for You' : 'Trending Discussions'}
</h3>
{showViewAll && (
<Link
href="/forum/discussions?sort=trending"
className="text-sm text-accent-red hover:underline"
>
View all
</Link>
)}
</div>
{/* Subtitle for personalized recommendations */}
{user && (
<p className="text-xs text-text-tertiary mb-4">
Based on your interests and activity
</p>
)}
{/* Recommended posts */}
<div className="space-y-3">
{posts.map((post, index) => (
<Link
key={post.id}
href={
post.post_type === 'bill_comment'
? `/bills/${post.bill_session}/${post.bill_number}#post-${post.id}`
: `/forum/posts/${post.id}`
}
className="
block p-3 rounded-lg bg-background-primary
hover:bg-background-secondary border-2 border-transparent
hover:border-accent-red transition-all group
"
>
<div className="flex items-start gap-3">
{/* Rank indicator */}
<div className="flex-shrink-0 w-6 h-6 rounded-full bg-gradient-to-br from-accent-red to-red-700 text-white text-xs font-bold flex items-center justify-center">
{index + 1}
</div>
{/* Content */}
<div className="flex-1 min-w-0">
<h4 className="font-medium text-text-primary group-hover:text-accent-red transition-colors line-clamp-2 mb-1">
{post.title || post.content.substring(0, 100)}
</h4>
<div className="flex items-center gap-3 text-xs text-text-tertiary">
<span className="flex items-center gap-1">
<ArrowUp size={12} />
{post.upvotes_count}
</span>
<span className="flex items-center gap-1">
<MessageSquare size={12} />
{post.reply_count}
</span>
{post.post_type === 'bill_comment' && post.bill_number && (
<span className="font-mono bg-background-secondary px-1.5 py-0.5 rounded">
{post.bill_number}
</span>
)}
{post.category && post.category.color && (
<span
className="px-1.5 py-0.5 rounded text-xs font-medium"
style={{
backgroundColor: post.category.color + '20',
color: post.category.color,
}}
>
{post.category.name}
</span>
)}
</div>
{/* New replies badge if present */}
{post.new_reply_count && post.new_reply_count > 0 && (
<div className="mt-1">
<span className="inline-flex items-center px-2 py-0.5 text-xs font-bold text-white bg-accent-red rounded-full">
{post.new_reply_count} new{' '}
{post.new_reply_count === 1 ? 'reply' : 'replies'}
</span>
</div>
)}
</div>
</div>
</Link>
))}
</div>
{/* Footer note for authenticated users */}
{user && (
<div className="mt-4 pt-4 border-t-2 border-border-primary">
<p className="text-xs text-text-tertiary">
💡 Recommendations update based on your votes and activity
</p>
</div>
)}
</div>
);
}