OpChan/src/components/FeedSidebar.tsx
2025-09-03 15:56:00 +05:30

191 lines
6.8 KiB
TypeScript

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { Plus, TrendingUp, Users, Eye } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import {
useForumData,
useForumSelectors,
useAuth,
usePermissions,
} from '@/hooks';
import { CypherImage } from '@/components/ui/CypherImage';
import { CreateCellDialog } from '@/components/CreateCellDialog';
import { useUserDisplay } from '@/hooks';
const FeedSidebar: React.FC = () => {
// ✅ Use reactive hooks for data
const forumData = useForumData();
const selectors = useForumSelectors(forumData);
const { currentUser, verificationStatus } = useAuth();
const { canCreateCell } = usePermissions();
const [showCreateCell, setShowCreateCell] = useState(false);
// Get user display information using the hook
const { displayName, hasENS, hasOrdinal } = useUserDisplay(
currentUser?.address || ''
);
// ✅ Get pre-computed stats and trending data from selectors
const stats = selectors.selectStats();
// Use cellsWithStats from forumData to get post counts
const { cellsWithStats } = forumData;
const trendingCells = cellsWithStats
.sort((a, b) => b.recentActivity - a.recentActivity)
.slice(0, 5);
// User's verification status display
const getVerificationBadge = () => {
if (verificationStatus.level === 'verified-owner') {
return { text: 'Verified Owner', color: 'bg-green-500' };
} else if (verificationStatus.level === 'verified-basic') {
return { text: 'Verified', color: 'bg-blue-500' };
} else if (hasENS) {
return { text: 'ENS User', color: 'bg-purple-500' };
} else if (hasOrdinal) {
return { text: 'Ordinal User', color: 'bg-orange-500' };
}
return { text: 'Unverified', color: 'bg-gray-500' };
};
const verificationBadge = getVerificationBadge();
return (
<div className="w-80 bg-cyber-muted/10 border-l border-cyber-muted p-4 space-y-6 overflow-y-auto">
{/* User Status Card */}
{currentUser && (
<Card className="bg-cyber-muted/20 border-cyber-muted">
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium">Your Status</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 rounded-full bg-cyber-accent/20 flex items-center justify-center">
<Users className="w-5 h-5 text-cyber-accent" />
</div>
<div className="flex-1">
<div className="font-medium text-sm">{displayName}</div>
<Badge
variant="secondary"
className={`${verificationBadge.color} text-white text-xs`}
>
{verificationBadge.text}
</Badge>
</div>
</div>
{verificationStatus.level === 'unverified' && (
<div className="text-xs text-muted-foreground">
<Eye className="w-3 h-3 inline mr-1" />
Read-only mode. Verify wallet to participate.
</div>
)}
{verificationStatus.level === 'verified-basic' && !hasOrdinal && (
<div className="text-xs text-muted-foreground">
<Eye className="w-3 h-3 inline mr-1" />
Read-only mode. Acquire Ordinals to post.
</div>
)}
</CardContent>
</Card>
)}
{/* Forum Stats */}
<Card className="bg-cyber-muted/20 border-cyber-muted">
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium flex items-center">
<TrendingUp className="w-4 h-4 mr-2" />
Forum Stats
</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-3 gap-4 text-center">
<div>
<div className="text-lg font-bold text-cyber-accent">
{stats.totalCells}
</div>
<div className="text-xs text-muted-foreground">Cells</div>
</div>
<div>
<div className="text-lg font-bold text-cyber-accent">
{stats.totalPosts}
</div>
<div className="text-xs text-muted-foreground">Posts</div>
</div>
<div>
<div className="text-lg font-bold text-cyber-accent">
{stats.totalComments}
</div>
<div className="text-xs text-muted-foreground">Comments</div>
</div>
</div>
</CardContent>
</Card>
{/* Trending Cells */}
<Card className="bg-cyber-muted/20 border-cyber-muted">
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium">Trending Cells</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
{trendingCells.map(cell => (
<Link
key={cell.id}
to={`/cell/${cell.id}`}
className="flex items-center space-x-3 p-2 rounded-sm hover:bg-cyber-muted/30 transition-colors"
>
<CypherImage
src={cell.icon}
alt={cell.name}
className="w-8 h-8 rounded-sm"
generateUniqueFallback={true}
/>
<div className="flex-1 min-w-0">
<div className="font-medium text-sm truncate">{cell.name}</div>
<div className="text-xs text-muted-foreground">
{cell.postCount} posts {cell.activeUsers} members
</div>
</div>
</Link>
))}
{trendingCells.length === 0 && (
<div className="text-center text-xs text-muted-foreground py-4">
No active cells yet
</div>
)}
</CardContent>
</Card>
{/* Quick Actions */}
{canCreateCell && (
<Card className="bg-cyber-muted/20 border-cyber-muted">
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium">Quick Actions</CardTitle>
</CardHeader>
<CardContent>
<Button
onClick={() => setShowCreateCell(true)}
className="w-full bg-cyber-accent hover:bg-cyber-accent/80"
size="sm"
>
<Plus className="w-4 h-4 mr-2" />
Create Cell
</Button>
</CardContent>
</Card>
)}
{/* Create Cell Dialog */}
<CreateCellDialog
open={showCreateCell}
onOpenChange={setShowCreateCell}
/>
</div>
);
};
export default FeedSidebar;