Skip to content

adding units of measurement and improving css #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions app/logged/dashboard/Dashboard.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,63 @@
font-size: 16px;
font-weight: bold;
color: #555;
}


.rankingSection {
margin-top: 40px;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.rankingSection h2 {
text-align: center;
font-size: 20px;
margin-bottom: 20px;
color: #333;
}

.rankingList {
list-style: none;
padding: 0;
margin: 0;
}

.rankingItem {
display: flex;
align-items: center;
padding: 15px 10px;
border-bottom: 1px solid #f0f0f0;
transition: background-color 0.2s ease;
}

.rankingItem:last-child {
border-bottom: none;
}

.rankingItem:hover {
background-color: #f7f7f7;
}

.rank {
font-size: 1.1em;
font-weight: bold;
color: #6a0dad;
width: 50px;
flex-shrink: 0;
}

.donorName {
flex-grow: 1;
font-size: 1em;
color: #555;
padding: 0 15px;
}

.donorScore {
font-size: 1.1em;
font-weight: 600;
color: #333;
}
150 changes: 123 additions & 27 deletions app/logged/dashboard/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@

import styles from './Dashboard.module.css';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHouse, faUser, faRecycle, faHandshake } from '@fortawesome/free-solid-svg-icons';
import { collection, query, onSnapshot } from "firebase/firestore";
import { Firestore } from "../../../config/firebase";

import { faHouse, faUser, faRecycle, faHandshake, faTrophy } from '@fortawesome/free-solid-svg-icons';
import { collection, query, onSnapshot, getDocs } from "firebase/firestore";
import { getDatabase, ref as dbRef, onValue } from "firebase/database";
import { Firestore, firebaseApp } from "../../../config/firebase";
import React, { useEffect, useState } from 'react';

const firestoreRefCollector = collection(Firestore, 'collector');
const firestoreRefDonor = collection(Firestore, 'donor');


