NOTEDASHBOARD
Panchobeltran702

obsidianvault.ai-dashboard

obsidianvault.ai-dashboard

import { useEffect, useState } from "react"; import { motion } from "framer-motion"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from "recharts"; import { Globe, Users, Lock, Coins } from "lucide-react";

export default function Dashboard() { const [stats, setStats] = useState(null); const [supporters, setSupporters] = useState([]); const [withdrawals, setWithdrawals] = useState([]);

useEffect(() => { const fetchData = async () => { const [s, sup, wd] = await Promise.all([ fetch("/api/stats").then(r => r.json()), fetch("/api/supporters").then(r => r.json()), fetch("/api/withdrawals").then(r => r.json()) ]); setStats(s); setSupporters(sup); setWithdrawals(wd); }; fetchData();

// realtime websocket updates
const ws = new WebSocket(`${window.location.origin.replace(/^http/, "ws")}/api/realtime`);
ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (msg.type === "stats") setStats(msg.data);
  if (msg.type === "supporters") setSupporters(msg.data);
  if (msg.type === "withdrawals") setWithdrawals(msg.data);
};
return () => ws.close();

}, []);

if (!stats) { return

Loading live stats...
; }

return (

<motion.h1 className="text-3xl font-bold text-center text-gray-900" initial={{ opacity: 0, y: -20 }} animate={{ opacity: 1, y: 0 }} > Obsidian Vault Live Dashboard </motion.h1>

  {/* Stat cards */}
  <div className="grid md:grid-cols-4 gap-6">
    <Card>
      <CardContent className="p-4 flex flex-col items-center">
        <Coins className="w-8 h-8 text-indigo-600" />
        <p className="mt-2 text-lg font-semibold">${stats.totalFunds.toLocaleString()}</p>
        <p className="text-sm text-gray-500">Total Funds Raised</p>
      </CardContent>
    </Card>
    <Card>
      <CardContent className="p-4 flex flex-col items-center">
        <Users className="w-8 h-8 text-indigo-600" />
        <p className="mt-2 text-lg font-semibold">{stats.totalSupporters}</p>
        <p className="text-sm text-gray-500">Supporters</p>
      </CardContent>
    </Card>
    <Card>
      <CardContent className="p-4 flex flex-col items-center">
        <Globe className="w-8 h-8 text-indigo-600" />
        <p className="mt-2 text-lg font-semibold">{supporters.length}</p>
        <p className="text-sm text-gray-500">Countries Reached</p>
      </CardContent>
    </Card>
    <Card>
      <CardContent className="p-4 flex flex-col items-center">
        <Lock className="w-8 h-8 text-indigo-600" />
        <p className="mt-2 text-lg font-semibold">{withdrawals.length}</p>
        <p className="text-sm text-gray-500">Pending Withdrawals</p>
      </CardContent>
    </Card>
  </div>

  {/* Chart */}
  <Card>
    <CardContent className="p-4">
      <h2 className="text-lg font-semibold mb-4">Funding Growth</h2>
      <ResponsiveContainer width="100%" height={300}>
        <LineChart data={stats.history}>
          <XAxis dataKey="time" />
          <YAxis />
          <Tooltip />
          <Line type="monotone" dataKey="funds" stroke="#4f46e5" strokeWidth={2} />
        </LineChart>
      </ResponsiveContainer>
    </CardContent>
  </Card>

  {/* Withdrawals table */}
  <Card>
    <CardContent className="p-4">
      <h2 className="text-lg font-semibold mb-4">Withdrawal Queue</h2>
      <table className="w-full text-left">
        <thead>
          <tr className="border-b">
            <th className="py-2">Wallet</th>
            <th className="py-2">Amount</th>
            <th className="py-2">Unlocks In</th>
          </tr>
        </thead>
        <tbody>
          {withdrawals.map((w, i) => (
            <tr key={i} className="border-b">
              <td className="py-2">{w.wallet}</td>
              <td className="py-2">${w.amount.toLocaleString()}</td>
              <td className="py-2">{w.unlocksIn} days</td>
            </tr>
          ))}
        </tbody>
      </table>
    </CardContent>
  </Card>

  {/* CTA */}
  <div className="text-center">
    <Button size="lg" className="bg-indigo-600 hover:bg-indigo-700 text-white">
      Become a Supporter
    </Button>
  </div>
</div>

); }

Related

How to Install

  1. Download the dashboard markdown file from GitHub
  2. Drop it into your vault (anywhere)
  3. Install the Homepage plugin and point it at the file
  4. Enable any listed CSS snippets for the intended look

Stats

Stars

0

Forks

0

Last updated 11mo ago

Categories