Repository navigation
Expand file tree
/
Copy pathbadges.js
More file actions
209 lines (179 loc) · 7.68 KB
/
Copy pathbadges.js
File metadata and controls
209 lines (179 loc) · 7.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
async function displayBadges() {
const badgeCounter = await ACTContract.methods.badgeCounter().call();
const badgeList = document.getElementById("badgeList");
badgeList.innerHTML = "";
ownerAddress = await ACTContract.methods.owner().call();
if(accountAddr)
if(ownerAddress.toLowerCase() === accountAddr.toLowerCase())
document.getElementById("createBadgeButton").style.display = "block";
if (badgeCounter > 0 && accountAddr) {
const fromBlock = 0;
const toBlock = "latest";
const badges = await ACTContract.getPastEvents("BadgeCreated", { fromBlock, toBlock });
const accountBadges = await ACTContract.getPastEvents("badgeRedeemed", {
filter: { user: accountAddr },
fromBlock, toBlock
});
const redeemedIds = new Set(accountBadges.map(ev => ev.returnValues.badgeId));
const availableBadges = badges.filter(ev => !redeemedIds.has(ev.returnValues.badgeId));
const badgeDetails = await Promise.all(
availableBadges.map(ev =>
ACTContract.methods.badge(ev.returnValues.badgeId).call()
)
);
if (availableBadges.length === 0) {
badgeList.innerHTML = `
<div class="empty-state">
<i class="fas fa-trophy"></i>
<p>You have already obtained all available badges!</p>
</div>
`;
return;
}
badgeDetails.forEach((badge, index) => {
const badgeId = availableBadges[index].returnValues.badgeId;
const card = document.createElement("div");
card.className = "card";
card.innerHTML = `
<div class="card-header" style="background-color: ${getBadgeColor(badge.level)};">
<i class="fas fa-award card-icon"></i>
<h3 class="card-title">${badge.name}</h3>
<span class="card-level">Level ${badge.level}</span>
</div>
<div class="card-body">
<div class="card-detail">
<i class="fas fa-coins"></i>
<span>${badge.requiredTokens} ACT required</span>
</div>
<button class="card-button" onclick="buyBadge(${badgeId})">
<i class="fas fa-shopping-cart"></i> Get Badge
</button>
</div>
`;
badgeList.appendChild(card);
});
} else {
badgeList.innerHTML = `
<div class="empty-state">
<i class="fas fa-wallet"></i>
<p>${accountAddr ? 'No badges available' : 'Connect wallet to view badges'}</p>
</div>
`;
}
}
async function buyBadge(badgeId) {
try {
const fromBlock = 0;
const toBlock = "latest";
const badge = await ACTContract.methods.badge(badgeId).call();
let balance = await ACTContract.methods.balanceOf(accountAddr).call();
const badgeEvents = await ACTContract.getPastEvents("badgeRedeemed", {
filter: { user: accountAddr },
fromBlock, toBlock
});
let maxLevel = 0;
for (let ev of badgeEvents) {
const badgeId = ev.returnValues.badgeId;
const badge = await ACTContract.methods.badge(badgeId).call();
const level = Number(badge.level);
if (level > maxLevel) maxLevel = level;
}
badgeLevel = parseInt(badge.level)
if(balance >= badge.requiredTokens){
if(maxLevel>badgeLevel || maxLevel == badgeLevel-1){
await ACTContract.methods.buyBadge(badgeId).send({
from: accountAddr
});
showToast(`Badge ${badge.name} redeemed!`, 'success');
displayBadges();
updateDashboard()
}else showToast("Your level is too low", "warning");
}else showToast("You don't have enough ACT", "warning");
} catch (err) {
showToast("Error during purchase: " + err.message, "error");
}
}
async function createBadge(){
const modal = document.createElement('div');
modal.className = 'modal-overlay';
modal.innerHTML = `
<div class="modal-content">
<div class="modal-header">
<h3><i class="fas fa-award"></i> New Badge</h3>
<button class="close-modal">×</button>
</div>
<div class="modal-body">
<form id="badgeForm" class="modal-form">
<div class="form-group">
<label for="badgeName"><i class="fas fa-tag"></i> Badge name</label>
<input type="text" id="badgeName" required>
</div>
<div class="form-group">
<label for="badgeDescription"><i class="fas fa-align-left"></i> Description </label>
<textarea id="badgeDescription" rows="3"></textarea>
</div>
<div class="form-group">
<label for="badgeLevel"><i class="fas fa-layer-group"></i> Level</label>
<select id="badgeLevel" required>
${Array.from({length: 5}, (_, i) => `<option value="${i+1}">Level ${i+1}</option>`).join('')}
</select>
</div>
<div class="form-group">
<label for="badgeTokens"><i class="fas fa-coins"></i> Required token</label>
<input type="number" id="badgeTokens" min="1" required>
</div>
<div class="form-actions">
<button type="button" class="cancel-button">Cancel</button>
<button type="submit" class="submit-button">
<i class="fas fa-plus-circle"></i> Create Badge
</button>
</div>
</form>
</div>
</div>
`;
document.body.appendChild(modal);
modal.querySelector('.close-modal').addEventListener('click', () => {
document.body.removeChild(modal);
});
modal.querySelector('.cancel-button').addEventListener('click', () => {
document.body.removeChild(modal);
});
modal.querySelector('#badgeForm').addEventListener('submit', async (e) => {
e.preventDefault();
const name = document.getElementById('badgeName').value;
const description = document.getElementById('badgeDescription').value;
const level = parseInt(document.getElementById('badgeLevel').value);
const requiredTokens = parseInt(document.getElementById('badgeTokens').value);
try {
const submitBtn = modal.querySelector('.submit-button');
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Creating...';
submitBtn.disabled = true;
await ACTContract.methods.createBadge(
name,
description || '',
level,
requiredTokens
).send({ from: accountAddr });
document.body.removeChild(modal);
displayBadges();
updateDashboard()
showToast('Badge created!', 'success');
} catch (error) {
console.error('Error creating badge:', error);
showToast(`Errore: ${error.message}`, 'error');
submitBtn.innerHTML = '<i class="fas fa-plus-circle"></i> Create Badge';
submitBtn.disabled = false;
}
});
}
function getBadgeColor(level) {
const colors = {
1: '#E3F2FD', // Light blue
2: '#BBDEFB', // Medium blue
3: '#90CAF9', // Stronger blue
4: '#64B5F6', // Blue
5: '#42A5F5' // Darker blue
};
return colors[level] || '#E3F2FD'; // Default light blue
}