Zum Inhalt

Charity Voting

Seite: app/charity/page.tsx (540 Zeilen) APIs: app/api/charity/rounds/, app/api/charity/projects/ Pfad: /charity Datenbank: chainbets_charity (separate Datenbank)

Übersicht

Das Charity-Voting-System ermöglicht die Verwaltung von Spendenabstimmungen. Spieler können über die App für Charity-Projekte abstimmen.

┌──────────────────────────────────────────────┐
│ + Neue Runde erstellen                        │
│ [Titel] [Beschreibung] [Start] [Ende]        │
│                              [Erstellen]      │
├──────────────────────────────────────────────┤
│ Runden-Liste                                  │
│ ┌────────────────────────────────────────┐    │
│ │ Runde: "Q1 2026 Spenden"              │    │
│ │ Status: active   Projekte: 5   Votes: 234│  │
│ │ [Close]                                │    │
│ └────────────────────────────────────────┘    │
├──────────────────────────────────────────────┤
│ Runden-Detail (bei Klick)                     │
│ ┌────────────────────────────────────────┐    │
│ │ Projekte mit Abstimmungsergebnis       │    │
│ │ 🌍 Klimaschutz    ████████ 89 Votes    │    │
│ │ 🏥 Gesundheit     ██████ 67 Votes      │    │
│ │ 📚 Bildung        ████ 45 Votes        │    │
│ │                                        │    │
│ │ [+ Projekt hinzufügen]                 │    │
│ └────────────────────────────────────────┘    │
└──────────────────────────────────────────────┘

Runden-Management

Status-Lifecycle

draft → active → closed → funded
Status Bedeutung Aktionen
draft Entwurf, Projekte hinzufügen Activate, Projekte bearbeiten
active Abstimmung läuft Close, Projekte hinzufügen
closed Abstimmung beendet Mark Funded
funded Spende ausgeführt Keine

Runde erstellen (POST)

INSERT INTO voting_rounds (title, description, start_date, end_date, status)
VALUES ($1, $2, $3, $4, 'draft')
RETURNING *

Status ändern (PUT)

UPDATE voting_rounds
SET status = $1, updated_at = NOW()
WHERE id = $2

Validierung: Status-Übergänge werden geprüft (draft→active→closed→funded).

Runden-Query

SELECT vr.*,
       COUNT(DISTINCT p.id)::int AS project_count,
       COALESCE(SUM(v.vote_count), 0)::int AS total_votes
FROM voting_rounds vr
LEFT JOIN projects p ON p.voting_round_id = vr.id
LEFT JOIN votes v ON v.project_id = p.id
GROUP BY vr.id
ORDER BY vr.created_at DESC

Projekt-Management

Projekt hinzufügen (POST)

INSERT INTO projects (voting_round_id, name, emoji, description, target_amount_usdt)
VALUES ($1, $2, $3, $4, $5)
RETURNING *

Voraussetzung: Runde muss draft oder active sein.

Projekt löschen (DELETE)

DELETE FROM projects WHERE id = $1

Voraussetzung: Zugehörige Runde muss draft sein.

Projekte mit Votes

SELECT p.id, p.name, p.emoji, p.description, p.target_amount_usdt,
       COUNT(v.id)::int AS total_votes,
       COUNT(DISTINCT v.voter_wallet)::int AS unique_voters
FROM projects p
LEFT JOIN votes v ON v.project_id = p.id
WHERE p.voting_round_id = $1
GROUP BY p.id
ORDER BY total_votes DESC

Abstimmungsvisualisierung

Die Abstimmungsergebnisse werden als Fortschrittsbalken dargestellt: - Breite relativ zum Projekt mit den meisten Stimmen - Anzeige von Gesamtstimmen und einzigartigen Wählern - Optional: Ziel-Betrag in USDT

Datenbank-Schema (chainbets_charity)

voting_rounds (
  id          SERIAL PRIMARY KEY,
  title       TEXT NOT NULL,
  description TEXT,
  start_date  DATE,
  end_date    DATE,
  status      VARCHAR DEFAULT 'draft',
  created_at  TIMESTAMP DEFAULT NOW()
)

projects (
  id                  SERIAL PRIMARY KEY,
  voting_round_id     INT REFERENCES voting_rounds(id),
  name                TEXT NOT NULL,
  emoji               VARCHAR,
  description         TEXT,
  target_amount_usdt  NUMERIC,
  status              VARCHAR DEFAULT 'active',
  created_at          TIMESTAMP DEFAULT NOW()
)

votes (
  id             SERIAL PRIMARY KEY,
  project_id     INT REFERENCES projects(id),
  voter_wallet   VARCHAR NOT NULL,
  vote_count     INT DEFAULT 1,
  created_at     TIMESTAMP DEFAULT NOW()
)