import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet, SafeAreaView, ScrollView, TouchableOpacity, RefreshControl, Alert, TextInput, } from 'react-native'; import { KurdistanColors } from '../../theme/colors'; import { usePezkuwi } from '../../contexts/PezkuwiContext'; interface Category { id: string; name: string; icon: string; color: string; } interface Discussion { id: string; categoryId: string; title: string; content: string; authorName: string; authorAddress: string; isPinned: boolean; isLocked: boolean; viewsCount: number; repliesCount: number; upvotes: number; tags: string[]; createdAt: string; lastActivityAt: string; } // Forum data stored in Supabase - categories and discussions fetched from database const ForumScreen: React.FC = () => { const { selectedAccount } = usePezkuwi(); const [categories, setCategories] = useState([]); const [discussions, setDiscussions] = useState([]); const [loading, setLoading] = useState(false); const [refreshing, setRefreshing] = useState(false); const [selectedCategory, setSelectedCategory] = useState(null); const [searchQuery, setSearchQuery] = useState(''); const [sortBy, setSortBy] = useState<'recent' | 'popular' | 'replies'>('recent'); // Stats calculated from real data const stats = { totalDiscussions: discussions.length, totalReplies: discussions.reduce((sum, d) => sum + d.repliesCount, 0), totalMembers: 0, // Will be fetched from Supabase onlineNow: 0, // Will be calculated from active sessions }; const fetchForumData = async () => { try { setLoading(true); // Note: Forum uses Supabase database, not blockchain // This is a web2 component for community discussions // TODO: Implement Supabase client and fetch real data // const { data: categoriesData } = await supabase.from('forum_categories').select('*'); // const { data: discussionsData } = await supabase.from('forum_discussions').select('*'); // For now, set empty arrays - will be populated when Supabase is configured setCategories([]); setDiscussions([]); } catch (error) { console.error('Failed to load forum data:', error); Alert.alert('Error', 'Failed to load forum data from database'); } finally { setLoading(false); setRefreshing(false); } }; useEffect(() => { fetchForumData(); }, []); const handleRefresh = () => { setRefreshing(true); fetchForumData(); }; const handleCreateTopic = () => { if (!selectedAccount) { Alert.alert('Login Required', 'You need to connect your wallet to create topics'); return; } Alert.alert('Create Topic', 'Create topic modal would open here'); // TODO: Navigate to CreateTopicScreen }; const handleDiscussionPress = (discussion: Discussion) => { Alert.alert( discussion.title, `${discussion.content.substring(0, 200)}...\n\nAuthor: ${discussion.authorName}\nReplies: ${discussion.repliesCount} | Views: ${discussion.viewsCount} | Upvotes: ${discussion.upvotes}`, [ { text: 'Cancel', style: 'cancel' }, { text: 'View Thread', onPress: () => Alert.alert('Thread View', 'Thread details screen would open here') }, ] ); }; const getCategoryById = (categoryId: string): Category | undefined => { return categories.find((c: Category) => c.id === categoryId); }; const getTimeAgo = (dateString: string): string => { const date = new Date(dateString); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMins / 60); const diffDays = Math.floor(diffHours / 24); if (diffMins < 60) return `${diffMins}m ago`; if (diffHours < 24) return `${diffHours}h ago`; return `${diffDays}d ago`; }; const filteredDiscussions = discussions .filter(d => !selectedCategory || d.categoryId === selectedCategory) .filter(d => !searchQuery || d.title.toLowerCase().includes(searchQuery.toLowerCase()) || d.content.toLowerCase().includes(searchQuery.toLowerCase())) .sort((a, b) => { if (a.isPinned && !b.isPinned) return -1; if (!a.isPinned && b.isPinned) return 1; switch (sortBy) { case 'popular': return b.viewsCount - a.viewsCount; case 'replies': return b.repliesCount - a.repliesCount; default: return new Date(b.lastActivityAt).getTime() - new Date(a.lastActivityAt).getTime(); } }); return ( } > {/* Header */} Community Forum Discuss, share ideas, and connect {/* Stats Grid */} 📋 {stats.totalDiscussions} Topics đŸ’Ŧ {stats.totalReplies} Replies đŸ‘Ĩ {stats.totalMembers} Members {stats.onlineNow} Online {/* Create Topic Button */} ➕ Create New Topic {/* Search Bar */} 🔍 {/* Categories Filter */} Categories setSelectedCategory(null)} > 📋 All Topics {categories.map((category) => ( setSelectedCategory(category.id)} > {category.icon} {category.name} ))} {/* Sort Tabs */} setSortBy('recent')} > ⏰ Recent setSortBy('popular')} > đŸ‘ī¸ Popular setSortBy('replies')} > đŸ’Ŧ Replies {/* Discussions List */} {filteredDiscussions.length === 0 ? ( đŸ’Ŧ {searchQuery ? 'No discussions found matching your search' : 'No discussions yet'} {!searchQuery && ( Create First Topic )} ) : ( filteredDiscussions.map((discussion) => { const category = getCategoryById(discussion.categoryId); return ( handleDiscussionPress(discussion)} > {/* Discussion Header */} {discussion.authorName.charAt(0).toUpperCase()} {discussion.authorName} {getTimeAgo(discussion.lastActivityAt)} {/* Badges */} {discussion.isPinned && ( 📌 PINNED )} {discussion.isLocked && ( 🔒 LOCKED )} {category && ( {category.icon} {category.name} )} {/* Title */} {discussion.title} {/* Content Preview */} {discussion.content} {/* Tags */} {discussion.tags.length > 0 && ( {discussion.tags.slice(0, 3).map((tag, idx) => ( #{tag} ))} {discussion.tags.length > 3 && ( +{discussion.tags.length - 3} more )} )} {/* Stats */} đŸ’Ŧ {discussion.repliesCount} đŸ‘ī¸ {discussion.viewsCount} 👍 {discussion.upvotes} ); }) )} {/* Info Note */} â„šī¸ Connect your wallet to create topics, reply to discussions, and upvote helpful content. ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#F8F9FA', }, scrollContent: { flex: 1, }, header: { padding: 20, paddingBottom: 16, }, headerTitle: { fontSize: 28, fontWeight: 'bold', color: '#333', marginBottom: 4, }, headerSubtitle: { fontSize: 14, color: '#666', }, statsGrid: { flexDirection: 'row', paddingHorizontal: 16, gap: 12, marginBottom: 20, }, statCard: { flex: 1, backgroundColor: '#FFFFFF', borderRadius: 12, padding: 12, alignItems: 'center', boxShadow: '0px 1px 4px rgba(0, 0, 0, 0.05)', elevation: 2, }, statIcon: { fontSize: 20, marginBottom: 4, }, statValue: { fontSize: 16, fontWeight: 'bold', color: '#333', marginBottom: 2, }, statLabel: { fontSize: 10, color: '#999', }, onlineIndicator: { width: 8, height: 8, borderRadius: 4, backgroundColor: KurdistanColors.kesk, marginBottom: 4, }, createButton: { backgroundColor: KurdistanColors.kesk, marginHorizontal: 16, marginBottom: 20, paddingVertical: 14, borderRadius: 12, alignItems: 'center', }, createButtonText: { fontSize: 16, fontWeight: '600', color: '#FFFFFF', }, searchContainer: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#FFFFFF', marginHorizontal: 16, marginBottom: 20, paddingHorizontal: 16, paddingVertical: 12, borderRadius: 12, boxShadow: '0px 1px 4px rgba(0, 0, 0, 0.05)', elevation: 2, }, searchIcon: { fontSize: 18, marginRight: 8, }, searchInput: { flex: 1, fontSize: 16, color: '#333', }, categoriesSection: { marginBottom: 20, }, sectionTitle: { fontSize: 16, fontWeight: 'bold', color: '#333', paddingHorizontal: 16, marginBottom: 12, }, categoriesScroll: { paddingHorizontal: 16, }, categoryChip: { paddingHorizontal: 16, paddingVertical: 8, borderRadius: 20, backgroundColor: '#E5E5E5', marginRight: 8, }, categoryChipActive: { backgroundColor: KurdistanColors.kesk, }, categoryChipText: { fontSize: 13, fontWeight: '600', color: '#666', }, categoryChipTextActive: { color: '#FFFFFF', }, sortTabs: { flexDirection: 'row', marginHorizontal: 16, marginBottom: 20, gap: 8, }, sortTab: { flex: 1, paddingVertical: 8, borderRadius: 12, backgroundColor: '#E5E5E5', alignItems: 'center', }, sortTabActive: { backgroundColor: KurdistanColors.kesk, }, sortTabText: { fontSize: 13, fontWeight: '600', color: '#666', }, sortTabTextActive: { color: '#FFFFFF', }, discussionsList: { paddingHorizontal: 16, gap: 12, }, emptyContainer: { padding: 40, alignItems: 'center', }, emptyIcon: { fontSize: 64, marginBottom: 16, }, emptyText: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 16, }, emptyButton: { backgroundColor: KurdistanColors.kesk, paddingHorizontal: 24, paddingVertical: 12, borderRadius: 12, }, emptyButtonText: { fontSize: 14, fontWeight: '600', color: '#FFFFFF', }, discussionCard: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 16, marginBottom: 12, boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.05)', elevation: 2, }, discussionCardPinned: { borderWidth: 1, borderColor: '#F59E0B', }, discussionHeader: { flexDirection: 'row', alignItems: 'center', marginBottom: 12, }, discussionAvatar: { width: 40, height: 40, borderRadius: 20, backgroundColor: KurdistanColors.kesk, justifyContent: 'center', alignItems: 'center', marginRight: 12, }, discussionAvatarText: { fontSize: 16, fontWeight: 'bold', color: '#FFFFFF', }, discussionHeaderInfo: { flex: 1, }, discussionAuthor: { fontSize: 14, fontWeight: '600', color: '#333', }, discussionTime: { fontSize: 12, color: '#999', }, badgesRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 6, marginBottom: 8, }, pinnedBadge: { backgroundColor: 'rgba(245, 158, 11, 0.1)', paddingHorizontal: 8, paddingVertical: 2, borderRadius: 8, }, pinnedBadgeText: { fontSize: 10, fontWeight: '700', color: '#F59E0B', }, lockedBadge: { backgroundColor: 'rgba(102, 102, 102, 0.1)', paddingHorizontal: 8, paddingVertical: 2, borderRadius: 8, }, lockedBadgeText: { fontSize: 10, fontWeight: '700', color: '#666', }, categoryBadge: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 8, }, categoryBadgeText: { fontSize: 10, fontWeight: '600', }, discussionTitle: { fontSize: 16, fontWeight: 'bold', color: '#333', marginBottom: 8, lineHeight: 22, }, discussionContent: { fontSize: 14, color: '#666', lineHeight: 20, marginBottom: 12, }, tagsRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 6, marginBottom: 12, }, tag: { backgroundColor: '#F0F0F0', paddingHorizontal: 8, paddingVertical: 3, borderRadius: 12, }, tagText: { fontSize: 11, color: '#666', }, tagsMore: { fontSize: 11, color: '#999', alignSelf: 'center', }, discussionStats: { flexDirection: 'row', gap: 16, paddingTop: 12, borderTopWidth: 1, borderTopColor: '#F0F0F0', }, discussionStat: { flexDirection: 'row', alignItems: 'center', gap: 4, }, discussionStatIcon: { fontSize: 14, }, discussionStatText: { fontSize: 13, color: '#666', fontWeight: '500', }, discussionStatUpvotes: { color: KurdistanColors.kesk, }, infoNote: { flexDirection: 'row', backgroundColor: '#E0F2FE', marginHorizontal: 16, marginTop: 16, marginBottom: 24, padding: 16, borderRadius: 12, gap: 12, }, infoNoteIcon: { fontSize: 20, }, infoNoteText: { flex: 1, fontSize: 12, color: '#0C4A6E', lineHeight: 18, }, }); export default ForumScreen;