nodebb-plugin-niki-loyalty 1.0.28 → 1.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/library.js +53 -33
  2. package/package.json +1 -1
package/library.js CHANGED
@@ -13,14 +13,15 @@ const Plugin = {};
13
13
  const SETTINGS = {
14
14
  pointsPerHeartbeat: 5,
15
15
  dailyCap: 250,
16
+ // coffeeCost: 250, // (eski kodda vardı ama artık tier sistemi var; istersen kullanırız)
16
17
  };
17
18
 
18
19
  // Rewards configuration (Ordered from highest cost to lowest)
19
20
  const REWARDS = [
20
- { cost: 250, name: "Ücretsiz Kahve ☕" },
21
- { cost: 180, name: "%60 İndirimli Kahve" },
22
- { cost: 120, name: "%30 İndirimli Kahve" },
23
- { cost: 60, name: "1 Kurabiye 🍪" }
21
+ { cost: 250, name: 'Ücretsiz Kahve ☕' },
22
+ { cost: 180, name: '%60 İndirimli Kahve' },
23
+ { cost: 120, name: '%30 İndirimli Kahve' },
24
+ { cost: 60, name: '1 Kurabiye 🍪' },
24
25
  ];
25
26
 
26
27
  // TEST MODE (Set to true to bypass point checks)
@@ -33,13 +34,21 @@ function safeParseMaybeJson(x) {
33
34
  if (x == null) return null;
34
35
  if (typeof x === 'object') return x;
35
36
  if (typeof x === 'string') {
36
- try { return JSON.parse(x); } catch (e) { return null; }
37
+ try {
38
+ return JSON.parse(x);
39
+ } catch (e) {
40
+ return null;
41
+ }
37
42
  }
38
43
  return null;
39
44
  }
40
45
 
41
46
  function safeStringify(obj) {
42
- try { return JSON.stringify(obj); } catch (e) { return null; }
47
+ try {
48
+ return JSON.stringify(obj);
49
+ } catch (e) {
50
+ return null;
51
+ }
43
52
  }
44
53
 
45
54
  // =========================
@@ -65,7 +74,7 @@ async function addKasaLog(staffUid, customerName, customerUid, rewardName, amoun
65
74
  cust: customerName,
66
75
  cuid: customerUid,
67
76
  amt: amount,
68
- reward: rewardName // Store the specific reward name
77
+ reward: rewardName, // Store the specific reward name
69
78
  };
70
79
  const payload = safeStringify(logEntry);
71
80
  if (!payload) return;
