├── .gitignore
├── .env.example
├── src
├── data
│ └── votes.json
├── app.ts
├── config
│ └── fluvio.ts
└── routes
│ └── vote.ts
├── tsconfig.json
├── package.json
├── LICENSE
├── README.md
└── public
├── vote.html
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | \node_modules
2 | .env
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | PORT=8000
2 | FLUVIO_TOPIC=vote-topic
--------------------------------------------------------------------------------
/src/data/votes.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | "Anand",
4 | "Anan",
5 | "Kom1"
6 | ],
7 | "B": [
8 | "Anon"
9 | ],
10 | "C": [
11 | "Kom"
12 | ],
13 | "D": [],
14 | "E": []
15 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "module": "CommonJS",
5 | "strict": true,
6 | "esModuleInterop": true,
7 | "outDir": "./dist",
8 | "rootDir": "./src",
9 | "resolveJsonModule": true,
10 | "skipLibCheck": true
11 | },
12 | "include": ["src/**/*"],
13 | "exclude": ["node_modules"]
14 | }
15 |
--------------------------------------------------------------------------------
/src/app.ts:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import cors from "cors";
3 | import dotenv from "dotenv";
4 | import path from "path";
5 | import voteRoutes from "./routes/vote";
6 | import { getVotes, initializeFluvio } from "./config/fluvio";
7 |
8 | dotenv.config();
9 | const port = process.env.PORT || 8000;
10 |
11 | const app = express();
12 | app.use(express.json());
13 | app.use(cors());
14 | app.use(express.static(path.join(__dirname, "../public")));
15 |
16 | app.use("/api/vote", voteRoutes);
17 |
18 | app.listen(port, () => {
19 | console.log(`Server running on port ${port}`);
20 | initializeFluvio();
21 | });
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1",
7 | "start": "tsc && node dist/app.js",
8 | "dev": "ts-node-dev src/app.ts"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "description": "",
14 | "devDependencies": {
15 | "@types/cors": "^2.8.17",
16 | "@types/express": "^4.17.21",
17 | "@types/node": "^22.4.0",
18 | "@types/ws": "^8.5.12",
19 | "nodemon": "^3.1.4",
20 | "ts-node": "^10.9.2",
21 | "ts-node-dev": "^2.0.0",
22 | "typescript": "^5.5.4"
23 | },
24 | "dependencies": {
25 | "@fluvio/client": "^0.14.9",
26 | "cors": "^2.8.5",
27 | "dotenv": "^16.4.5",
28 | "express": "^4.19.2",
29 | "ws": "^8.18.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 K Om Senapati
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/config/fluvio.ts:
--------------------------------------------------------------------------------
1 | import Fluvio, { Offset } from "@fluvio/client";
2 | import dotenv from "dotenv";
3 |
4 | dotenv.config();
5 |
6 | const FLUVIO_TOPIC = process.env.FLUVIO_TOPIC || "vote-topic";
7 | const PARTITION = 0;
8 |
9 | export const initializeFluvio = async () => {
10 | try {
11 | const fluvio = new Fluvio();
12 | await fluvio.connect();
13 | console.log("Fluvio initialized");
14 | } catch (error) {
15 | console.error("Failed to initialize Fluvio:", error);
16 | }
17 | };
18 |
19 | export const getConsumer = async () => {
20 | const fluvio = new Fluvio();
21 | await fluvio.connect();
22 | const consumer = await fluvio.partitionConsumer(FLUVIO_TOPIC, PARTITION);
23 | return consumer;
24 | };
25 |
26 | const getProducer = async () => {
27 | const fluvio = new Fluvio();
28 | await fluvio.connect();
29 | const producer = await fluvio.topicProducer(FLUVIO_TOPIC);
30 | return producer;
31 | };
32 |
33 | export const sendVote = async (candidate: string) => {
34 | const producer = await getProducer();
35 | await producer.send("candidate", JSON.stringify(candidate));
36 | };
37 |
38 | export const getVotes = async () => {
39 | const votes: string[] = [];
40 | const consumer = await getConsumer();
41 |
42 | await consumer.stream(Offset.FromEnd(), async (record) => {
43 | votes.push(record.valueString());
44 | });
45 | return votes;
46 | };
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **Real-Time Vote App** 🎉
2 |
3 | 
4 |
5 | ## **Description:**
6 |
7 | The Real-Time Vote App provides a seamless voting experience with live updates using Fluvio and Server-Sent Events (SSE). Users can cast their votes in real-time and watch as the results update dynamically. This application showcases modern web technologies and real-time data handling, making voting engaging and immediate.
8 |
9 | ## **Tech Stack:**
10 |
11 | [](https://skillicons.dev)
12 |
13 | - Chart JS
14 | - Fluvio
15 |
16 | ## **Features:**
17 |
18 | - **Real-Time Voting:** 🗳️ See live updates on voting results as votes are cast.
19 | - **Dynamic Charting:** 📊 View and interact with real-time charts using Chart.js.
20 |
21 |
23 |
24 | 
25 | 
26 | 
27 |
28 | Screenshots:
246 | This app provides real-time voting results using Fluvio and 247 | Server-Sent Events (SSE). 248 |
249 | 250 | 268 | 269 |279 | Display real-time voting data using dynamic charts that update 280 | instantly. 281 |
282 |286 | Utilize Fluvio, a powerful real-time data platform for live vote 287 | streaming. 288 |
289 |293 | Efficiently manage votes using JSON for data handling and 294 | processing. 295 |
296 |342 | Our project is open source! Contribute and star us on GitHub. 343 |
344 | 394 |401 | For more information or inquiries, feel free to reach out. 402 |
403 | 404 | 557 | 558 |