nodebb-plugin-niki-loyalty 1.2.1 → 1.2.2
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.
- package/library.js +1 -314
- package/package.json +1 -1
- package/plugin.json +0 -8
package/library.js
CHANGED
|
@@ -419,318 +419,5 @@ Plugin.addNavigation = async function (nav) {
|
|
|
419
419
|
return nav;
|
|
420
420
|
};
|
|
421
421
|
|
|
422
|
-
// Widget
|
|
423
|
-
Plugin.renderNikiAdminWidget = async function (widget) {
|
|
424
|
-
const uid = widget.uid;
|
|
425
|
-
if (!uid) {
|
|
426
|
-
return { html: '' }; // Misafirler göremez
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
const isAdmin = await user.isAdministrator(uid);
|
|
430
|
-
const isMod = await user.isGlobalModerator(uid);
|
|
431
|
-
|
|
432
|
-
if (!isAdmin && !isMod) {
|
|
433
|
-
return { html: '' }; // Yetkisiz kullanıcılar göremez
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Widget HTML'i (Sadece JS tarafından doldurulacak container)
|
|
437
|
-
const html = `
|
|
438
|
-
<style>
|
|
439
|
-
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
|
|
440
|
-
|
|
441
|
-
.niki-admin-widget {
|
|
442
|
-
font-family: 'Poppins', sans-serif;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
.niki-admin-header {
|
|
446
|
-
background: linear-gradient(135deg, #3E2723, #5D4037);
|
|
447
|
-
color: #fff;
|
|
448
|
-
padding: 25px;
|
|
449
|
-
border-radius: 16px;
|
|
450
|
-
margin-bottom: 20px;
|
|
451
|
-
text-align: center;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
.niki-admin-header h2 {
|
|
455
|
-
margin: 0 0 8px;
|
|
456
|
-
font-size: 22px;
|
|
457
|
-
font-weight: 700;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
.niki-admin-header p {
|
|
461
|
-
margin: 0;
|
|
462
|
-
opacity: 0.85;
|
|
463
|
-
font-size: 13px;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
.niki-stats-grid {
|
|
467
|
-
display: grid;
|
|
468
|
-
grid-template-columns: repeat(3, 1fr);
|
|
469
|
-
gap: 12px;
|
|
470
|
-
margin-bottom: 20px;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
.niki-stat-box {
|
|
474
|
-
background: #fff;
|
|
475
|
-
border-radius: 12px;
|
|
476
|
-
padding: 16px;
|
|
477
|
-
text-align: center;
|
|
478
|
-
box-shadow: 0 2px 10px rgba(0,0,0,0.06);
|
|
479
|
-
border: 1px solid #eee;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
.niki-stat-num {
|
|
483
|
-
font-size: 26px;
|
|
484
|
-
font-weight: 700;
|
|
485
|
-
color: #3E2723;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
.niki-stat-lbl {
|
|
489
|
-
font-size: 11px;
|
|
490
|
-
color: #8D6E63;
|
|
491
|
-
text-transform: uppercase;
|
|
492
|
-
letter-spacing: 0.5px;
|
|
493
|
-
margin-top: 4px;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
.niki-table-box {
|
|
497
|
-
background: #fff;
|
|
498
|
-
border-radius: 16px;
|
|
499
|
-
overflow: hidden;
|
|
500
|
-
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
|
|
501
|
-
border: 1px solid #eee;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
.niki-table-top {
|
|
505
|
-
background: #FAFAFA;
|
|
506
|
-
padding: 12px 16px;
|
|
507
|
-
border-bottom: 1px solid #eee;
|
|
508
|
-
display: flex;
|
|
509
|
-
justify-content: space-between;
|
|
510
|
-
align-items: center;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
.niki-table-t {
|
|
514
|
-
font-weight: 700;
|
|
515
|
-
color: #3E2723;
|
|
516
|
-
font-size: 14px;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
.niki-search {
|
|
520
|
-
padding: 8px 12px;
|
|
521
|
-
border: 1px solid #ddd;
|
|
522
|
-
border-radius: 8px;
|
|
523
|
-
font-size: 13px;
|
|
524
|
-
width: 180px;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
.niki-ulist {
|
|
528
|
-
list-style: none;
|
|
529
|
-
margin: 0;
|
|
530
|
-
padding: 0;
|
|
531
|
-
max-height: 450px;
|
|
532
|
-
overflow-y: auto;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
.niki-urow {
|
|
536
|
-
display: flex;
|
|
537
|
-
align-items: center;
|
|
538
|
-
padding: 12px 16px;
|
|
539
|
-
border-bottom: 1px solid #f0f0f0;
|
|
540
|
-
transition: background 0.2s;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
.niki-urow:hover {
|
|
544
|
-
background: #FAFAFA;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
.niki-rank {
|
|
548
|
-
width: 35px;
|
|
549
|
-
font-weight: 700;
|
|
550
|
-
color: #8D6E63;
|
|
551
|
-
font-size: 13px;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
.niki-avatar {
|
|
555
|
-
width: 38px;
|
|
556
|
-
height: 38px;
|
|
557
|
-
border-radius: 50%;
|
|
558
|
-
margin-right: 12px;
|
|
559
|
-
object-fit: cover;
|
|
560
|
-
border: 2px solid #EFEBE9;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
.niki-avatar-letter {
|
|
564
|
-
width: 38px;
|
|
565
|
-
height: 38px;
|
|
566
|
-
border-radius: 50%;
|
|
567
|
-
margin-right: 12px;
|
|
568
|
-
display: flex;
|
|
569
|
-
align-items: center;
|
|
570
|
-
justify-content: center;
|
|
571
|
-
font-weight: 700;
|
|
572
|
-
color: #fff;
|
|
573
|
-
font-size: 16px;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
.niki-uinfo {
|
|
577
|
-
flex: 1;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
.niki-uname {
|
|
581
|
-
font-weight: 600;
|
|
582
|
-
color: #1a1a1a;
|
|
583
|
-
font-size: 14px;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
.niki-uname a {
|
|
587
|
-
color: inherit;
|
|
588
|
-
text-decoration: none;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
.niki-uname a:hover {
|
|
592
|
-
color: #5D4037;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
.niki-pts {
|
|
596
|
-
font-weight: 700;
|
|
597
|
-
font-size: 16px;
|
|
598
|
-
color: #3E2723;
|
|
599
|
-
background: #EFEBE9;
|
|
600
|
-
padding: 6px 14px;
|
|
601
|
-
border-radius: 16px;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
.niki-loading, .niki-empty {
|
|
605
|
-
text-align: center;
|
|
606
|
-
padding: 40px;
|
|
607
|
-
color: #888;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
@media (max-width: 480px) {
|
|
611
|
-
.niki-stats-grid {
|
|
612
|
-
grid-template-columns: 1fr;
|
|
613
|
-
}
|
|
614
|
-
.niki-search {
|
|
615
|
-
width: 140px;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
</style>
|
|
619
|
-
|
|
620
|
-
<div class="niki-admin-widget">
|
|
621
|
-
<div class="niki-admin-header">
|
|
622
|
-
<h2>🐱 Niki Puan Yönetimi</h2>
|
|
623
|
-
<p>Kullanıcıların puan durumunu takip edin</p>
|
|
624
|
-
</div>
|
|
625
|
-
|
|
626
|
-
<div class="niki-stats-grid" id="niki-widget-stats">
|
|
627
|
-
<div class="niki-stat-box">
|
|
628
|
-
<div class="niki-stat-num" id="w-stat-users">-</div>
|
|
629
|
-
<div class="niki-stat-lbl">Kullanıcı</div>
|
|
630
|
-
</div>
|
|
631
|
-
<div class="niki-stat-box">
|
|
632
|
-
<div class="niki-stat-num" id="w-stat-points">-</div>
|
|
633
|
-
<div class="niki-stat-lbl">Toplam Puan</div>
|
|
634
|
-
</div>
|
|
635
|
-
<div class="niki-stat-box">
|
|
636
|
-
<div class="niki-stat-num" id="w-stat-avg">-</div>
|
|
637
|
-
<div class="niki-stat-lbl">Ortalama</div>
|
|
638
|
-
</div>
|
|
639
|
-
</div>
|
|
640
|
-
|
|
641
|
-
<div class="niki-table-box">
|
|
642
|
-
<div class="niki-table-top">
|
|
643
|
-
<span class="niki-table-t">Kullanıcı Puanları</span>
|
|
644
|
-
<input type="text" class="niki-search" id="niki-w-search" placeholder="🔍 Ara...">
|
|
645
|
-
</div>
|
|
646
|
-
<ul class="niki-ulist" id="niki-w-list">
|
|
647
|
-
<li class="niki-loading">Yükleniyor...</li>
|
|
648
|
-
</ul>
|
|
649
|
-
</div>
|
|
650
|
-
</div>
|
|
651
|
-
|
|
652
|
-
<script>
|
|
653
|
-
(function() {
|
|
654
|
-
let widgetUsers = [];
|
|
655
|
-
|
|
656
|
-
function loadWidgetUsers() {
|
|
657
|
-
$.get('/api/niki-loyalty/admin/users', function(data) {
|
|
658
|
-
widgetUsers = data || [];
|
|
659
|
-
renderWidgetUsers(widgetUsers);
|
|
660
|
-
updateWidgetStats(widgetUsers);
|
|
661
|
-
}).fail(function() {
|
|
662
|
-
$('#niki-w-list').html('<li class="niki-empty">Veriler yüklenemedi.</li>');
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
function updateWidgetStats(users) {
|
|
667
|
-
const total = users.length;
|
|
668
|
-
const pts = users.reduce((s, u) => s + u.points, 0);
|
|
669
|
-
const avg = total > 0 ? Math.round(pts / total) : 0;
|
|
670
|
-
$('#w-stat-users').text(total);
|
|
671
|
-
$('#w-stat-points').text(Math.floor(pts).toLocaleString());
|
|
672
|
-
$('#w-stat-avg').text(avg);
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
function renderWidgetUsers(users) {
|
|
676
|
-
const list = $('#niki-w-list');
|
|
677
|
-
list.empty();
|
|
678
|
-
if (users.length === 0) {
|
|
679
|
-
list.html('<li class="niki-empty">Henüz puanı olan kullanıcı yok.</li>');
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
const rp = (window.config && window.config.relative_path) || '';
|
|
683
|
-
users.forEach((u, i) => {
|
|
684
|
-
const url = rp + '/user/' + u.userslug;
|
|
685
|
-
let av;
|
|
686
|
-
if (u.picture) {
|
|
687
|
-
av = '<img src="' + u.picture + '" class="niki-avatar" onerror="this.style.display=\'none\'">';
|
|
688
|
-
} else {
|
|
689
|
-
const l = (u.username || '?').charAt(0).toUpperCase();
|
|
690
|
-
av = '<div class="niki-avatar-letter" style="background-color:' + u.iconBg + '">' + l + '</div>';
|
|
691
|
-
}
|
|
692
|
-
list.append(
|
|
693
|
-
'<li class="niki-urow">' +
|
|
694
|
-
'<span class="niki-rank">#' + (i + 1) + '</span>' +
|
|
695
|
-
av +
|
|
696
|
-
'<div class="niki-uinfo"><div class="niki-uname"><a href="' + url + '" target="_blank">' + u.username + '</a></div></div>' +
|
|
697
|
-
'<div class="niki-pts">' + Math.floor(u.points) + ' P</div>' +
|
|
698
|
-
'</li>'
|
|
699
|
-
);
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
$('#niki-w-search').on('input', function() {
|
|
704
|
-
const q = $(this).val().toLowerCase().trim();
|
|
705
|
-
if (!q) { renderWidgetUsers(widgetUsers); return; }
|
|
706
|
-
renderWidgetUsers(widgetUsers.filter(u => u.username.toLowerCase().includes(q)));
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
if (document.readyState === 'loading') {
|
|
710
|
-
document.addEventListener('DOMContentLoaded', loadWidgetUsers);
|
|
711
|
-
} else {
|
|
712
|
-
loadWidgetUsers();
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
$(window).on('action:ajaxify.end', function() {
|
|
716
|
-
if ($('.niki-admin-widget').length) loadWidgetUsers();
|
|
717
|
-
});
|
|
718
|
-
})();
|
|
719
|
-
</script>
|
|
720
|
-
`;
|
|
721
|
-
|
|
722
|
-
return { html };
|
|
723
|
-
};
|
|
724
|
-
|
|
725
|
-
// Widget'ları tanımlama
|
|
726
|
-
Plugin.defineWidgets = async function (widgets) {
|
|
727
|
-
widgets.push({
|
|
728
|
-
widget: 'niki-admin-panel',
|
|
729
|
-
name: 'Niki Admin Panel',
|
|
730
|
-
description: 'Niki puan yönetimi paneli (Sadece Admin ve Modlara görünür)',
|
|
731
|
-
content: ''
|
|
732
|
-
});
|
|
733
|
-
return widgets;
|
|
734
|
-
};
|
|
735
|
-
|
|
422
|
+
// Widget fonksiyonları kaldırıldı
|
|
736
423
|
module.exports = Plugin;
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -32,14 +32,6 @@
|
|
|
32
32
|
{
|
|
33
33
|
"hook": "action:post.upvote",
|
|
34
34
|
"method": "onUpvote"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"hook": "filter:widgets.getWidgets",
|
|
38
|
-
"method": "defineWidgets"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"hook": "filter:widget.render:niki-admin-panel",
|
|
42
|
-
"method": "renderNikiAdminWidget"
|
|
43
35
|
}
|
|
44
36
|
],
|
|
45
37
|
"staticDirs": {
|