import React, { useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { MessageSquare, Leaf, Megaphone, PencilLine, ThumbsUp, Users, Calendar, Search } from "lucide-react"; // --- Mock Data Types const seededArticles = [ { id: 1, title: "Cities that banned single-use plastics in 2025", author: "M. Popescu", excerpt: "Policy shifts from Cluj to Porto are reshaping urban waste.", tags: ["policy", "waste"], date: "2025-07-10" }, { id: 2, title: "Community solar: how co-ops cut bills by 30%", author: "A. Ruiz", excerpt: "A practical blueprint for neighborhood arrays.", tags: ["energy", "community"], date: "2025-06-28" }, { id: 3, title: "River guardians: citizen science that works", author: "K. Ionescu", excerpt: "From nitrate testing to legal wins.", tags: ["water", "science"], date: "2025-05-14" }, ]; const seededPetitions = [ { id: 1, title: "Protect the Valea Morilor wetlands", goal: 5000, signed: 1380, owner: "GreenAction Chisinau", summary: "Stop the infill plan and designate the wetlands as a protected urban reserve.", tags: ["biodiversity", "urban"], created: "2025-07-02" }, { id: 2, title: "Make Bucharest a 30 km/h city", goal: 20000, signed: 11940, owner: "Streets for People", summary: "Save lives, cut noise, and slash emissions with a citywide speed limit.", tags: ["transport", "health"], created: "2025-06-21" }, { id: 3, title: "No LNG terminal at Constanța", goal: 10000, signed: 8450, owner: "Black Sea Watch", summary: "Invest in offshore wind and grid upgrades instead of fossil lock-in.", tags: ["energy", "climate"], created: "2025-05-30" }, ]; const seededThreads = [ { id: 1, title: "Anyone mapping heat islands in Sector 6?", author: "daria", upvotes: 23, replies: 12, tags: ["mapping", "heat"], last: "2h" }, { id: 2, title: "How to start a repair café?", author: "andrei", upvotes: 41, replies: 33, tags: ["repair", "community"], last: "5h" }, { id: 3, title: "Grant tips for citizen science kits", author: "sara", upvotes: 9, replies: 4, tags: ["funding", "science"], last: "1d" }, ]; function Stat({ icon: Icon, label, value }: { icon: any; label: string; value: string | number }) { return (
{value}
{label}
); } function ProgressBar({ current, goal }: { current: number; goal: number }) { const pct = Math.max(0, Math.min(100, Math.round((current / goal) * 100))); return (
{pct}% to goal
); } export default function EcoCommunitySite() { const [articles, setArticles] = useState(seededArticles); const [petitions, setPetitions] = useState(seededPetitions); const [threads, setThreads] = useState(seededThreads); const [query, setQuery] = useState(""); const filteredArticles = useMemo(() => articles.filter(a => a.title.toLowerCase().includes(query.toLowerCase())), [articles, query]); const filteredPetitions = useMemo(() => petitions.filter(p => p.title.toLowerCase().includes(query.toLowerCase())), [petitions, query]); const filteredThreads = useMemo(() => threads.filter(t => t.title.toLowerCase().includes(query.toLowerCase())), [threads, query]); // New Petition state const [openNewPetition, setOpenNewPetition] = useState(false); const [petitionDraft, setPetitionDraft] = useState({ title: "", goal: 1000, summary: "", owner: "" }); // New Thread state const [openNewThread, setOpenNewThread] = useState(false); const [threadDraft, setThreadDraft] = useState({ title: "", tags: "" }); // Auth mock const [user, setUser] = useState<{ name: string } | null>({ name: "Guest" }); function signPetition(id: number) { setPetitions(prev => prev.map(p => (p.id === id ? { ...p, signed: Math.min(p.goal, p.signed + 1) } : p))); } function createPetition() { if (!petitionDraft.title.trim() || !petitionDraft.owner.trim()) return; const newP = { id: petitions.length + 1, title: petitionDraft.title, goal: Math.max(100, petitionDraft.goal || 1000), signed: 0, owner: petitionDraft.owner, summary: petitionDraft.summary || "", tags: ["community"], created: new Date().toISOString().slice(0, 10), }; setPetitions([newP, ...petitions]); setOpenNewPetition(false); setPetitionDraft({ title: "", goal: 1000, summary: "", owner: "" }); } function createThread() { if (!threadDraft.title.trim()) return; const newT = { id: threads.length + 1, title: threadDraft.title, author: user?.name || "guest", upvotes: 0, replies: 0, tags: threadDraft.tags ? threadDraft.tags.split(",").map(t => t.trim()).filter(Boolean) : ["discussion"], last: "just now", } as any; setThreads([newT, ...threads]); setOpenNewThread(false); setThreadDraft({ title: "", tags: "" }); } return (
{/* Header */}
GreenAction
setQuery(e.target.value)} placeholder="Search..." className="pl-9 w-48" />
Start a Petition
setPetitionDraft({ ...petitionDraft, title: e.target.value })} />
setPetitionDraft({ ...petitionDraft, owner: e.target.value })} />
setPetitionDraft({ ...petitionDraft, goal: Number(e.target.value) })} />