@@ -80,7 +89,7 @@ Plugin.init = async function (params) {
80
89
  const router = params.router;
81
90
  const middleware = params.middleware;
82
91
 
83
- // 1) HEARTBEAT (Earn Points)
92
+ // 1) HEARTBEAT (Earn Points) + ✅ EARN LOG (2. koddaki özellik)
84
93
  router.post('/api/niki-loyalty/heartbeat', middleware.ensureLoggedIn, async (req, res) => {
85
94
  try {
86
95
  const uid = req.uid;
@@ -96,6 +105,9 @@ Plugin.init = async function (params) {
96
105
  await user.incrementUserFieldBy(uid, 'niki_points', SETTINGS.pointsPerHeartbeat);
97
106
  await db.incrObjectFieldBy(dailyKey, 'score', SETTINGS.pointsPerHeartbeat);
98
107
 
108
+ // ✅ Log: Cüzdan geçmişinde "kazanım" görünsün
109
+ await addUserLog(uid, 'earn', SETTINGS.pointsPerHeartbeat, 'Ders Çalışma 📚');
110
+
99
111
  const newBalance = await user.getUserField(uid, 'niki_points');
100
112
  return res.json({ earned: true, points: SETTINGS.pointsPerHeartbeat, total: newBalance });
101
113
  } catch (err) {
@@ -121,10 +133,7 @@ Plugin.init = async function (params) {
121
133
  let dailyPercent = (dailyScore / SETTINGS.dailyCap) * 100;
122
134
  if (dailyPercent > 100) dailyPercent = 100;
123
135
 
124
- const history = (historyRaw || [])
125
- .map(safeParseMaybeJson)
126
- .filter(Boolean)
127
- .reverse();
136
+ const history = (historyRaw || []).map(safeParseMaybeJson).filter(Boolean).reverse();
128
137
 
129
138
  return res.json({
130
139
  points: currentPoints,
@@ -132,14 +141,14 @@ Plugin.init = async function (params) {
132
141
  dailyCap: SETTINGS.dailyCap,
133
142
  dailyPercent,
134
143
  history,
135
- rewards: REWARDS // Send reward tiers to frontend
144
+ rewards: REWARDS,
136
145
  });
137
146
  } catch (err) {
138
147
  return res.status(500).json({ points: 0, history: [] });
139
148
  }
140
149
  });
141
150
 
142
- // 3) KASA HISTORY
151
+ // 3) KASA HISTORY (+ ✅ iconBg + reward fallback (2. koddaki özellik))
143
152
  router.get('/api/niki-loyalty/kasa-history', middleware.ensureLoggedIn, async (req, res) => {
144
153
  try {
145
154
  const isAdmin = await user.isAdministrator(req.uid);
@@ -152,20 +161,27 @@ Plugin.init = async function (params) {
152
161
  const uids = rows.map(r => parseInt(r.cuid, 10)).filter(n => Number.isFinite(n) && n > 0);
153
162
  const users = await user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture', 'icon:bgColor']);
154
163
  const userMap = {};
155
- (users || []).forEach(u => { userMap[u.uid] = u; });
164
+ (users || []).forEach(u => {
165
+ userMap[u.uid] = u;
166
+ });
156
167
 
157
168
  const rp = nconf.get('relative_path') || '';
158
169
 
159
170
  const enriched = rows.map(r => {
160
171
  const uid = parseInt(r.cuid, 10);
161
172
  const u = userMap[uid];
162
- if (!u) return r;
173
+ if (!u) {
174
+ // yine de reward fallback yapalım
175
+ return { ...r, reward: r.reward || 'İşlem' };
176
+ }
163
177
  return {
164
178
  ...r,
165
179
  cust: u.username || r.cust || 'Bilinmeyen',
166
180
  userslug: u.userslug || r.userslug || '',
167
181
  picture: u.picture || r.picture || '',
168
- profileUrl: (u.userslug ? `${rp}/user/${u.userslug}` : ''),
182
+ iconBg: u['icon:bgColor'] || r.iconBg || '#4b5563',
183
+ profileUrl: u.userslug ? `${rp}/user/${u.userslug}` : '',
184
+ reward: r.reward || 'İşlem',
169
185
  };
170
186
  });
171
187
 
@@ -180,8 +196,7 @@ Plugin.init = async function (params) {
180
196
  try {
181
197
  const uid = req.uid;
182
198
  const points = parseInt((await user.getUserField(uid, 'niki_points')) || 0, 10);
183
-
184
- // Get the cost of the cheapest reward
199
+
185
200
  const minCost = REWARDS[REWARDS.length - 1].cost;
186
201
 
187
202
  if (!TEST_MODE_UNLIMITED && points < minCost) {
@@ -201,7 +216,7 @@ Plugin.init = async function (params) {
201
216
  // 5) SCAN QR (Determine Reward & Deduct Points)
202
217
  router.post('/api/niki-loyalty/scan-qr', middleware.ensureLoggedIn, async (req, res) => {
203
218
  try {
204
- const token = (req.body && req.body.token) ? String(req.body.token) : '';
219
+ const token = req.body && req.body.token ? String(req.body.token) : '';
205
220
  const isAdmin = await user.isAdministrator(req.uid);
206
221
  const isMod = await user.isGlobalModerator(req.uid);
207
222
  if (!isAdmin && !isMod) return res.status(403).json({ success: false, message: 'Yetkisiz' });
@@ -210,22 +225,21 @@ Plugin.init = async function (params) {
210
225
  if (!customerUid) return res.json({ success: false, message: 'Geçersiz Kod' });
211
226
 
212
227
  const pts = parseInt((await user.getUserField(customerUid, 'niki_points')) || 0, 10);
213
-
228
+
214
229
  // Calculate best possible reward
215
230
  let selectedReward = null;
216
231
  if (!TEST_MODE_UNLIMITED) {
217
- for (const reward of REWARDS) {
218
- if (pts >= reward.cost) {
219
- selectedReward = reward;
220
- break;
221
- }
222
- }
223
- if (!selectedReward) {
224
- return res.json({ success: false, message: 'Puan Yetersiz' });
232
+ for (const reward of REWARDS) {
233
+ if (pts >= reward.cost) {
234
+ selectedReward = reward;
235
+ break;
225
236
  }
237
+ }
238
+ if (!selectedReward) {
239
+ return res.json({ success: false, message: 'Puan Yetersiz' });
240
+ }
226
241
  } else {
227
- // Default for test mode
228
- selectedReward = REWARDS[0];
242
+ selectedReward = REWARDS[0];
229
243
  }
230
244
 
231
245
  // Deduct Points
@@ -268,8 +282,14 @@ Plugin.addScripts = async function (scripts) {
268
282
  };
269
283
 
270
284
  Plugin.addNavigation = async function (nav) {
271
- nav.push({ route: '/niki-wallet', title: 'Niki Cüzdan', enabled: true, iconClass: 'fa-coffee', text: 'Niki Cüzdan' });
285
+ nav.push({
286
+ route: '/niki-wallet',
287
+ title: 'Niki Cüzdan',
288
+ enabled: true,
289
+ iconClass: 'fa-coffee',
290
+ text: 'Niki Cüzdan',
291
+ });
272
292
  return nav;
273
293
  };
274
294
 
275
- module.exports = Plugin;
295
+ module.exports = Plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-niki-loyalty",
3
- "version": "1.0.28",
3
+ "version": "1.0.29",
4
4
  "description": "Niki The Cat Coffee Loyalty System - Earn points while studying on IEU Forum.",
5
5
  "main": "library.js",
6
6
  "nbbpm": {