function CountCollectors(callback) {
const q = query(firestoreRefCollector);

return onSnapshot(q, (snapshot) => {
const count = snapshot.size;
callback(count);
Expand All @@ -26,7 +24,6 @@ function CountCollectors(callback) {

function CountDonor(callback) {
const q = query(firestoreRefDonor);

return onSnapshot(q, (snapshot) => {
const count = snapshot.size;
callback(count);
Expand All @@ -42,16 +39,16 @@ function SumResidues(callback) {

snapshot.forEach((doc) => {
const statistic = doc.data().statistic;
sum_eletronicKg += statistic.eletronicKg;
sum_glassKg += statistic.glassKg;
sum_metalKg += statistic.metalKg;
sum_oilKg += statistic.oilKg;
sum_paperKg += statistic.paperKg;
sum_plasticKg += statistic.plasticKg;
sum_RecyclingCollections += statistic.collectionsCompleted;
sum_eletronicKg += statistic.eletronicKg || 0;
sum_glassKg += statistic.glassKg || 0;
sum_metalKg += statistic.metalKg || 0;
sum_oilKg += statistic.oilKg || 0;
sum_paperKg += statistic.paperKg || 0;
sum_plasticKg += statistic.plasticKg || 0;
sum_RecyclingCollections += statistic.collectionsCompleted || 0;
});

const total_sum = sum_eletronicKg + sum_glassKg + sum_metalKg + sum_oilKg + sum_paperKg + sum_plasticKg + sum_RecyclingCollections;
const total_sum = sum_eletronicKg + sum_glassKg + sum_metalKg + sum_oilKg + sum_paperKg + sum_plasticKg;

callback({
sum_eletronicKg: sum_eletronicKg,
Expand All @@ -66,6 +63,30 @@ function SumResidues(callback) {
});
}


const calculateTotalPoints = (collections) => {
let points = 0;
if (!collections) return 0;
collections.forEach(item => {
const typesArray = (typeof item.types === 'string' && item.types) ? item.types.split(',').map(type => type.trim()) : [];
const weightMatch = String(item.weight || '0').match(/\d+/);
const weight = parseInt(weightMatch?.[0] ?? '0', 10);
if (weight > 0 && typesArray.length > 0) {
typesArray.forEach(type => {
if (type === "plastico") points += weight * 80;
if (type === "metal") points += weight * 12;
if (type === "eletronico") points += weight * 15;
if (type === "papel") points += weight * 50;
if (type === "oil") points += weight * 10;
if (type === "vidro") points += weight * 30;
});
}
});
return points;
};



const Dashboard = () => {
const [NCollector, setNCollector] = useState(0);
const [NDonor, setNDonor] = useState(0);
Expand All @@ -78,13 +99,11 @@ const Dashboard = () => {
const [QPp, setQPp] = useState(0);
const [QPl, setQPl] = useState(0);

const [rankingData, setRankingData] = useState([]);

useEffect(() => {
const unsubscribe1 = CountCollectors((data) => {
setNCollector(data);
});
const unsubscribe2 = CountDonor((data) => {
setNDonor(data);
});
const unsubscribe1 = CountCollectors((data) => setNCollector(data));
const unsubscribe2 = CountDonor((data) => setNDonor(data));
const unsubscribe3 = SumResidues((data) => {
setQSumResidues(data.total_sum);
setNSumRecyclingCollections(data.sum_recyclingCollections);
Expand All @@ -93,7 +112,7 @@ const Dashboard = () => {
setQMt(data.sum_metalKg);
setQOl(data.sum_oilKg);
setQPp(data.sum_paperKg);
setQPl(data.sum_paperKg);
setQPl(data.sum_plasticKg);
});

return () => {
Expand All @@ -103,14 +122,76 @@ const Dashboard = () => {
};
}, []);

useEffect(() => {
const fetchAndSetRanking = async () => {
const donorNames = {};
try {
const donorSnapshot = await getDocs(firestoreRefDonor);
donorSnapshot.forEach(doc => {
donorNames[doc.id] = doc.data().name || 'Doador Anônimo';
});
} catch (error) {
console.error("Erro ao buscar nomes dos doadores:", error);
}

const infoRef = dbRef(getDatabase(firebaseApp), 'recyclable/');

const unsubscribe = onValue(infoRef, (snapshot) => {
if (!snapshot.exists()) {
setRankingData([]);
return;
}
const data = snapshot.val();

const allDonorsCollections = {};
for (const id in data) {
const collectionInfo = data[id];
const currentDonorId = collectionInfo?.donor?.id;
if (currentDonorId) {
if (!allDonorsCollections[currentDonorId]) {
allDonorsCollections[currentDonorId] = [];
}
allDonorsCollections[currentDonorId].push({
types: collectionInfo.types ?? '',
weight: collectionInfo.weight ?? '0 KG',
});
}
}

const donorScores = Object.keys(allDonorsCollections).map(donorId => ({
id: donorId,
name: donorNames[donorId] || 'Doador Anônimo',
score: calculateTotalPoints(allDonorsCollections[donorId])
}));

donorScores.sort((a, b) => b.score - a.score);
setRankingData(donorScores);
}, (error) => {
console.error('Erro ao buscar dados de reciclagem:', error);
});

return unsubscribe;
};

let unsubscribeFromOnValue;
fetchAndSetRanking().then(unsubscribe => {
unsubscribeFromOnValue = unsubscribe;
});

return () => {
if (unsubscribeFromOnValue) {
unsubscribeFromOnValue();
}
};
}, []);

const stats = [
{ title: 'Coletores', value: NCollector, icon: faUser },
{ title: 'Doadores', value: NDonor, icon: faHouse },
{ title: 'Resíduos coletados', value: QSumResidues, icon: faRecycle },
{ title: 'Coletas feitas', value: NRecyclingCollections, icon: faHandshake },
{ title: 'Kgs Coletados', value: QSumResidues, icon: faRecycle },
{ title: 'Coletas Feitas', value: NRecyclingCollections, icon: faHandshake },
];

const wasteData = [
{ type: 'Eletrônico', amount: QEl, color: '#FFA500' },
{ type: 'Vidro', amount: QGl, color: '#6A5ACD' },
Expand All @@ -119,6 +200,8 @@ const Dashboard = () => {
{ type: 'Papel', amount: QPp, color: '#6A5ACD' },
{ type: 'Plástico', amount: QPl, color: '#FF6347' },
];

const totalWasteForBar = QEl + QGl + QMt + QOl + QPp + QPl || 1;

return (
<div>
Expand Down Expand Up @@ -147,17 +230,30 @@ const Dashboard = () => {
<div
className={styles.wasteBar}
style={{
width: `${waste.amount}%`,
width: `${(waste.amount / totalWasteForBar) * 100}%`,
backgroundColor: 'rgb(170, 220, 160)',
}}
></div>
</div>
<span className={styles.wasteAmount}>{waste.amount}t</span>
<span className={styles.wasteAmount}>{waste.amount} kg</span>
</div>
))}
</div>
</div>

{/* Seção de Ranking de Doadores agora usa os dados dinâmicos */}
<div className={styles.rankingSection}>
<h2><FontAwesomeIcon icon={faTrophy} /> Ranking de Doadores</h2>
<ul className={styles.rankingList}>
{rankingData.map((donor, index) => (
<li key={donor.id} className={styles.rankingItem}>
<span className={styles.rank}>{index + 1}º</span>
<span className={styles.donorName}>{donor.name}</span>
<span className={styles.donorScore}>{donor.score.toLocaleString('pt-BR')} pts</span>
</li>
))}
</ul>
</div>
</div>
);
};
Expand Down